android 4.3以上修改DNS 及 流程(netd)

来源:互联网 发布:陈少杰 西安 网络直播 编辑:程序博客网 时间:2024/06/05 18:30

一、android中代码
framework端,设置dns服务器代码路径如下:
kk-4.x/libcore/luni/src/main/java/java/net/InetAddress.java
kk-4.x/frameworks/base/services/java/com/android/server/NetworkManagementService.java
kk-4.x/frameworks/base/services/java/com/android/server/NativeDaemonConnector.java
NetworkManagementService中函数setDnsServersForInterface
最终会通过本地socket传输命令到守护进程netd
所以framework层还可以使用INetworkManagementService mNetd  来更改dns地址

二、和dns相关libc代码路径如下:
kk-4.x/bionic/libc/netbsd

三、netd模块,netd是一个守护进程
kk-4.x/system/netd

四、其他命令设置dns
iptables -t nat -A OUTPUT -p udp --dport 53 -j DNAT --to-destination 202.96.134.33:53

取消设置的DNS:
iptables -t nat -L OUTPUT -n -v --line-numbers
iptables -t nat -D OUTPUT *linenumber*


五、第一次开机起来后获取DNS:

/data/data/com.android.providers.settings/databases/Settings.db 里面有保存dns数据


在开机状态下,获取DNS:
EthernetManager可以设置获取DNS,这个dns是保存在内存的键值对中。

六、流程
android 4.3之后通过DNS获取ip,采用netd代理,netd是一个守护进程

通过ndc命令可以配置DNS服务器:
ndc resolver setifdns eth0 "" 8.8.8.8 8.8.4.4
各个版本支持的ndc命令:
https://github.com/bparmentier/DNSSetter/wiki/ndc-resolver-commands


1、ndc通过本地socket将命令传给netd
2、通过netd调用res_cache将dns1和dns2等信息保存到cache中
3、 netd调用bionic libc下netbsd中函数getaddrinfo
4、libc更新要访问的dns服务器ip地址



android中请求DNS服务器,获取ip流程如下

上层应用设置dns


NativeDaemonConnector通过java本地socket,将命令
发送给NetD


如果不走netd,流程如下:

注:lbc为android下bionic里面的libc

如果4.3之后有需求,需要和4.3之前一样,通过属性配置DNS。
那么可以合并4.0.3代码,即res_init.c中合并通过属性获取DNS
服务器ip地址代码,通过在自己的程序中设置环境变量:
setenv("ANDROID_DNS_MODE", "local", 1);不要export。

当然不合并代码也是可以的,只需要修改dns服务器地址。
在res_init中res_setservers里面可以修改
                            
struct addrinfo hints, *ai;
memset(&hints, 0, sizeof(hints));
hints.ai_family = PF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = AI_NUMERICHOST;
sprintf(sbuf, "%u", NAMESERVER_PORT);
sprintf(propname, "net.dns%d", i+1);
__system_property_get(propname,propvalue);
printf(" propname: %s \n",propname);
printf("propvalue dns: %s \n",propvalue);
char* p = propvalue;
while (*p == ' ' || *p == '\t')
p++;
p[strcspn(p, ";# \t\n")] = '\0';
if (getaddrinfo(propvalue, sbuf, &hints, &ai) != 0){
memcpy(&statp->nsaddr_list[nserv],&set->sin, size);
}else{
memcpy(&statp->nsaddr_list[nserv],ai->ai_addr, ai->ai_addrlen);
}

如果不修改底层代码,是可以通过ndc命令修改DNS服务器的。原理就是第一个图。


基本请求流程如下:

android apk上从dns服务器获取ip方式如下:

new Thread( networkTask).start();

Runnable networkTask = new Runnable() {
         @Override
         public void run() {
               try {
                   InetAddress inetAddress = InetAddress.getByName( "www.baidu.com");
                   Log. i( TAG, "Address is getHostName:" + inetAddress.getHostName());
                   Log. i( TAG, "Address is " + inetAddress.getHostAddress());
              } catch (Exception e) {
                   e.printStackTrace();
                   Log. i( TAG, "Address is Exception");
              }
         }
};

< uses-permission android:name = "android.permission.INTERNET" />



0 0