动态dns那点事

Time: 二月 8, 2012
Category: Programming practices

最近在捣腾着家里的老爷机准备搭建一台服务器,因为在 linux 环境中,动态域名解析的事可没 windows 那么方便,就只好自己动手来解决了。主要还是依赖 oray 的服务。

ip 问题

实践证明,不依赖于外界条件,仅从本地环境是无法获取公网ip的。想来也是,内网与外网通信很多本身就是靠NAT地址转换来工作的。服务器发出去的数据包,只包含真实的目的ip地址,而源ip却是由内网分配的,经过路由的时候会被转换。

所以不管用什么途径 gethostbyname() 也好,getaddrinfo() 也好 ,还是靠分析socket套接口的内容来获得 ip 地址等等,均不能获得其公网的 ip。原因很简单,看看你底层硬件网卡所记录的信息就知道了。

 

Linux/C 代码:获取网卡ip地址
  1. int getpubipv4(char *ipv4)
  2. {
  3.     int sockfd;
  4.     struct ifreq ifr;
  5.     if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
  6.         return(0);
  7.     ifr.ifr_addr.sa_family = AF_INET;
  8.     strncpy(ifr.ifr_name, "eth0", IFNAMSIZ-1);
  9.     ioctl(sockfd, SIOCGIFADDR, &ifr);
  10.     sprintf(ipv4,"%s",
  11.         inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr));
  12.     close(sockfd);
  13.     return(0);
  14. }

不过没有关系,获取公网 ip 还有很多方便的办法,查看路由表(原理上应该没有问题,没有实际验证过)和借助第三方API工具,比如 oray 的 checkip 服务就非常的不错,http://ddns.oray.com/checkip  如果你不担心 oray 服务稳定性问题的话。oray 提供的 web 查询服务,我们用代码来模拟一个 http 请求即可完成,大概是这样

GET /checkip HTTP/1.1[CRLF]
Host: ddns.oray.com[CRLF]
Connection: close[CRLF]
User-Agent: oray[CRLF]
Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7[CRLF]
Cache-Control: no-cache[CRLF]
Accept-Language: de,en;q=0.7,en-us;q=0.3[CRLF]
[CRLF]

动态解析

oray 同样提供了非常详细的文档,参考:花生壳 HTTP 协议说明 。错误代码没必要解析那么详细,我也只是简单实现了一下 good ,足已。

 

后话,改善一下代码,写成 deamon,开机自动运行或者写个脚本,chkconfig 做成服务什么的都可以。一个 linux 下动态域名解析的问题就解决了。

4 comments to “动态dns那点事”

  1. 番茄说道:

    怎么换风格了?

Leave a Comment