?? dns協議.htm
字號:
<P align=justify>每個resolver的實現都不相同,會有復雜的邏輯處理各種錯誤,而本文只討論一個綱領。</P>
<P align=justify>4.3.1. 根(Stub)resolvers</P>
<P
align=justify>一種實現resolver的方法就是在支持循環查詢的服務器上實現,這樣可以節省PC機上的資源,也可以對查詢結果緩沖進行集中管理。其它的事情就是要一個支持循環查詢服務器地址的文件在PC機上,PC機上資源有限,支持一個域名數據庫可能不太現實。用戶必須確定所列的名字服務器支持循環查詢,服務器可以拒絕進行任何客戶的循環查詢請求,因此用戶必須向管理員核對。這種類型的服務有一些不足,因為循環查詢較費時,根對UDP重發時間的選擇比較難以確定,服務器會因為根的反復重發而崩潰。使用TCP或許會好,但這樣會嚴重占用主機時間,使用TCP相當于實現一個實時的查詢系統。</P>
<P align=justify>4.3.2. 資源</P>
<P
align=justify>除了自己的資源外,resolver可以訪問本地服務器保存的區數據。這會使resolver的速度加快,但是也可以讓緩沖數據沖掉區數據。本文中指的本地信息是說緩沖和共享區數據,在有認證數據和緩沖數據時應該優先使用認證數據。下面的算法假設所有函數被轉換為一個通常的查詢函數,使用下面的數據結構代表進行中的請求的狀態:</P></FONT>
<TABLE cellSpacing=1 cellPadding=7 width="100%" border=1>
<TBODY>
<TR>
<TD vAlign=top width="15%"><FONT face=宋體 size=3>
<P align=justify>SNAME</FONT></P></TD>
<TD vAlign=top width="85%">
<BLOCKQUOTE><FONT face=宋體 size=3>
<P align=justify>要查詢的域名</FONT></P></BLOCKQUOTE></TD></TR>
<TR>
<TD vAlign=top width="15%"><FONT face=宋體 size=3>
<P align=justify>STYPE</FONT></P></TD>
<TD vAlign=top width="85%">
<BLOCKQUOTE><FONT face=宋體 size=3>
<P align=justify>查詢請求的QTYPE</FONT></P></BLOCKQUOTE></TD></TR>
<TR>
<TD vAlign=top width="15%"><FONT face=宋體 size=3>
<P align=justify>SCLASS</FONT></P></TD>
<TD vAlign=top width="85%">
<BLOCKQUOTE><FONT face=宋體 size=3>
<P align=justify>查詢請求的QCLASS</FONT></P></BLOCKQUOTE></TD></TR>
<TR>
<TD vAlign=top width="15%"><FONT face=宋體 size=3>
<P align=justify>SLIST</FONT></P></TD>
<TD vAlign=top width="85%">
<BLOCKQUOTE><FONT face=宋體 size=3>
<P
align=justify>表示正在查詢的名字服務器和區,它保存resolver的預測,預測希望查詢的數據在什么地方,通過接收的數據,此結構內的數據會發生變化。它包括服務器地址,區內已知的服務器,歷史記錄,以及表示查詢距離目標還有多遠的標記(查詢從樹頂開始向下,直到目標)。</FONT></P></BLOCKQUOTE></TD></TR>
<TR>
<TD vAlign=top width="15%"><FONT face=宋體 size=3>
<P align=justify>SBELT</FONT></P></TD>
<TD vAlign=top width="85%">
<BLOCKQUOTE><FONT face=宋體 size=3>
<P
align=justify>在resolver無法從本地信息知道應該查詢哪個服務器時,它就派上用場了。</FONT></P></BLOCKQUOTE></TD></TR>
<TR>
<TD vAlign=top width="15%"><FONT face=宋體 size=3>
<P align=justify>CACHE</FONT></P></TD>
<TD vAlign=top width="85%">
<BLOCKQUOTE><FONT face=宋體 size=3>
<P
align=justify>保存前一次響應的結果,因為resolver會拋棄達到TTL時間的RR,所有大部分resolver實現將接收到RR的時間轉換為絕對時間,然后保存在緩沖中,resolver可以在查詢時順便將過期RR拋棄,也可定期進行維護。</FONT></P></BLOCKQUOTE></TD></TR></TBODY></TABLE><FONT
face=宋體 size=3>
<P align=justify>4.3.3. 算法</P>
<P align=justify>大體上,算法有四步:</P>
<BLOCKQUOTE>
<OL>
<LI>
<P align=justify>檢查結果是否在本地,如果是則直接返回;</P>
<LI>
<P align=justify>向最合適的服務器查詢;</P>
<LI>
<P align=justify>向多個服務器發出請求,直到得到響應;</P>
<LI>
<P align=justify>分析結果:</P></LI></OL>
<BLOCKQUOTE>
<UL>
<LI>
<P align=justify>如果響應給出了結果或包含名字錯誤,緩沖并返回結果給用戶;</P>
<LI>
<P align=justify>如果響應指出更合適的服務器,緩沖這個結果,轉第2步;</P>
<LI>
<P align=justify>如果響應顯示CNAME,但并不是答案,緩沖CNAME,將SNAME改為CNAME
RR中的統一名稱,然后轉第1步;</P>
<LI>
<P
align=justify>如果響應顯示服務器失敗或其它不可識別的內容,從SLIST中刪除此服務器,然后轉第3步。</P></LI></UL></BLOCKQUOTE></BLOCKQUOTE>
<P
align=justify>第1步在緩沖內查找,如果找到了,那就返回給用戶。有些resolver可以設置不使用緩沖內的數據,但并不推薦把它做為默認情況。如果resolver能夠直接訪問服務器的區,而且能夠找到數據的認證形式,則不要使用緩沖內的數據。</P>
<P
align=justify>第2步向服務器查詢需要的數據,通常的辦法是尋找本地提供的服務器RR,提供SNAME,然后給出SNAME的父域名,父域名的父域名,以此類推,直到根。因此,如果SNAME=Mockapetris.ISI.EDU,查詢NS
RR的順序為Mockapetris.ISI.EDU,ISI.EDU,EDU,最后是.(根)。NS
RR列出了此區的或在SNAME之上的主機名,復制名字到SLIST,使用本地信息設置它們的地址,可能地址不可用,此時resolver有幾種不同的選擇,最好是進行并行搜索,一個搜索現在可用的,一個去尋找新的,當然實現起來就有麻煩了,我們把實現的一些規則列于下面:</P>
<BLOCKQUOTE>
<UL>
<LI>
<P
align=justify>加入一些限制,讓請求不會進入無限循環,也不會造成對鏈式請求和對其它服務的鏈式請求,即使在有人錯誤配置的情況下也不能造成上述情況</P>
<LI>
<P align=justify>盡一切可以獲得響應</P>
<LI>
<P align=justify>避免不必要的傳輸</P>
<LI>
<P align=justify>盡快獲得響應</P></LI></UL></BLOCKQUOTE>
<P align=justify>如果查詢NS
RR失敗,resolver從SBELT中初始化SLIST,基本的思想是當resolver不知道哪個服務器在工作時,它會從一個配置文件中取得相應的信息。雖然是特殊情況,但基本上要有兩個根服務器地址存在于這種配置文件中。有兩個是為了冗余,根服務器可以對所有的域空間進行探索,兩個本地服務器將允許resolver繼續嘗試利用本地資源解析域名。除了名字的名字和地址,SLIST中可以保存服務器的優先查詢順序,保證高優先級在前,本地服務器在遠程服務器前,也可能是由成功的統計結果得到,算法不盡相同。</P>
<P
align=justify>第3步發出請求,直到收到響應。算法基本思想是對所有列出的服務器以循環方式進行發送。實際上,要重視多穴(multihomed)主機的多個地址,在使用多個resolver的時候要注意對相同主機進行重新傳輸對時間的影響。SLIST通常包括一個值,用于控制和監視傳輸的超時。</P>
<P
align=justify>第4步涉及分析結果,resovler應該檢查響應的ID域看是不是和請求的ID一致。理想的響應是從認證權威那里收到的數據,它要么給出需要的數據,要么給出名字錯誤。在TTL大于0的時候,結果保存于緩沖,同時結果返回給用戶。如果結果指出其它服務器A,要對這個服務器A和SLIST中的主機進行比較,看是不是更合適,這可以通過比較SLIST中的匹配計數完成,這個匹配計數是通過SNAME和服務器A中的NS
RR計算得到。如果不合適,這個響應會被忽略,如果合適,結果會被緩沖,相應的服務器會進入SLIST,新的查詢開始。如果響應包括CNAME,新查詢將從CNAME開始,除非響應有標準格式的數據,或CNAME就中結果。</P>
<P align=justify>5.例子</P>
<P
align=justify>在我們的例子空間中,假設我們希望將根管理權分散到MIL,EDU,MIT.EDU和ISI.EDU區,我們可以按下圖分配名字服務器:(認證權威將被加上括號)</P>
<P align=justify> </P><PRE> |(C.ISI.EDU,SRI-NIC.ARPA
| A.ISI.EDU)
+---------------------+------------------+
| | |
MIL EDU ARPA
|(SRI-NIC.ARPA, |(SRI-NIC.ARPA, |
| A.ISI.EDU | C.ISI.EDU) |
+-----+-----+ | +------+-----+-----+
| | | | | | |
BRL NOSC DARPA | IN-ADDR SRI-NIC ACC
|
+--------+------------------+---------------+--------+
| | | | |
UCI MIT | UDEL YALE
|(XX.LCS.MIT.EDU, ISI
|ACHILLES.MIT.EDU) |(VAXA.ISI.EDU,VENERA.ISI.EDU,
+---+---+ | A.ISI.EDU)
| | |
LCS ACHILLES +--+-----+-----+--------+
| | | | | |
XX A C VAXA VENERA Mockapetris</PRE>
<P
align=justify>根名字服務器在C.ISI.EDU,SRI-NIC.ARPA和A.ISI.EDU,MIL域由SRI-NIC.ARPA和A.ISI.EDU支撐;EDU域由SRI-NIC.ARPA和C.ISI.EDU,服務器擁有的區可以連接也可以不連接,本例中,C.ISI.EDU和根及EDU域連接,A.ISI.EDU和根及MIL域有連接,但和ISI.EDU有一個不連接的區。</P>
<P align=justify>5.1. C.ISI.EDU名字服務器</P>
<P align=justify>C.ISI.EDU是IN級的根,MIL,EDU域的名字服務器,也擁有這些域的區,對根域的區數據如下:</P><PRE> . IN SOA SRI-NIC.ARPA. HOSTMASTER.SRI-NIC.ARPA. (
870611 ;serial
1800 ;refresh every 30 min
300 ;retry every 5 min
604800 ;expire after a week
86400) ;minimum of a day
NS A.ISI.EDU.
NS C.ISI.EDU.
NS SRI-NIC.ARPA.
MIL. 86400 NS SRI-NIC.ARPA.
86400 NS A.ISI.EDU.
EDU. 86400 NS SRI-NIC.ARPA.
86400 NS C.ISI.EDU.
SRI-NIC.ARPA. A 26.0.0.73
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -