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

转自 [(http://blog.csdn.net/ganyue803/article/details/51646284)]

一、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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值