- 论坛徽章:
- 0
|
问题找到了,我在嵌入式设备上用的dhcp客户端为dhcpc,软件包为udhcp-0.9.8.tar,刚开始是改了一下编译器编译了一下在我们的嵌入式设备上就能跑了。但总会有得不到动态分配的ip地址的情况出现(现象是在我们公司大网dhcp服务器工作的时候,能够得到动态分配的ip的几率大一点,而当公司的dhcp服务器关闭,我自己在fc5上搭建的dhcpd服务器工作的时候,只有很小的几率能获得动态分配的ip地址)。后来我跟进源码加打印后发现,send_discover这个函数在拨号不成功的时候,根本没有被调到。后来再查啊查,发现这个client是单任务的,由select控制目前是去读包呢还是发包。刚进来的时候当然应该发discover包了,但是
if (tv.tv_sec > 0) {
DEBUG(LOG_INFO, "Waiting on select...\n");
max_fd = signal_pipe[0] > fd ? signal_pipe[0] : fd;
retval = select(max_fd + 1, &rfds, NULL, NULL, &tv);
DEBUG(LOG_INFO, "retval[%d]\n", retval);
}
else
{
retval = 0; /* If we already timed out, fall through */
}
now = time(0);
if (retval == 0) {
...
send_discover(xid, requested_ip);
...
}
else {
...
}
这些语句决定了,当tv.tv_sec > 0时,只要在fd里在tv这么长的时间内有包收到,这个客户端就永远也不会去发出任何dhcp相关的包,它的tv原来是这样写的:
static unsigned long timeout;
tv.tv_sec = timeout - time(0);
这样timeout的初始值就是0,而time(0)则是一个很大的整数,这两个数以减tv.tv_sec就也是一个很大的整数,所以要在这么长的时间内都不收到udp包,只有碰好的运气了。所以其实只要将这个timeout初始化一下就好了 timeout = (unsigned long)time(0);然后再考虑一下unsigned long的溢出问题timenow = time(0); tv.tv_sec = (timeout>timenow)?(timeout - timenow):0;改好后一运行,相当快就得到动态分配的ip了(只是为什么原来有这样的bug在公司服务器开的时候还是能有比较大的几率获得动态分配的ip的道理不得而知,不求甚解算了)。
不知道这样的一个bug为什么还在一个成熟的版本里的,难道作者是故意这样好让我们去研究一下他的代码?^_^! |
|