1. 程式人生 > >dns工作過程及原理 (linux dns及android dan的實現差異)

dns工作過程及原理 (linux dns及android dan的實現差異)

前言

本文分析dns工作過程及原理,給一個簡單的dns實現程式碼流程,並針對linux及android

下實現dns的不同,分別分析,供學習dns參考。

一、DNS功能

DNS(Domain Name System,域名系統),dns用於進行域名解析,說白了,就是給出一個

主機名,你給我找出該主機名對應的ip地址。例如:給你www.baidu.com的主機名,你給
我查出對應的ip地址:163.177.151.109。一些主機名還會有別名,如www.baidu.com就
有別名www.a.shifen.com,甚至不止一個別名,或一個別名有2個ip地址。在linux機子
上,執行nslookup(name service lookup)就是進行域名解析。如下面:

~$ nslookup www.baidu.com
Server:         127.0.0.1
Address:        127.0.0.1#53

Non-authoritative answer:
www.baidu.com   canonical name = www.a.shifen.com.
Name:   www.a.shifen.com
Address: 163.177.151.109
Name:   www.a.shifen.com
Address: 163.177.151.110

二、DNS的原理

上面介紹了dns的功能,那要實現dns的功能,dns需要做什麼工作?主要就3點:1、記錄dns

伺服器的ip地址(請求進行域名解析的地方);2、向dns伺服器請求進行域名解析(dns
實質工作),3、快取已經解析過的主機名與ip地址對應關係(這樣已快取的就不需要再向
dns伺服器請求解析了)。
一個dns的解析過程如下:
1、 應用程式請求一個主機名解析,如:應用程式跟dns說,我需要知道www.baidu.com
的ip地址,你給我查一下;
2、 Dns先在本地快取中查詢,若查到,返回ip地址給應用,流程結束。若沒查到, 進行
下一步;
3、 Dns把需要查詢的主機名打包進dns資料包,然後把dns資料包傳送到dns服務;
4、 DNS伺服器返回查詢的主機名的dns資料包;
5、 Dns解析資料包,把主機名對應的ip地址返回給應用程式;
下圖為網絡卡抓到的dns資料包的收發,請求www.baidu.com的ip地址:
這裡寫圖片描述

下圖為dns執行流程:
這裡寫圖片描述
上面是從本機看到的情況,實際上在向DNS伺服器請求時,所請求的DNS伺服器也不一
定知道主機名對應的ip地址,就會向上一級DNS請求,更多資料請自行查詢dns協議。

下面程式碼片段為freescale小系統上的dns處理過程,看起來流程還是比較清晰簡單的:

wiced_result_t dns_client_hostname_lookup( const char* hostname, wiced_ip_address_t* address, uint32_t timeout_ms )
{
    /* 省略部分程式碼*/
     ...

    /* Create socket to send packets */
    if ( wiced_udp_create_socket( &socket, WICED_ANY_PORT, WICED_STA_INTERFACE ) != WICED_SUCCESS )
    {
        return WICED_ERROR;
    }

    while ( ipv4_address_found == WICED_FALSE && remaining_time > 0)
    {
        /* Send DNS query messages */
        for ( a = 0; a < dns_server_address_count; a++ )
        {
            wiced_ip_address_t host_ipv6_address;
            uint16_t           available_space;

            /* 建立dns資料包 */
            if ( wiced_packet_create_udp( &socket, (uint16_t) ( sizeof(dns_message_header_t) + sizeof(dns_question_t) + hostname_length ), &packet, (uint8_t**) &iter.header, &available_space ) != WICED_SUCCESS )
            {
                goto exit;
            }

            /* 省略部分程式碼*/
            ...

            /* 傳送dns資料包 */
            if ( wiced_udp_send( &socket, &dns_server_address_array[a], DNS_PORT, packet ) != WICED_SUCCESS )
            {
                wiced_packet_delete( packet );
                goto exit;
            }

            /* 省略部分程式碼*/
            ...
        }

        /* Attempt to receive response packets */
        while ( ipv4_address_found == WICED_FALSE && remaining_time > 0 )
        {
            /* 省略部分程式碼*/
            ...

            /* 接收dns資料包 */
            if ( wiced_udp_receive( &socket, &packet, remaining_time ) == WICED_SUCCESS )
            {
                uint16_t     data_length;
                uint16_t     available_data_length;
                wiced_bool_t answer_found = WICED_FALSE;

                /* Extract the data */
                result = wiced_packet_get_data( packet, 0, (uint8_t**) &iter.header, &data_length, &available_data_length );
                if ( ( result != WICED_SUCCESS ) || ( data_length < sizeof(dns_message_header_t) ) )
                {
                    goto exit;
                }

                /* 解析dns資料包,解析出主機名的ip地址 */
                /* 省略部分程式碼*/
                ...

                wiced_packet_delete( packet );
            }

            /* 省略部分程式碼*/
            ...
        }
    }

exit:
    wiced_udp_delete_socket( &socket );

    /* 省略部分程式碼*/
    ...

    if ( ipv4_address_found == WICED_TRUE )
    {
        *address = resolved_ipv4_address;
        return WICED_SUCCESS;
    }

    /* 省略部分程式碼*/
    ...

    return WICED_ERROR;
}

三、Linux的dns實現

網上搜索Linux dns時,都是一些linux dns怎麼配置的,配置host.conf,

resolv.conf檔案,配置完後,重啟一下network就好了,至於為什麼配置這些檔案,dns
又是在哪裡執行的,都沒有說明。
在Linux上執行nslookup(name service lookup)或ping(ping主機名,如:ping
www.baidu.com)都會執行dns的動作。執行dns時都是呼叫gethostbyname函式,
gethostbyname函式,傳入主機名,dns執行成功後,返回主機名對應的ip地址。
而gethostbyname函式的實現是在c庫中完成的,也就是dns的整個執行過程都是由c庫實
現,c庫中dns實現過程與上一節介紹的流程原理是相同的,只是還多了一些配置檔案用於
設定引數、dns ip地址什麼的,就是前面提到的host.conf,resolv.conf檔案,這就是為什
麼Linux的dns只需要配置host.conf,resolv.conf檔案,不需要再做其它工作的原因,因為
c庫已經替你完成dns的實際工作。在Linux嵌入式系統中,若發現dns不能正常工作,那就
看一下host.conf,resolv.conf等檔案是否配置正確,還有就是dns執行使用的c庫在機子上
有沒有。
想了解c庫怎麼實現dns的,請自行下載c庫原始碼分析:http://www.gnu.org/software/libc/

四、Android的dns實現

Android也是搭建在Linux之上,而在Android下就沒見到host.conf,resolv.conf這

些檔案,但Android的dns也是能正常工作的。這是因為Android重寫了libc庫的dns實現
部分,重寫的dns程式碼在android\bionic\libc\dns目錄。重寫後的dns,請求dns的介面,
有gethostbyname(相容以前的c庫介面)及android_gethostbynamefornet(給
android使用)介面,但根據不同的dns請求發起者,走的流程有點不一樣,其中還涉及到
了netd的處理。Android java層請求dns時,是通過netd進行,netd呼叫
android_gethostbynamefornet介面。而Android下編譯的ping程式是不通過netd而直
接呼叫gethostbyname介面,但最終還是要走到netd,由netd呼叫
android_gethostbynamefornet介面。Android下dns的請求流程如下圖:
這裡寫圖片描述

gethostbyname_internal中判斷是否為netd呼叫下來的依據是,

getenv(“ANDROID_DNS_MODE”)返回是否不為NULL並且值為“local”,而netd啟動
時會設定setenv(“ANDROID_DNS_MODE”, “local”, 1),而ping程式不會。

五、Linux的dns快取

Linux的dns,在配置resolv.conf檔案的時候,第一個dns ip地址配置為nameserver 

127.0.0.1,也就是從本地dns快取中查詢,查詢不到時再根據第二個、第三個dns ip地址
進行dns請求。

六、第三方dns庫

有時候我們不想使用編譯工具中libc自帶的dns庫,也可以移植第三

方的dns庫,如c-ares dns庫,該dns庫支援多種平臺。例如:linux
平臺上,它與linux的配置完全相容,可以在現有的linux dns配置文
件上,直接編譯c-ares庫放到機子上即可使用。

相關推薦

dns工作過程原理 linux dnsandroid dan實現差異

前言 本文分析dns工作過程及原理,給一個簡單的dns實現程式碼流程,並針對linux及android 下實現dns的不同,分別分析,供學習dns參考。 一、DNS功能 DNS(Domain Name System,域名系統),dns用於進行域名解

客戶端到伺服器端的通訊過程原理很清晰,保證看後頓悟

  學習任何東西,我們只要搞清楚其原理,就會觸類旁通。現在結和我所學,我想總結一下客戶端到伺服器端的通訊過程。只有明白了原理,我們才會明白當我們程式開發過程中錯誤的問題會出現在那,才會更好的解決問題。     我們首先要了解一個概念性的詞彙:Socket     sock

kubernetes安裝過程中錯誤kube-dns 狀態一直是Pending,master節點是NotReady

安裝環境如下: cenos7系統 kubeadm安裝方法 版本是:kubernetes1.10 K8s安裝完成後,發現所有的pod都起了,除了kube-dns ,顯示的狀態一直是Pending.

solr搜索之入門原理

solr solr入門 1 solr簡介solr官方文檔:http://wiki.apache.org/solr/DataImportHandler 下載地址:http://www.apache.org/dyn/closer.cgi/lucene/solr/2 solr入門我們使

MQTT協議學習實踐Linux服務端,Android客戶端的例子

nbsp hub 設備 log config cati href 10.10.4 rmi 前言 MQTT(Message Queuing Telemetry Transport),是一個物聯網傳輸協議,它被設計用於輕量級的發布/訂閱式消息傳輸,旨在為低帶寬和不穩定

徹底弄懂HTTP緩存機制原理轉載

一次 chrom https 分開 res 技術 觸發 明顯 總結 https://www.cnblogs.com/chenqf/p/6386163.html 前言 Http 緩存機制作為 web 性能優化的重要手段,對於從事 Web 開發的同學們來說,應該是知識體系庫中的

雜記——controller的工作原理以CSDN網站導航條為例

最近初學springMVC,今天明白了controller和jsp之間聯絡的工作原理,於是記一個小筆記。 先看一個程式碼 下面是controller中的一個cookieBind方法 @RequestMapping(value="/cookiebind", method = {Reques

jmeter安裝使用linux

(1)將jmeter安裝包壓縮zip上傳到伺服器/opt/software/apache-jmeter-4.0.zip (2)解壓: unzip apache-jmeter-4.0.zip (3)配置環境變數 3.1) vim /etc/profile 3.2)

Java併發基礎-鎖的使用原理可重入鎖、讀寫鎖、內建鎖、訊號量等

本文目錄: 1 基礎 1.1 可重入鎖 可重入鎖表示的是,如果一個執行緒在未釋放已獲得鎖的情況下再次對該物件加鎖,將可以加鎖成功。而且可以不斷的加鎖成功多次。但需要注意的是,每次加鎖操作必須對應著一次釋放鎖的操作。 如以下示例是可以執行的(

淺析RxJava 1.x&2.x版本使用區別原理:Observable、Flowable等基本元素原始碼解析

RxJava開源框架的風靡程度在Github上無需多言,它帶來的響應式程式設計模式和執行緒隨意切換、巢狀請求、背壓等功能給了開發者耳目一新的體驗,更是成為了大多數APP中常用的RxJava+Okhttp/Retrofit+MVP/MVVM/Clean黃金組合中的

ClassLoader的工作原理Java中和Andriod中的一些區別

早期使用過 Eclipse 等 Java 編寫的軟體的同學可能比較熟悉,Eclipse 可以載入許多第三方的外掛(或者叫擴充套件),這就是動態載入。這些外掛大多是一些 Jar 包,而使用外掛其實就是動態載入 Jar 包裡的 Class 進行工作。這其實非常好理解,Ja

編譯器的工作過程原理

原始碼要執行,必須先轉成二進位制的機器碼。這是編譯器的任務。 比如,下面這段原始碼(假定檔名叫做test.c)。 #include <stdio.h> int main(void) { fputs("Hello, world!\n", stdout);

【 專欄 】- 作業系統原理linux

作業系統原理(linux) BIOS(BIOS中斷服務程式),Intel風格x86彙編的核心引導主程式,從真實模式下怎麼進入保護模式,怎麼實現中斷呼叫,怎麼實現特權級檢查,怎麼實現任務的建立,怎麼實現多工的管理;怎麼載入全部核心程

hadoop作業調優引數整理原理整個mapreduce執行流程都講的清楚,一步一步優化

1 Map side tuning引數 1.1 MapTask執行內部原理 當map task開始運算,併產生中間資料時,其產生的中間結果並非直接就簡單的寫入磁碟。這中間的過程比較複雜,並且利用到了記憶體buffer來進行已經產生的部分結果的快取,並在記憶體bu

詳解openstack命令啟動實現流程原理nova --debug image-list

第二個引數就是entry_points.txt檔案group名稱 nova就是傳遞進來的引數,實際指向novaclient.shell模組的main函式 跟進程式碼: 上述程式碼從命令列接收引數,或者從環境變數中獲取引數值,進行驗證等操作。  nova --debug im

jdk下載安裝linux

一:jdk安裝 1.jdk下載地址: jdk1.7 64位官方下載地址 http://www.oracle.com/technetwork/java/javase/downloads/index.html 想要下載最新版本,當前也選擇下載即可: 下載歷史版本:從首

VMware虛擬機器三種聯網方法原理Linux 三種網路

一、Brigde——橋接:預設使用VMnet0 1、原理:         Bridge  橋"就是一個主機,這個機器擁有兩塊網絡卡,分別處於兩個區域網中,同時在"橋"上,執行著程式,讓區域網A中的所有資料包原封不動的流入B,反之亦然。這樣,區域網A和B就無縫的在鏈路層連線起

python中decorator的用法原理

0、 概念 什麼叫裝飾器,其實也可以叫做包裝器。即對於一個既有的函式func(args),在呼叫它之前和之後,我們希望都做一些事情,把這個函式包裝起來。 python中的裝飾器分為兩類:函式裝飾器和類裝飾器。 這裡我們先討論函式裝飾器。 1. 不帶引數的decorator

13、基因組的拼接原理轉載沈夢圓的博客

學習 jpg 知識 general arch fly 技術分享 重復 prot 最近學習了一下基因組的拼接原理,以下是我的學習筆記和一些思考。基因組的拼接原理是高通量測序技術的基礎知識吧,我個人認為即使不做基 因組拼接工作,也可以學習一下幾個主流拼接軟件的算法和原理。我主要

Nginx系列-2.配置LNMPLinux、Nginx、MySQL、PHP架構

Linux Nginx Nginx系列-2.配置LNMP(Linux、Nginx、MySQL、PHP)架構 目錄 - Nginx系列 Nginx系列-1.Linux下安裝Nginx Nginx系列-2.配置LNMP(Linux、Nginx、MySQL、PHP)架構 Nginx系列-3.配置Ngi