生活随笔
收集整理的這篇文章主要介紹了
resolver
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
resolv.conf 文件格式;resolv.conf 文件是由一組關(guān)鍵詞及其值組成,若一行以";"/"#"開頭,則表明該行是注釋行;否則該行存放著一個(gè)關(guān)鍵詞及其對應(yīng)的取值;如下文件包含了"nameserver",以及"options"兩個(gè)關(guān)鍵詞;其中"127.0.1.1"為關(guān)鍵詞"nameserver"的取值;"ndots:1"為關(guān)鍵詞"options"的取值.
;?helloworld,注釋行.
nameserver?127.0.1.1
options?ndots:1
關(guān)鍵詞 //?resolver?對含有多個(gè)?DNS?Server?時(shí)使用的算法,假設(shè)當(dāng)前有?A,B?2?個(gè)?DNS?服務(wù)器
for(?i=0;i<最大重試次數(shù);++i)do{ret?=?use(A);?//?使用?A.if(?ret?==?SUCCESS)?//?若?A?成功返回結(jié)果,則中止break;ret?=?use(B);?//?否則使用?B?來解析請求.if(?ret?==?SUCCESS)break;?//?如果?B?也失敗,則再來一次.}while(0);//?我最初的想法是,當(dāng)?A?超時(shí)時(shí),再對?A?發(fā)送請求,直至達(dá)到最大重試次數(shù)后,再使用?B.
resolver 這里只介紹了 man 手冊中不清晰的地方,
_res.options RES_DEFNAMES,若在 _res.options 中指定該標(biāo)志,則若 res_search() 中指定的 dname 中不含有一個(gè)'.',則會將 resolv.conf 中 domain 關(guān)鍵詞的值追加到在 dname 之后,形成一個(gè)完全限定域名.
RES_DNSRCH,若在 _res.options 中指定該標(biāo)志,則 res_search() 會根據(jù) ndots 的值來判斷 dname 是否是一個(gè)完全限定域名(如 dname 中'.'的個(gè)數(shù) < ndots,則認(rèn)為不是).若 dname 被認(rèn)為是一個(gè)完全限定域名,則直接查詢 dname;否則若 dnmae 被認(rèn)為不是完全限定域名,則會依次在 search 關(guān)鍵詞中指定的域表下搜索 dname(若返回"沒有域名"的錯誤,則使用下一個(gè)域測試);如下:
//?resolv.conf?配置
search?xxx.yyy.net?yyy.net?net
options?ndots:2res_search("www.xxx",,,);
//?則此時(shí)會依次查詢
dn_comp() int?dn_comp(unsigned?char?*domain,?unsigned?char?*comp_dn,int?length,unsigned?char?**dnptrs,?unsigned?char?**lastdnptr);
domain;待壓縮的域名,
comp_dn,length;[comp_dn,comp_dn+length) 存放 domain 壓縮后的結(jié)果.
[dnsptr,lastdnptr) 確定了 u_char* 類型的指針數(shù)組,其中 dnptrs 指向著數(shù)組的第一個(gè)元素,lastdnptr-dnptrs 確定了數(shù)組的長度.這個(gè)數(shù)組存放著在當(dāng)前 DNS 消息中,已經(jīng)壓縮的域名的地址.其中第一個(gè)元素(dnptrs[0])指向著 DNS 消息的首部,以 NULLL 來表示有效元素的結(jié)束.在調(diào)用 dn_comp() 壓縮域名之后,會將 comp_dn 也追加到數(shù)組 dnptrs 中.
若 dnptrs 為 0,則不對 domain 進(jìn)行壓縮,即直接將其存放 [comp_dn,comp_dn+length) 中;
若 lastdnptr 不為 0,則不更新數(shù)組 dnptrs,即不將 comp_dn 追加到當(dāng)前數(shù)組中.
返回壓縮后域名的字節(jié)長度;或者 -1,表明出錯. void?printDnptrs(u_char?**dnptrs,int?dnptrsSize){for(int?i=0;i<dnptrsSize;++i)printf("%p?",dnptrs[i]);putchar('\n');
}///?依據(jù)?16?進(jìn)制(不帶?0x?前綴)輸出?[src,src+size)?中每一個(gè)字節(jié)的值
void?dump(void?*src,size_t?size){unsigned?char?*s?=?(unsigned?char*)src;for(size_t?i?=?0;i<size;++i)printf("%02hhx?",s[i]);putchar('\n');
}int?main(int?argc,char?*argv[]){const?int?bufSize?=?512;u_char?buf[bufSize]?=?{0};u_char?*dnsMsgBuf?=?buf;u_char?*?const?dnsMsgBufEnd?=?dnsMsgBuf+bufSize;//?[dnsMsgBuf,dnsMsgBufEnd)?存放?dns?消息.//?現(xiàn)在希望將用戶在命令行參數(shù)中指定的域名都以壓縮存儲的形式存放在?dns?消息中.//?dnptrsSize?取值為?7,去除?dnptrs[0],以及表示有效信息結(jié)束的?NULL,剩下?5?個(gè)元素用于//?存放壓縮過的域名地址,這表明在壓縮第?6?個(gè)域名時(shí)會根據(jù)?dnptrs?中存放的地址得到前?5?個(gè)//?域名壓縮信息,從而在壓縮第?6?個(gè)域名時(shí)可以使用這些信息;但在壓縮之后由于?dnptrs?沒有空間,//?所以第?6?個(gè)域名壓縮之后的地址不能存放在?dnptrs?中,即在壓縮第?7?個(gè)域名時(shí)使用的仍是前//?5?個(gè)域名壓縮后的信息.const?int?dnptrsSize?=?7;u_char?*dnptrs[dnptrsSize]?=?{dnsMsgBuf,0};?//?在調(diào)用?dn_comp?之前務(wù)忘初始化u_char?**?const?dnptrsEnd?=?dnptrs?+?dnptrsSize;int?ret?=?0;u_char?*nextDomainPtr?=?dnsMsgBuf+12;?//?第一個(gè)域名的存放地址,12?為?DNS?首部長.for(int?i?=?1;?i<argc;?++i){printf("%d:壓縮;域名:%s;",i,argv[i]);ret?=?dn_comp(argv[i],nextDomainPtr,dnsMsgBufEnd-nextDomainPtr,dnptrs,dnptrsEnd);if(ret?<?0){printf("err:%m\n");break;}printf("壓縮后長度:%d\n",ret);nextDomainPtr?+=?ret;nextDomainPtr?+=?4;printf("%d:",i);printDnptrs(dnptrs,dnptrsSize);}if(ret?<?0)return?1;puts("構(gòu)造好的?DNS?報(bào)文:");
//????dump(dnsMsgBuf,dnsMsgBufEnd-dnsMsgBuf);write(2,dnsMsgBuf,dnsMsgBufEnd-dnsMsgBuf);return?0;
}//?運(yùn)行:
$?./Test?www.360.com?www.qikoo.com?www.haosou.com?2>dnsmsg.txt
1:壓縮;域名:www.360.com;壓縮后長度:13
1:0x7fffa45e8080?0x7fffa45e808c?(nil)?(nil)?(nil)?(nil)?(nil)?
2:壓縮;域名:www.qikoo.com;壓縮后長度:12
2:0x7fffa45e8080?0x7fffa45e808c?0x7fffa45e809d?(nil)?(nil)?(nil)?(nil)?
3:壓縮;域名:www.haosou.com;壓縮后長度:13
3:0x7fffa45e8080?0x7fffa45e808c?0x7fffa45e809d?0x7fffa45e80ad?(nil)?(nil)?(nil)?
構(gòu)造好的?DNS?報(bào)文:
$?od?-A?d?-t?x1z?dnsmsg.txt
0000000?00?00?00?00?00?00?00?00?00?00?00?00?03?77?77?77??>.............www<
0000016?03?33?36?30?03?63?6f?6d?00?00?00?00?00?03?77?77??>.360.com......ww<
0000032?77?05?71?69?6b?6f?6f?c0?14?00?00?00?00?03?77?77??>w.qikoo.......ww<
0000048?77?06?68?61?6f?73?6f?75?c0?14?00?00?00?00?00?00??>w.haosou........<
0000064?00?00?00?00?00?00?00?00?00?00?00?00?00?00?00?00??>................<
*
0000512
//?可以看到??與??中的".com"都是使用??的壓縮.
dn_expand() int?dn_expand(unsigned?char?*msg,?unsigned?char?*eomorig,unsigned?char?*comp_dn,?char?*exp_dn,int?length);
msg,eomorig;[msg,eomorig) 中存放著一條完整的 DNS 報(bào)文.在 man 手冊中,只說明 msg 指向著報(bào)文的開始,而沒有說明 eomorig 的功能,經(jīng)過猜測與實(shí)現(xiàn),eomorig 的全稱應(yīng)該為 end of msg origin;
comp_dn,exp_dn,length; comp_dn 指向著域名(可能被壓縮了),dn_expand() 會解壓這個(gè)域名并將其存放在 [exp_dn,exp_dn+length) 確定的緩沖區(qū)中. 返回值是 comp_dn 指向的域名被壓縮的部分的字節(jié)長度(我覺得沒啥大用). ????//?現(xiàn)在[dnsMsgBuf,dnsMsgBufEnd)存放著?DNS?報(bào)文;而且數(shù)組?dnptrs?中存放著域名的地址.//?此時(shí)調(diào)用?dn_expand()?解壓出這些域名.char?domainBuf[256];for(int?i=1;dnptrs[i]!=0;++i){ret?=?dn_expand(dnsMsgBuf,dnsMsgBufEnd,dnptrs[i],domainBuf,sizeof(domainBuf));if(ret?<?0){printf("err:%m\n");break;}printf("%d:%s\n",i,domainBuf);}//?該段代碼追加在上面代碼"write(2,,)"之后,return?0?之前.
//?運(yùn)行:
1:www.360.com
2:www.qikoo.com
3:www.haosou.com
轉(zhuǎn)載于:https://my.oschina.net/u/1383479/blog/383862
總結(jié)
以上是生活随笔 為你收集整理的resolver 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔 推薦給好友。