【轉載請註明出處:錢國正專欄 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介面如下:
<span style="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),};</span>
具體註冊的對象在下面
<span style="font-size:18px;">root@YSWiFi:/etc/config# ubus list -v'dhcp' @8f0c907e "ipv4leases":{} "ipv6leases":{}'log' @92083360 "read":{"lines":"Integer"} "write":{"event":"String"}<span style="color:#000099;">'network' @36acc569 "restart":{} "reload":{} "add_host_route":{"target":"String","v6":"Boolean","interface":"String"} "get_proto_handlers":{} "add_dynamic":{"name":"String"}</span>'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# </span>
簡單來說,我想找的問題,就是resolv.conf.auto是如何產生的,是由誰產生的, 在wan口up的時候netifd進行會更新狀態,根據獲得的心的DNS地址填寫這個resolv.conf.auto檔案。
netifd.h
<span style="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_PATHNULL /* use the default set in libuci */#define DEFAULT_HOTPLUG_PATH"/sbin/hotplug-call"<span style="color:#000099;">#define DEFAULT_RESOLV_CONF"/tmp/resolv.conf.auto"</span>#endif</span>
interface-ip.c
<span style="font-size:18px;">voidinterface_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);}}</span>
總結:
雖然找到了在哪裡生產的檔案,要一下子解決或者是重現這個問題可不容易。所以我採取了一種折中的方法,指定每個用戶端的DNS伺服器為google的DNS伺服器8.8.8.8 , 8.8.4.4.
【轉載請註明出處:錢國正專欄 http://blog.csdn.net/qianguozheng/article/details/37666829】