參考:
https://blog.csdn.net/crazw/article/details/8986504
http://www.ruanyifeng.com/blog/2016/06/dns.html
https://www.cnblogs.com/davidwang456/articles/10660051.html
原文作者:smilesundream
原文鏈接:https://blog.csdn.net/smilesundream/article/details/69397318
如果說ARP協議是用來將IP地址轉換爲MAC地址,那麼DNS協議則是用來將域名轉換爲IP地址(當然也可以將IP地址轉換爲相應的域名地址)。 在討論DNS協議之前,先回答幾個容易想到的問題。
問題一:網絡中的主機爲什麼不直接使用域名而用IP地址進行通信?
因爲IP地址是固定長度的,IPv4是32位,IPv6是128位,而域名是變長的,不便於計算機處理,但便於用戶使用,例如www.baidu.com這是百度的域名,我們一看就明白。總結一點就是IP地址是面向主機的,而域名則是面向用戶的。
問題二:假如用戶希望通過FTP客戶進程來訪問運行在一臺遠程主機上的FTP服務器,該FTP服務器的域名爲xxx.com.,給出整個處理流程大致描述?(假設xxx.com是一個實際存在的服務器域名)
1.用戶將xxx.com.傳遞給其主機上的FTP客戶進程;
2.FTP客戶程序將xxx.com.傳遞給DNS客戶進程;
3.由於每一臺主機在加載內核後都能獲得其DNS服務器的IP地址,DNS客戶進程便通過該IP地址向DNS服務器發送DNS查詢報文,要求服務器給出xxx.com對應的IP地址;
4.DNS服務器進程在收到該DNS查詢報文後,通過一系列的查詢操作(遞歸查詢或迭代查詢)獲得xxx.com對應的IP地址後將xxx.com的IP地址寫入到DNS響應報文中發回給DNS客戶進程;
5.DNS客戶進程將獲得的xxx.com的IP交付給FTP客戶進程;
6.FTP客戶進程在收到FTP服務器的IP地址後,就可以訪問FTP服務器了。
Notice:客戶進程在於服務器進程發送數據報之前,必須要知道服務進程所在服務器的IP地址,因爲socket地址=(IP地址:端口號),網絡進程間的通信是通過socket進行的。
下面詳細地介紹下DNS協議的工作原理。
一、域名
像Linux目錄結構一樣,現代因特網採用層次樹狀結構的命名方法,任何一個連接在因特網上的主機或路由器,都有一個唯一的層次結構的名字,該名字稱爲域名。
(1)域名的分級:域名可以劃分爲各個子域,子域還可以繼續劃分爲子域的子域,這樣就形成了頂級域、二級域、三級域等。
其中頂級域名分爲:國家頂級域名、通用頂級域名、反向域名。
國家頂級域名:中國:cn, 美國:us,英國uk...
通用頂級域名:com 公司企業 edu教育機構 gov政府部門 int國際組織 mil軍事部門 net網絡
org非盈利組織...
反向域名:只有一個arpa,用於PTR查詢(IP地址轉換爲域名) 。
(2)域名的完整性:根據域名的完整性,我們將域名分爲FQDN和PQDN。
FQDN(Full Qualified Domain Name):完全合格的域名,也稱爲絕對域名(還記得絕對路徑嗎?Linux中的絕對路徑是以/開頭,而此處的絕對域名則是已.結尾)。
PQDN(Partiallly qualified domain name):標號不是以.結束,在將該地址傳遞給DNS服務器之前,本主機的DNS客戶進程中的解析程序可以補充缺少的部分(稱爲後綴),使得PQDN變爲FQDN,顯然DNS客戶程序通常保存了一份有關後綴的列表。
一個域名服務器所負責的範圍,或者說有管理權限的範圍,就稱爲區,每一個區中所有的結點必須是連通的,每一個區中都設置相應的權限域名服務器,用來保存該去中的所有主機的域名到IP地址的映射。所以,DNS服務器的負責範圍不是以“域”爲單位的,而是以“區”爲單位,區可能小於或等於域,但一定不會大於域,區是“域”的子集。
NOTICE:同一個區可能存在多個權限域名服務器。
域名服務器主要分爲:根域名服務器、頂級域名服務器、權限域名服務器、本地域名服務器。
根域名服務器:相當於一個總指揮,每一個域名服務器都必須知道如何與根域名服務器聯繫;
頂級域名服務器:負責管理所有的二級域名;
權限域名服務器:負責管理一個區。當一個權限域名服務器還不能給出最後的查詢回答時,就會告訴查詢請求的DNS客戶進程,下一步應當找哪一個權限域名服務器;
本地域名服務器:可以看成是默認域名服務器,DNS客戶進程收到主機發送過來的域名後,就會最初向該域名服務器發送查詢請求。
爲了保證數據的安全性,一個區域的管理者必須爲該區域提供一個主域名服務(primaryserver)和 輔助域名服務器(secondary server)。主域名服務器從磁盤文件中調入該區域的所有信息,而輔助域名服務器則從主域名服務器調入所有信息,我們將輔助域名服務器從主域名服務器調入信息的過程稱爲區域傳送。當主域名服務器的磁盤文件更新時,輔助名字服務器會定時(通常爲3h)向主域名服務器詢問是否有數據更新,如果有,則通過區域傳送方式獲得新數據。建立輔助域名服務器的目的是爲了保證數據的安全性,當主域名服務器出現故障時間,其輔助域名服務器可以繼續對客戶提供服務。
NOTICE:一個服務器可以是某個區域的主域名服務器,同時又是另一個區域的輔助域名服務器。
二、遞歸查詢與迭代查詢
在理解遞歸查詢與迭代查詢之前,必須要弄明白“遞歸”與“迭代”的區別。我們從C++的角度來理解遞歸與迭代的區別,所謂遞歸就是函數自己調用自己,而迭代則是函數內部循環地調用他人。下面,我們舉出遞歸與迭代的C++程序:
遞歸程序:f(n)=f(n-1)+n,f(1)=1,我們用C++遞歸實現如下
[cpp] view plain copy
- #include<iostream>
- int f(int n)
- {
- if(n==1)
- return 1;
- else
- return f(n-1)+n;<span style="color:#ff0000;">//遞歸過程</span>
- }
迭代程序:f(n)=1+2+3+...+n,我們用C++迭代實現如下
[cpp] view plain copy
- #include<iostream>
- int f(int n)
- {
- int i,sum=0;
- for(i=1;i<=n;i++)
- {
- sum+=i;<span style="color:#ff0000;">//迭代過程</span>
- }
- return sum;
- }
NOTICE遞歸和迭代的區別,通俗地說:遞歸就是把一件事情交給別人,如果事情沒有辦完,哪怕已經辦了很多,都不要把結果告訴我,我要的是你的最終結果,而不是中間結果;如果你沒辦完,請你找別人辦完;而迭代則是我交給你一件事,你能辦多少就告訴我你辦了多少,然後剩下的事情就由我來辦。
下面給出這兩種查詢方式在DNS查詢中的應用圖:
遞歸查詢:
迭代查詢:
Notice:通常情況下,主機向本地域名服務器的查詢一般都是採用遞歸查詢,本地域名服務器向根根域名服務器的查詢通常採用迭代查詢。
三、DNS報文格式
下面注意介紹下DNS報文中的標誌部分(注意不是標識,標識只是給出一個序列號,客戶在每次發送查詢時使用不同的標識好,服務器在響應的響應中重複這個標識號):
QR:定義報文類型,QR=0表示查詢報文,1表示響應報文;
opcode:定義查詢或響應的類型,0表示標準的,1表示反向的,2表示服務器狀態請求;
AA(Authoritative answer):授權回答,只用於響應報文。1表示該域名服務器是該區域的授權服務器;
TC(Truncated):可截斷的,使用UDP服務時,若響應報文的總長度超過512B,則只返回前512B;
RD(Recursion Desired):期望遞歸,0表示DNS客戶進程希望迭代查詢,1表示DNS客戶希望遞歸查詢;
RA(Recursion Available):遞歸可用,只用於響應報文。若域名服務器支持遞歸,則該服務器便在響應報文中將 RA=1。
(zero):保留字段;
rcode:表示在響應中的差錯狀態,只有權限服務器才能做出該判斷。具體如下:
0:無差錯 1:格式差錯 2:問題出在域名服務器上
3:名字差錯 4:查詢類型不支持 5:在管理上被禁止 6~15:保留
查詢問題(問題記錄):
查詢名:包含域名的可變長度字段,每個域以計數開頭,最後一個字符爲0(零),每個字符佔1B。如:www.baidu.com可以這樣記錄:3www5baidu3com0;
查詢類型:每一個問題的查詢有一個類型,響應也有一個類型。
其中最常用的查詢是A類型和PTR類型:A類型就是域名到IP地址,PTR查詢就是IP地址到域名。
查詢類:定義了使用DNS的特定協議,1表示因特網。
資源記錄(RR)
響應報文中的三種資源記錄(回答、授權、附加)均採用相同的格式,如下圖所示:
上圖域名、類型和類與查詢報文中的問題記錄中的查詢名、查詢類型、查詢類對應;
生存時間: 以s爲單位,定義了此回答的有效期(一般爲2天)。在這段有效期內,客戶長鬚可以將此回答保存在caching中,當TTL設置爲0表示該資源記錄只能用於本次回答,而不能存放在caching中;
資源數據長度:用於記錄後面資源數據的長度;
資源數據:包含對查詢的回答(在回答部分),或者權限服務器的域名(在授權部分),或者一些附加信息(在附加信息部分)。這個字段的格式和內容取決於類型字段的值。它可以是下述之一:
a.數值 這個數以八位組爲單位,例如IPv4是4個八位組的整數倍;
b.域名 記錄域名由兩種方法,方法一就是查詢報文中所提到的如:3www5baidu3com0,方法二是採用指針的方法,因爲一個回答報文中可能同時包含多種資源記錄RR,而對於每一種資源記錄RR,都會重複域名部分,爲了節約空間,在後面的RR(非第一個RR)的域名部分,我們採用偏移指針的方式。偏移指針(佔用16位)指的是偏離DNS響應報文首部最開始的位置(以字節爲單位)且以11開頭,偏移值範圍爲0~63B。例如偏離首部最開始部分12B可以記錄爲:1100 0000 0000 1100。
Notice:當在響應報文中出現域名重複時,DNS要求用偏移指針來代替域名,DNS定義了2B的偏移指針,格式“11+偏移長度”,最高位固定爲11,從而實現壓縮。
c.字符串 字符串用1B的長度字段緊跟着一串長度的字符。長度字段並不像域名長度哪有受限。字符串可以多打255個字符(包括長度字段)
四、高速緩存Caching
DNS客戶程序將查詢報文交給某個DNS服務器後(通常是主機域名服務器),若被查詢的域名不在該DNS服務器的映射表中,則該DNS服務器會向另外一個DNS服務器請求 映射並在接收到響應後,把該映射信息返回給DNS客戶程序之前,先要將該映射存儲在自己的Caching中。若同一個客戶或另一個客戶請求同樣的映射時,它就檢查caching,並能夠快速實現解析。當然,由於該服務器不是DNS程序的所請求域名的權限服務器,爲了告知DNS客戶程序這個響應是來自caching,而不是一個授權的信息源,這個服務器要把響應標記爲未授權的。
Caching可以提高解析效率,當然“如何更新Caching”是一個問題。可以採取如下方案反正Caching過時:
方案一:權限域名服務器把TTL的信息添加到映射上,因爲TTL定義了接收信息的服務器可以把映射信息放入Caching的時間長度(通常爲2天),經過這段時間後,這個映射就變爲無效的,因而任何查詢都必須在發送給權限服務器。
方案二:DNS要求每一個權限服務器對Caching中的每一條映射都有保持一個TTL計數器。Caching必須定期地搜索並清除那些TTL到期的映射。
五、DNS請求中UDP和TCP的選擇
DNS可以使用UDP/53,也可以使用TCP/53,當響應報文的長度小於512B時就使用UDP(因爲UDP的最大報文長度爲512B),若響應報文的長度超過512B,則選用TCP。DNS協議關於UDP和TCP的選擇通常爲以下兩種情況:
(1)若DNS客戶程序事先知道響應報文的長度512B,則應當使用TCP連接;
NOTICE:主域名服務器與輔助域名服務器在進行區域傳送時,通常數據量都比較大,所有DNS規定,區域傳送使用TCP協議。
(2)若解析程序不知道響應報文的長度,它一般使用UDP協議發送DNS查詢報文,若DNS響應報文的長度大於512B,服務器就截斷響應報文,並把TC(truncated)位置1,在這種情況下,DNS客戶程序通常使用TCP重發原來的查詢請求,從而它將來能夠從DNS服務器中收到完整的響應。
綜上所述,我們可以得出結論:DNS客戶程序在不知情(不知道DNS響應報文的長度是否超過512B)的情況下通常採用UDP與DNS服務器程序連接,在知情的情況下則採用TCP進行連接。