Java構建TCP/IP協議:DNS,域名解析協議系統的運行流程

DNS協議的運轉需要客戶端和服務器進行交互。由于服務器端需要存儲大量的域名信息,同時每天需要應答海量的解析請求,因此它的設計必須遵循分布式系統。客戶端向一臺服務器請求解析服務時,對方可能沒有相應的域名信息,于是它會向上一層查詢,獲得擁有給定域名信息的服務器,然后把對應服務器的信息歸還給客戶端,然后客戶端再重新發起請求。

我們還需要關注域名信息如何在服務器上存儲。在域名服務器上,信息存儲有兩種方式,一種是域名信息以二進制格式存儲,這種格式對應的名稱叫Resource Record Filed Format,同時為了方便管理員管理,這些信息又通過文本形式展現出來,對應的格式稱為Master File Representation,管理員通過修改后者就能使得對應的二進制信息進行相應變換:

Java構建TCP/IP協議:DNS,域名解析協議系統的運行流程

Resource Record 是一種特定數據結構,專門用于存儲域名解析相關信息,例如域名對應的服務器IP,域名解析服務器地址等,在后面我們解析數據包時再深入探討。

域名解析其實有三種形式,第一種是我們熟悉的,將域名發給服務器然后獲得域名對應IP;第二種叫反向解析,將IP發給服務器然后獲得對應域名;第三種叫電子郵件解析,將郵件地址發給服務器然后獲得郵件的接收對象IP。我們將主要關注第一種形式的原理和實現。

當我們執行第一種域名解析時,首先要做的是獲得域名服務器地址。這個過程并非一撮而就,有可能我們查詢第一個服務器時,它給我們返回另一個服務器的地址,然后我們繼續查詢;第二步是確定服務器后,我們要解析它返回來的數據內容。在這個過程中,第二步相對容易,而第一步則比較棘手。

在查詢對應域名服務器時有兩種方式,一種是循環式,第一個域名沒有對應信息,但返回另一個它認為有對應信息的服務器,接著客戶端向第二個服務器請求,第二個服務器又返回另一個服務器信息,該過程依次循環直到找到對應服務器為止:

Java構建TCP/IP協議:DNS,域名解析協議系統的運行流程

第二種叫遞歸式,它與一種的區別在于,服務器承擔起客戶端查找對應服務器的職責,服務器會反復向其他服務器查詢,直到拿到對應域名信息后,直接返回給客戶端:

Java構建TCP/IP協議:DNS,域名解析協議系統的運行流程

接下來我們看看DNS數據包的基本格式,首先第一部分叫頭部,用于描述消息類型,以及后續數據結構的相關信息;第二部分叫”問題“,它用來包含客戶端想向服務器查詢的信息;第三部分叫”答案“,是服務器用于回復客戶端查詢;第四部分叫Authority,如果請求沒有得到全部答復,這部分內容告訴客戶端向哪個服務器進行查詢;第五部分叫Additional,這部分包含客戶端查詢信息的附加說明,它并非必須,所以數據包的基本結構如下:

Java構建TCP/IP協議:DNS,域名解析協議系統的運行流程

我們用wireshark抓取dns有關的消息包后,對照上面描述的條目進行解析。啟動wireshark,然后使用關鍵詞dns過濾,然后在瀏覽器里輸入一個你以前沒有訪問過的網址,如果輸入已經訪問過的,瀏覽器會有緩存,因此不會走dns協議。以下是我抓取到的一個DNS解析請求包:

Java構建TCP/IP協議:DNS,域名解析協議系統的運行流程

首先是頭部,它包含12字節,從Transaction ID 到 Additional RRs,每個字段2字節。ID用來標志一次會話,一個會話內的數據包擁有相同ID。Flags分為兩部分,第一部分一字節叫做QR,用來表示該數據包是查詢還是回答,如果是查詢就設置為0,如果是回答就設置為1.如果是查詢,那么第二個字節就是OpCode,進一步表明具體查詢,它分為若干部分,前四個比特位用于表明查詢類型,0表示查詢域名對應IP,1不再使用;2表示查詢域名服務器狀態;3目前不使用,4用于服務器之間的交互;5也是用于服務器之間的交互。

第五個比特位叫AA,它只在回復包中設置,用于表明回復的權威性,它的具體內容我們暫時忽略。第六個比特位叫TC,它用于表明數據是否被截斷,用于DNS支持UDPTCP,但使用UDP時數據包不能超過512字節,如果超過數據包就得截斷成多個小數據包,如果該位設置成1,它表明雙方需要通過TCP來建立連接。第8位叫RD,如果設置成1,它意味著客戶端請求遞歸式查詢,也就是讓服務器幫忙向其他服務器詢問,得到最終消息后再返還給客戶端。

接下來字節的比特位是RA,如果設置為1表示服務器支持遞歸式查詢,也就是服務器把所有累活都承擔了,0則是不支持。接下來三個比特位必須設置為0,接著4個比特位表示返回碼,如果值為0表示返回數據正常,非0表示出現錯誤,其中取值1表示查詢數據包格式錯誤;2表示服務器自身故障;3表示解析錯誤;4表示不支持所要求的查詢;5表示拒絕查詢請求;其他值我們暫時忽略。

接下來用于表示相應條目的數量,Questions表示有幾個查詢條目,Answer RRs表示有幾個回復條目,Authority RRs表示有幾個權威信息條目,所謂“權威”是指真正能夠解析域名的服務器,如果當前服務器不能解析域名請求,它需要把請求轉發給其他服務器時,它自己就不是Authoritive,我們家用路由器其實承擔域名解析服務器的職責,但是它本身不可能包含所需要的域名信息,它會把請求轉發給上一層服務器,因此路由器就不是”權威“域名解析服務器。由此一個DNS域名解析數據包的輪廓如下:

Java構建TCP/IP協議:DNS,域名解析協議系統的運行流程

接下來我們看看問題段數據結構,它結構如下:

Java構建TCP/IP協議:DNS,域名解析協議系統的運行流程

首先是問題名字,這個字段長度可變,存儲的是要查詢的域名,以0作為結尾。第二個是問題類型,它是2字節,用于表明查詢的類型,取值1表示查詢域名對應IP,取值2查詢服務器名稱,具體類型在后面我們用到時再詳細討論。最后是問題類別,一般而言寫死為1。

這里我們講解一下Question Name對應的字符串結構,例如對于字符串:www.baidu.com,它的對應格式為[3]www[5]baidu[3]com,其中[]內表示接下來字符個數,例如[3]表示后面跟著3個字符www,[5]表示接下來跟著5個字符,注意到這些數字所在位置正好對應字符串中符號點所在位置。

接下來我們看Answer Resource Records 的結構,服務器收到客戶端請求,完成解析工作后,把解析信息存儲在該結構里發回給客戶端。它的結構如下,第一個是名字字符串,可變長,它對應要解析的域名或服務器名稱。接著是資源類型,2字節,表明資源的類型,如果取值是5,那么接下來對應著域名服務器對應的字符串名稱,接著是資源類別,2字節,一般設置成1;接著是TTL(Time To Live),4字節,表明這些信息能在緩存中存儲多久;接著是RDLength,2字節,用于表明接下來內容的長度;最后是相應內容,如果資源類型是5,那么內容就是字符串,如果是1,那么內容就是4字節的IP地址,該數據類型對應的格式輪廓如下:

Java構建TCP/IP協議:DNS,域名解析協議系統的運行流程

這里值得提到的是,如果資源類型5,那么對應的字符串才是“真正”域名,例如下面顯示內容:

Java構建TCP/IP協議:DNS,域名解析協議系統的運行流程

它顯示的是,一開始我們使用域名“pan.baidu.com”去進行域名解析,此時解析服務器沒有直接返回該域名對應的IP,而是返回另一個域名yiyun.n.shifen.com,前面”pan.baidu.com”其實是一個別名,打個比方,一個人可以使用假名和真名,假名可以隨時變,真名則要跟身份證綁定。同樣的道理,pan.baidu.com這個域名可以根據需要隨時變化,例如以后它可以變成pen.baidu.com,但是第二個域名就唯一綁定一臺服務器,我們只有拿這個域名去查詢才能找到對應的IP。

為了簡單起見,其他兩種資源的數據格式我們暫時放一放,以后需要的時候才研究,在下一節我們將使用代碼實現本節描述的DNS域名解析流程。

原文 

http://network.51cto.com/art/201906/597805.htm

本站部分文章源于互聯網,本著傳播知識、有益學習和研究的目的進行的轉載,為網友免費提供。如有著作權人或出版方提出異議,本站將立即刪除。如果您對文章轉載有任何疑問請告之我們,以便我們及時糾正。

PS:推薦一個微信公眾號: askHarries 或者qq群:474807195,里面會分享一些資深架構師錄制的視頻錄像:有Spring,MyBatis,Netty源碼分析,高并發、高性能、分布式、微服務架構的原理,JVM性能優化這些成為架構師必備的知識體系。還能領取免費的學習資源,目前受益良多

轉載請注明原文出處:Harries Blog? » Java構建TCP/IP協議:DNS,域名解析協議系統的運行流程

贊 (0)
分享到:更多 ()

評論 0

  • 昵稱 (必填)
  • 郵箱 (必填)
  • 網址
2013平特肖公式