<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                DnsProxyListener和Android系統中的DNS管理有關。什么是DNS呢?Android系統中DNS又有什么特點呢?來看下文。 **1. Android DNS介紹[3]** DNS是Domain Name System(域名系統)的縮寫。其主要目的是在域名和IP地址之間建立一種映射。簡單點說,DNS的功能類似于電話簿,它可將人名映射到相應的電話號碼。在DNS中,人名就是域名,電話號碼就是IP地址。域名系統的管理由DNS服務器來完成。全球范圍內的DNS服務器共同構成了一個分布式的域名-IP數據庫。 對使用域名來發起網絡操作的網絡程序來說,其域名解析工作主要分兩步: - 1)第一步工作就是需要將域名轉換成IP。由于域名和IP的轉換關系存儲在DNS服務器上,所以該網絡程序要向DNS服務器發起請求,以獲取域名對應的IP地址。 - 2)DNS服務器根據DNS解析規則解析并得到該域名對應的IP地址,然后返回給客戶端。在DNS中,每一個域名和IP的對應關系被稱之為一條記錄。客戶端一般會緩存這條記錄以備后續之用。 >[info] **提醒**:DNS解析規則比較復雜,感興趣的讀者可研究DNS的相關協議。 對軟件開發者來說,常用的域名解析socket API有兩個: - getaddrinfo:它根據指定的host名或service名得到對應的IP地址(該IP地址由結構體addrinfo表達)。 - getnameinfo:根據指定的IP地址(由結構體sockaddr表達)得到對應的host或service的名稱。 Android中,這兩個函數均由Bionic C實現。其代碼實現基于NetBSD的解析庫(resolver library),并經過一些修改。這些修改包括: - 沒有實現name-server-switch功能。這是為了保持Bionic C庫的輕便性而做的裁剪。 - DNS服務器的配置文件由/etc/resolv.conf變成/system/etc/resolv.conf[^1]。在Android系統中,/etc目錄實際上為/system/etc目錄的鏈接。resolv.conf存儲的是DNS服務器的IP地址。 - 系統屬性中保存了一些DNS服務器的地址,它們通過諸如"net.dns1"或"net.dns2"之類的屬性來表達。這些屬性由dhcpd進程或其他系統模塊負責維護。 - 每個進程還可以設置進程特定的DNS服務器地址。它們通過諸如"net.dns1.<pid>"或"net.dns2.<pid>"的系統屬性來表達。 - 不同的網絡設備也有對應的DNS服務器地址,例如通過wlan接口發起的網絡操作,其對應的DNS服務器由系統屬性“net.wlan.dns1”表示。 圖2-6所示為三星Galaxy Note2中有關dns信息的示意圖。 :-: ![](http://img.blog.csdn.net/20140303220925140?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvSW5ub3N0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 圖2-6 net.dns設置示意圖 由圖2-6可知: - 系統中有些進程有自己特定的DNS服務器。 - 不同網絡設備也設置了對應的DNS服務器地址。 **2. getaddrinfo函數分析** 本節將介紹Android中getaddrinfo的實現,我們將只關注Android對其做的改動。 **getaddrinfo.c::getaddrinfo** ~~~ int getaddrinfo(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res) { ......//getaddrinfo的正常處理 //Android平臺的特殊定制 if (android_getaddrinfo_proxy(hostname, servname, hints, res) == 0) { return 0; } ......//如果上述函數處理失敗,則繼續getaddrinfo的正常處理 return error } ~~~ 由上述代碼可知,Android平臺中的getaddrinfo會調用其定制的android_getaddrinfo_proxy函數完成一些特殊操作,該函數的實現如下所示: **getaddrinfo.c::android_getaddrinfo_proxy** ~~~ static int android_getaddrinfo_proxy(const char *hostname, const char *servname, const struct addrinfo *hints, struct addrinfo **res) { ....... //取ANDROID_DNS_MODE環境變量。只有Netd進程設置了它 const char* cache_mode = getenv("ANDROID_DNS_MODE"); ...... //由于Netd進程設置了此環境變量,故Netd進程調用getaddrinfo的話,將不會采用這套定制的方法 if (cache_mode != NULL && strcmp(cache_mode, "local") == 0) { return -1; } //獲取本進程對應的DNS地址 snprintf(propname, sizeof(propname), "net.dns1.%d", getpid()); if (__system_property_get(propname, propvalue) > 0) { return -1; } //建立和Netd中DnsProxyListener的連接,將請求轉發給它去執行 sock = socket(AF_UNIX, SOCK_STREAM, 0); if (sock < 0) { return -1; } ...... strlcpy(proxy_addr.sun_path, "/dev/socket/dnsproxyd", sizeof(proxy_addr.sun_path)); ......//發送請求,處理回復等 return -1; } ~~~ 由上述代碼可知: - 當Netd進程調用getaddrinfo時,由于其設置了ANDROID_DNS_MODE環境變量,所以該函數會繼續原來的流程。 - 當非Netd進程調用getaddrinfo函數時,首先會開展android_getaddrinfo_proxy中的工作,即判斷該進程是否有定制的DNS服務器,如果沒有的話它將和位于Netd進程中的"dnsproxyd"監聽socket建立連接,然后把請求發給DnsProxyListener去執行。 **3. DnsProxyListener命令介紹** 下面來介紹DnsProxyListener(以后簡稱DPL),圖2-7所示為其家族成員示意圖: :-: ![](http://img.blog.csdn.net/20140303220949593?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvSW5ub3N0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 圖2-7 DPL家族示意圖 由圖2-7可知,DPL僅定義了兩個命令: - GetAddrInfoCmd,和Bionic C庫的getaddrinfo函數對應。 - GetHostByAddrCmd,和Bionic C庫的gethostbyaddr函數對應。 這個兩條命令的處理比較簡單,此處就不擬展開詳細的代碼。 為方便讀者理解,我們將給出調用序列圖,如圖2-8所示。 :-: ![](http://img.blog.csdn.net/20140303221011140?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvSW5ub3N0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 圖2-8 GetAddrInfoCmd處理流程示意圖 由圖2-8所示,GetAddrInfoHandler最終的處理還是交由Bionic C的getaddrinfo函數來完成。根據前文所述,由于Netd進程設置了ANDROID_DNS_MODE環境變量,故Netd調用的getaddrinfo將走正常的流程。這個正常流程就是Netd進程將向指定的DNS服務器發起請求以解析域名。 Android系統中,通過這種方式來管理DNS的好處是所有解析后得到的DNS記錄都將緩存在Netd進程中,從而使這些信息成為了一個公共的資源,最大程度內做到了信息共享。 [^1]:此處結論來自bioni c/li bc/docs/OVERVIEW.txt 文件,不過根據同目錄下CHANGE S. txt 的說明, resolv. conf將不再使用。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看