免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6005 | 回复: 0
打印 上一主题 下一主题

pdnsd软件移植android过程 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-03-11 00:02 |只看该作者 |倒序浏览
pdnsd是一个DNS本地缓存软件。它的特点是缓存可以存储到硬盘上,系统重启都仍然保存(当然也可以设置为不保存)。
我的安卓系统设备有时要通过代理上网,因为UDP协议数据包难以穿过只支持TCP协议的代理通道,所以无法成功DNS解析。导致各种网络应用无法使用。
我想通过建立本地DNS服务的办法来解决这个问题。在平时无限制网络环境下,访问需要用到域名,把域名解析存储到本地。在代理上网环境下,访问本地DNS服务,获得已保存过的域名解析信息。
android上好像没有现成的这种软件。有一个移植的叫dnsmasq的软件,虽然有本地缓存功能,但它的缓存只存在内存里,服务或系统一重启就没有了。后来就找到了这个pdnsd,能满足我需要的功能。但是就需要移植。
我电脑是x86 linux系统。移动设备是arm android 2.3.3系统。Pdnsd版本1.2.8
现在把移植过程简单记载如下。

首先下载安装交叉编译软件以及pdnsd源码。
参考了网上的“Android原生(Native)C开发之八:Toolchain环境搭建篇”这篇文章。没有下载全部android源码。只下载了源码中的bionic(也许连这个也不用下,我不确定)。
现在android源码不能直接从google下载了。要先在google下载repo脚本,并设置环境变量。下载android其中的bionic源码。
下载android开发工具NDK。我们只需要其中的toolchain。使用NDK自带的toolchain分离工具,make-standalone-toolchain.sh。要指定你需要的android版本。本来我的是android 2.3.3,平台版本应该是10,但ndk没有10这个版本,比10低的是9,比10高的是15。15是android 4.0,9是x86的,我选了8。分离出来是个名为arm-linux-androideabi-4.4.3的压缩包,把它解压到某个目录。再把先前bionic目录中的一些头文件复制到arm-linux-androideabi-4.4.3/sysroot/usr/include下(也许不用复制,toolchain的头文件已经是完整的了,有机会试试)。

现在开始编译pdnsd源码。
设置环境
export PATH=toolchain安装目录/binPATH
export CC=arm-linux-androideabi-gcc
export LD=arm-linux-androideabi-ld
export AR=arm-linux-androideabi-ar
本来直接想用arm-linux-androideabi-gcc来编译的,结果一执行,提示config.h找不到。自己指定了一个空的config.h文件,又提示很多宏没定义。看来很多宏是用指定的一个config.h头文件来定义的。这个config.h本来是没有的,是由configure脚本生成。先执行./configure,让它生成config.h,打开一看,果然定义了很多宏。再包含进这个头文件编译,又提示一些宏重复定义之类的错误信息。唉,算了我也不是程序员,搞不懂这些高深的东西。还是用软件自带的脚本来解决这些问题吧。
最好先在configure文件里把ac_default_prefix=/usr/local参数部分改成你将在android中放pdnsd.conf配置文件的上一级目录,比如将来要放在android的/etc下面,就改成ac_default_prefix=/。否则,以后要执行的时候要加上-c参数指定配置文件。
执行./configure –host=arm-linux-androideabi
configure脚本没能通过,提示mkfifo功能找不到。不知道是什么意思。在configure脚本中找到包含这个mkfifo的语句,for ac_func in nanosleep gettimeofday mkfifo select socket strerror uname snprintf vsnprintf
把mkfifo这个词删掉。再执行configure,通过了。不知道去掉检查mkfifo会有什么影响。以后再看吧。在config.h文件中修改CACHEDIR这个宏的定义为你想在android中存放缓存文件的目录路径。如果跟后面你实际放的路径不同,pdnsd-ctl这个控制工具程序将无法获取pdnsd的状态信息。
执行make。得到编译好的文件,src下的pdnsd和pdnsd-ctl下的pdnsd-ctl。用file pdnsd看一下,的确显示是arm编码。
接下来就是拷贝到android设备中。如果有驱动,可以直接通过数据线拷到设备的sdcard上。当然也可以用标准的adb命令来做。除了拷贝可执行文件外,还要拷贝一个参数配置文件pdnsd.conf。参考网上的资料,自己写一个,填好缓存大小、存放目录、dns服务器地址等参数。可执行文件只拷pdnsd就可以,另外一个pdnsd-ctl可用可不用。
拷贝到sdcard上后还要再把可执行文件拷到/system/bin目录中,这需要有root权限的文件浏览器来做这件事。然后设置权限。我是用的terminal emulator,在shell中使用chmod命令加上可执行权限。设置权限时会提示是只读文件。我是用了es文件浏览器中的挂载system目录为可写文件系统的功能。先在es文件浏览器设置中勾上这个选项,再在shell中操作。把配置文件pdnsd.conf拷到/etc或其它地方都可以。设置pdnsd.conf的权限,记得其它用户的权限不能可写。pdnsd运行的时候会检查,不允许其他用户可写。pdnsd.conf文件中有个cache文件存放目录,默认是在/var/cache/pdnsd,android没有var这个目录,要么自己建,要么改到其它地方。我在pdnsd.conf中设的是/cache/pdnsd。在/cache下建立pdnsd文件夹,再在下面建立一个pdnsd.cache的空文件。好像不先建好这个文件启动不了。
接下来运行pdnsd。
在终端窗口中先su获得root权限
再输入pdnsd
如果先前没改configure文件中的ac_default_prefix=/usr/local这句,pdnsd默认配置文件在/usr/local/etc下,那就要手动指定配置文件路径。pdnsd -c /etc/pdnsd.conf。如果你的pdnsd.cache文件放在一个非root权限的目录下,会有一个报错信息,不能绑定socket,没有权限。不过pdnsd也不会中止,仍然可以用。只不过无法生成名为pdnsd.status的socket文件,pdnsd-ctl无法获取pdnsd的状态信息。我曾经放在sdcard下的子目录下,权限设了777都提示没权限,文件夹属主是system.sdcard_rw。后来放到/cache/下才成功,建议不要放到sdcard下面。
新开一个shell窗口,执行netstat -an,可以看到127.0.0.1 udp 53端口在监听。yeah!!!看来成功了。
我使用dns changer这个软件来设置dns,把dns设为本地地址:127.0.0.1。打开网页浏览器,可以正常浏览。在shell下使用busybox nslookup google.com 127.0.0.1,可以获取ip地址。用ls -l 查看缓存目录/pdnsd.cache,可以看到pdnsd.cache文件在增大。

移植成功
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP