原文地址:
http://blog.csdn.net/qianguozheng/article/details/37666829
起因
为了解决客户反映的openwrt系统上不了网的问题,我们对其进行了远程协助,发现ip可以访问,只是域名访问不了,这就帮助我们定位了问题---DNS.
网上搜寻
找到了个有同样的问题,说是域名服务器不能用,同样是20M光纤拨号,真是巧合啊,到网上搜了这个哥们的网名,找到不少,但是最近发表的不多哦,无果,自己看代码查查。
代码分析
从拨号进行找了/lib/netifd脚本,无果,自己看看在线进程,发现竟然存在这么一个进程 netifd, 既然这样,那就看看源代码吧。
至此,又发现了【http://xinliang.me/blog/?p=149】,这位兄弟的博客,绝对是先驱,看他的东西很有条理,学习到了,openwrt下果然是使用ubus类似Linux发行版上的dbus, ubus主要是用于系统进程间通信,关于详情,请访问这个哥的博客。
nfetifd的ubus RPC接口如下:
-
"font-size:18px;">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),
-
};
-
-
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),
};
具体注册的对象在下面
-
"font-size:18px;">root@YSWiFi:/etc/config# ubus list -v
-
'dhcp' @8f0c907e
-
"ipv4leases":{}
-
"ipv6leases":{}
-
'log' @92083360
-
"read":{"lines":"Integer"}
-
"write":{"event":"String"}
-
"color:#000099;">'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#
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
-
"font-size:18px;">#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"
-
"color:#000099;">#define DEFAULT_RESOLV_CONF "/tmp/resolv.conf.auto"
-
#endif
#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"
#endif
interface-ip.c
-
"font-size:18px;">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);
-
}
-
}
-
void
interface_write_resolv_conf(void)
{
struct interface *iface;
char *path = alloca(strlen(resolv_conf) + 5);
FILE *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.
阅读(2391) | 评论(0) | 转发(1) |