[转]Android DNS 代码分析

转自:http://blog.csdn.net/span76/article/details/41478555

Android DNS 代码都在bionic/libc/netbsd中

(虽然netbsd 是个废弃的项目,但dns功能部分代码被 Android用上了)

netbsd 代码晦涩难懂,只有一边写程序,一边打log验证


照抄了一个简单程序, 在android 下面用 mmm 编译可以得到 py_getaddr 可执行文件, 用adb 登陆到 devices 再到 system/bin 下去执行

[html]  view plain copy
  1. payne@payne-desktop:~/njb/getaddr$ cat py_getaddr.c   
  2. #include <stdio.h>  
  3. #include <stdlib.h>  
  4. #include <sys/socket.h>  
  5. #include <netinet/in.h>  
  6. #include <netdb.h>  
  7. #include <string.h>  
  8. int main(int argc, char **argv)  
  9. {  
  10. if (argc != 2) {  
  11. fprintf(stderr, "Usage: %s hostname\n",  
  12. argv[0]);  
  13. exit(1);     
  14. }  
  15.   
  16. struct addrinfo *answer, hint, *curr;  
  17. char ipstr[16];     
  18. bzero(&hint, sizeof(hint));  
  19. hint.ai_family = AF_INET;  
  20. hint.ai_socktype = SOCK_STREAM;  
  21.   
  22. int ret = getaddrinfo(argv[1], NULL, &hint, &answer);  
  23. if (ret != 0) {  
  24. fprintf(stderr,"getaddrinfo: %s\n",  
  25. gai_strerror(ret));  
  26. exit(1);  
  27. }  
  28.   
  29. for (curr = answer; curr != NULL; curr = curr->ai_next) {  
  30. inet_ntop(AF_INET,  
  31. &(((struct sockaddr_in *)(curr->ai_addr))->sin_addr),  
  32. ipstr, 16);  
  33. printf("%s\n", ipstr);  
  34. }  
  35.   
  36. freeaddrinfo(answer);  
  37. exit(0);  
  38. }  


[html]  view plain copy
  1. cat Android.mk   
  2. LOCAL_PATH:= $(call my-dir)  
  3.   
  4. include $(CLEAR_VARS)  
  5.   
  6. LOCAL_SRC_FILES:py_getaddr.c  
  7. LOCAL_MODULE :py_getaddr  
  8. LOCAL_STATIC_LIBRARIES :libcutils libc  
  9. include $(BUILD_EXECUTABLE)  

到运行 py_getadd  sohu.com 的时候, 调用过程如下

[转]Android DNS 代码分析_第1张图片


_files_getaddrinfo 是读取/system/etc/hosts 检索

_dns_getaddrinfo 是访问dns server

在访问构造 dns 访问的时候,如何找到 dns server, 原来在 __res_get_state  调用返回 __res_state  (这个复杂的结构定义在  bionic/libc/private/resolv_private.h#__res_state )

在调用过程中 __res_vinit 使用了系统设置的 8.8.8.8 nameserver (jeallybean 代码在bionic/libc/netbsd/resolv/res_init.c#339)


之后res_queryN 用 res_nmkquery 构造dns 查询,并用 res_nsend 发送查询,并得到返回结果。

[转]Android DNS 代码分析_第2张图片


运行程序和 log 的打印结果如下:

py_getaddr sohu.com                                                             
======================= _files_getaddrinfo
======================= _dns_getaddrinfo
=========== getaddrinfo cp 8.8.8.8, subf 53
================ res_searchN sohu.com
================ res_querydomainN  name sohu.com, domain (null)
================ res_queryN sohu.com
;; res_nmkquery(QUERY, sohu.com, IN, A)
================getanswer sohu.com
220.181.90.240
123.125.116.19

你可能感兴趣的:(Android)