起因
为了解决客户反映的openwrt系统上不了网的问题,我们对其进行了远程协助,发现ip可以访问,只是域名访问不了,这就帮助我们定位了问题---DNS.
网上搜寻
找到了个有同样的问题,说是域名服务器不能用,同样是20M光纤拨号,真是巧合啊,到网上搜了这个哥们的网名,找到不少,但是最近发表的不多哦,无果,自己看代码查查。
代码分析
从拨号进行找了/lib/netifd脚本,无果,自己看看在线进程,发现竟然存在这么一个进程 netifd, 既然这样,那就看看源代码吧。
至此,又发现了【http://xinliang.me/blog/?p=149】,这位兄弟的博客,绝对是先驱,看他的东西很有条理,学习到了,openwrt下果然是使用ubus类似Linux发行版上的dbus, ubus主要是用于系统进程间通信,关于详情,请访问这个哥的博客。
nfetifd的ubus RPC接口如下:
static struct ubus_method main_object_methods[] = {
{ .name = "restart", .handler = netifd_handle_restart },
{ .name = "reload", .handler = netifd_handle_reload },
UBUS_METHOD("add_host_route", netifd_add_host_route, route_policy),
{ .name = "get_proto_handlers", .handler = netifd_get_proto_handlers },
UBUS_METHOD("add_dynamic", netifd_add_dynamic, dynamic_policy),
};
static struct ubus_object_type main_object_type =
UBUS_OBJECT_TYPE("netifd", main_object_methods);
static struct ubus_object main_object = {
.name = "network",
.type = &main_object_type,
.methods = main_object_methods,
.n_methods = ARRAY_SIZE(main_object_methods),
};具体注册的对象在下面
root@YSWiFi:/etc/config# ubus list -v
'dhcp' @8f0c907e
"ipv4leases":{}
"ipv6leases":{}
'log' @92083360
"read":{"lines":"Integer"}
"write":{"event":"String"}
'network' @36acc569
"restart":{}
"reload":{}
"add_host_route":{"target":"String","v6":"Boolean","interface":"String"}
"get_proto_handlers":{}
"add_dynamic":{"name":"String"}
'network.device' @7b6892b7
"status":{"name":"String"}
"set_alias":{"alias":"Array","device":"String"}
"set_state":{"name":"String","defer":"Boolean"}
'network.interface' @e62dccc3
"up":{}
"down":{}
"status":{}
"prepare":{}
"dump":{}
"add_device":{"name":"String"}
"remove_device":{"name":"String"}
"notify_proto":{}
"remove":{}
"set_data":{}
'network.interface.lan' @817ffe0f
"up":{}
"down":{}
"status":{}
"prepare":{}
"dump":{}
"add_device":{"name":"String"}
"remove_device":{"name":"String"}
"notify_proto":{}
"remove":{}
"set_data":{}
'network.interface.lan2' @137330bd
"up":{}
"down":{}
"status":{}
"prepare":{}
"dump":{}
"add_device":{"name":"String"}
"remove_device":{"name":"String"}
"notify_proto":{}
"remove":{}
"set_data":{}
'network.interface.loopback' @44806906
"up":{}
"down":{}
"status":{}
"prepare":{}
"dump":{}
"add_device":{"name":"String"}
"remove_device":{"name":"String"}
"notify_proto":{}
"remove":{}
"set_data":{}
'network.interface.wan' @4ebe9d3b
"up":{}
"down":{}
"status":{}
"prepare":{}
"dump":{}
"add_device":{"name":"String"}
"remove_device":{"name":"String"}
"notify_proto":{}
"remove":{}
"set_data":{}
'network.wireless' @9a257aa5
"up":{}
"down":{}
"status":{}
"notify":{}
'service' @582b527e
"set":{"name":"String","script":"String","instances":"Table","triggers":"Array","validate":"Array"}
"add":{"name":"String","script":"String","instances":"Table","triggers":"Array","validate":"Array"}
"list":{"name":"String"}
"delete":{"name":"String","instance":"String"}
"update_start":{"name":"String"}
"update_complete":{"name":"String"}
"event":{"type":"String","data":"Table"}
"validate":{"package":"String","type":"String","service":"String"}
'system' @d8c56a4b
"board":{}
"info":{}
"upgrade":{}
"watchdog":{"frequency":"Integer","timeout":"Integer","stop":"Boolean"}
"signal":{"pid":"Integer","signum":"Integer"}
root@YSWiFi:/etc/config# 简单来说,我想找的问题,就是resolv.conf.auto是如何产生的,是由谁产生的, 在wan口up的时候netifd进行会更新状态,根据获得的心的DNS地址填写这个resolv.conf.auto文件。
netifd.h
ifdef DUMMY_MODE #define DEFAULT_MAIN_PATH "./examples" #define DEFAULT_CONFIG_PATH "./config" #define DEFAULT_HOTPLUG_PATH "./examples/hotplug-cmd" #define DEFAULT_RESOLV_CONF "./tmp/resolv.conf" #else #define DEFAULT_MAIN_PATH "/lib/netifd" #define DEFAULT_CONFIG_PATH NULL /* use the default set in libuci */ #define DEFAULT_HOTPLUG_PATH "/sbin/hotplug-call" #define DEFAULT_RESOLV_CONF "/tmp/resolv.conf.auto"</span> #endif
interface-ip.c
void
interface_write_resolv_conf(void)
{
struct interface *iface;
charchar *path = alloca(strlen(resolv_conf) + 5);
FILEFILE *f;
uint32_t crcold, crcnew;
sprintf(path, "%s.tmp", resolv_conf);
unlink(path);
f = fopen(path, "w+");
if (!f) {
D(INTERFACE, "Failed to open %s for writing\n", path);
return;
}
vlist_for_each_element(&interfaces, iface, node) {
if (iface->state != IFS_UP)
continue;
if (vlist_simple_empty(&iface->proto_ip.dns_search) &&
vlist_simple_empty(&iface->proto_ip.dns_servers) &&
vlist_simple_empty(&iface->config_ip.dns_search) &&
vlist_simple_empty(&iface->config_ip.dns_servers))
continue;
fprintf(f, "# Interface %s\n", iface->name);
write_resolv_conf_entries(f, &iface->config_ip);
if (!iface->proto_ip.no_dns)
write_resolv_conf_entries(f, &iface->proto_ip);
}
fflush(f);
rewind(f);
crcnew = crc32_file(f);
fclose(f);
crcold = crcnew + 1;
f = fopen(resolv_conf, "r");
if (f) {
crcold = crc32_file(f);
fclose(f);
}
if (crcold == crcnew) {
unlink(path);
} else if (rename(path, resolv_conf) < 0) {
D(INTERFACE, "Failed to replace %s\n", resolv_conf);
unlink(path);
}
}总结:
虽然找到了在哪里生产的文件,要一下子解决或者是重现这个问题可不容易。所以我采取了一种折中的方法,指定每个客户端的DNS服务器为google的DNS服务器8.8.8.8 , 8.8.4.4.
本站的文章和资源来自互联网或者站长的原创,按照 CC BY -NC -SA 3.0 CN协议发布和共享,转载或引用本站文章应遵循相同协议。如果有侵犯版权的资 源请尽快联系站长,我们会在24h内删除有争议的资源。欢迎大家多多交流,期待共同学习进步。








