tcpip協(xié)議詳解卷二實現(xiàn)17_第1頁
tcpip協(xié)議詳解卷二實現(xiàn)17_第2頁
tcpip協(xié)議詳解卷二實現(xiàn)17_第3頁
tcpip協(xié)議詳解卷二實現(xiàn)17_第4頁
tcpip協(xié)議詳解卷二實現(xiàn)17_第5頁
已閱讀5頁,還剩12頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認(rèn)領(lǐng)

文檔簡介

1、 下載第17章插 口 選 項17.1引言本章討論修改插口行為的幾個系統(tǒng)調(diào)用,以此來結(jié)束插口層的介紹。 setsockopt和getsockopt系統(tǒng)調(diào)用已在第8.8節(jié)中介紹過,主要描述訪問IP特點的選項。在本章中,我們將介紹這兩個系統(tǒng)調(diào)用的實現(xiàn)以及通過它們來控制的插口級選項。 ioctl函數(shù)在第4.4節(jié)中已介紹過,在第4.4節(jié)中,我們描述了用于網(wǎng)絡(luò)接口配置的與協(xié)議無關(guān)的ioctl命令。在第6.7節(jié)中,我們描述了用來分配網(wǎng)絡(luò)掩碼以及單播、多播和目的地址的IP 專用的ioctl命令。本章我們將介紹ioctl的實現(xiàn)和fcntl函數(shù)的相關(guān)特點。 最后,我們介紹getsockname和getpeerna

2、me系統(tǒng)調(diào)用,它們用來返回插口和連接的地址信息。 圖17-1列出了實現(xiàn)插口選項系統(tǒng)調(diào)用的函數(shù)。本章描述帶陰影的函數(shù)。 圖17-1 setsockopt 和getsockopt 系統(tǒng)調(diào)用 17.2代碼介紹 本章中涉及的源代碼來自于圖 17-2中列出的四個文件。圖17-2 本章討論的源文件 文 件 名 說 明 kern/kern_descrip.c kern/uipc_syscalls.c kern/uipc_socket.c kern/sys_socket.cfcntl系統(tǒng)調(diào)用 setsockopt、getsockopt、getsockname和getpeername系統(tǒng)調(diào)用 插口層對setso

3、ckopt和getsockopt的處理 ioctl系統(tǒng)調(diào)用對插口的處理 432TCP/IP詳解 卷2:實現(xiàn) 全局變量和統(tǒng)計量 下載本章中描述的系統(tǒng)調(diào)用沒有定義新的全局變量,也沒有收集任何統(tǒng)計量。 17.3setsockopt系統(tǒng)調(diào)用 圖8-29列出了函數(shù)setsockopt (和getsockopt)能夠訪問的各種不同的協(xié)議層。本章主要集中在SOL_SOCKET級的選項,這些選項在圖17-3中列出。 圖17-3 setsockopt 和getsockopt 選項 setsockopt函數(shù)原型為: int setsockopt(int s, int level, int optname, voi

4、d *optval, int optlen);圖17-4顯示了setsockopt調(diào)用的源代碼。 5 6 5 - 5 9 7 getsock返回插口描述符的file結(jié)構(gòu)。如果val非空,則將valsize個字節(jié)的數(shù)據(jù)從進程復(fù)制到用m_get分配的mbuf中。與選項對應(yīng)的數(shù)據(jù)長度不能超過MLEN個字節(jié),所以, 如果valsize大于MLEN,則返回EINVAL。調(diào)用sosetopt,并返回其值。 圖17-4 setsockopt 系統(tǒng)調(diào)用 optnameoptval 類型 變 量 說 明 SO_ SNDBUF SO_ RCVBUFSO_ SNDLOWAT SO_ RCVLOWAT SO_ SND

5、TI MEO SO_ RCVTI MEO SO_ DEBUGSO_ REUSEADDR SO_ REUSEPORT SO_ KEEPAL I VE SO_ DONTROUTE SO_ BROADCASTSO_ USELOOPBACSO_ OOBI NL I NE S O_ L I NGERSO_ ERROR S O_ TYPE其他 int int int intstruct timeva struct timeva intint int int int int Kintintstruct linger intintso_snd.sb_hiwat so_rcv.sb_hiwat so_snd.s

6、b_lowat so_rcv.sb_lowat lso_snd.sb_timeo so_snd.sb_timeo so_options so_options so_options so_options so_options so_options so_optionsso_options so_linger so_error so_type發(fā)送緩存高水位標(biāo)記接收緩存高水位標(biāo)記發(fā)送緩存低水位標(biāo)記接收緩存低水位標(biāo)記發(fā)送超時值 接收超時值 記錄插口調(diào)試信息 插口能重新使用一個本地地址插口能重新使用一個本地端口協(xié)議查詢空閑的連接 旁路路由表 插口支持廣播報文 僅用于選路域插口;發(fā)送進程接收自己的選路報文

7、 協(xié)議排隊內(nèi)聯(lián)的帶外數(shù)據(jù) 插口關(guān)閉但仍發(fā)送剩余數(shù)據(jù) 獲取差錯狀態(tài)并清除;只用于getsockopt 獲取插口類型;只用于getsockopt返回ENOPROTOOPT 第 17 章 插 口 選 項433下載圖17-4 (續(xù))sosetopt函數(shù) sosetopt函數(shù)處理所有插口級的選項,并將其他的選項傳給與插口關(guān)聯(lián)的協(xié)議的pr_ctloutput函數(shù)。圖17-5列出了sosetopt函數(shù)的部分代碼。 圖17-5 sosetopt 函數(shù) 434TCP/IP詳解 卷2:實現(xiàn) 下載圖17-5 (續(xù))7 5 2 - 7 6 4 如果選項不是插口級的(SOL_SOCKET)選項,則給底層協(xié)議發(fā)送PRCO

8、_SETOPT請求。注意:調(diào)用的是協(xié)議的 pr_ctloutput函數(shù),而不是它的pr_usrreq函數(shù)。圖17-6說明了Internet協(xié)議調(diào)用的pr_ctloutput函數(shù)。 圖17-6 pr_ctloutput 函數(shù) 7 6 5 switch語句處理插口級的選項。 8 4 1 - 8 4 4 對于不認(rèn)識的選項,在保存它的mbuf被釋放后返回ENOPROTOOPT。 8 4 5 - 8 5 5 如果沒有出現(xiàn)差錯,則控制總是會執(zhí)行到 switch。在switch語句中,如果協(xié)議層需要響應(yīng)請求或插口層,則將選項傳送給相應(yīng)的協(xié)議。 Internet協(xié)議中沒有一個預(yù)期處理插口級的選項。 注意,如果

9、協(xié)議收到不預(yù)期的選項,則直接將其 pr_ctloutput函數(shù)的返回值丟棄。并將m置空,以免調(diào)用m_free,因為協(xié)議負(fù)責(zé)釋放緩存。 圖17-7說明了linger選項和在插口結(jié)構(gòu)中設(shè)置單一標(biāo)志的選項。 7 6 6 - 7 7 2 linger選項要求進程傳入linger結(jié)構(gòu): struct linger int l_onoff;/* option on/off */int l_linger; /* linger time in seconds */;確保進程已傳入長度為 l i n g e r結(jié)構(gòu)大小的數(shù)據(jù)后,將結(jié)構(gòu)成員 l _ l i n g e r 復(fù)制到so_linger中。在下一組ca

10、se語句后決定是使能還是關(guān)閉該選項。 so_linger和close系統(tǒng)調(diào)用在第15.15節(jié)中已介紹過。 7 7 3 - 7 8 9 當(dāng)進程傳入一個非0值時,設(shè)置選項對應(yīng)的布爾標(biāo)志;當(dāng)進程傳入的是 0時,將對應(yīng)標(biāo)志清除。第一次檢查確保一個整數(shù)大小 (或更大)的對象在mbuf中,然后設(shè)置或清除對應(yīng)的選項。 圖17-8顯示了插口緩存選項的處理。 7 9 0 - 8 1 5這組選項改變插口的發(fā)送和接收緩存的大小。第一個 if語句確保提供給四個選項的變量是整型。對于SO_SNDBUF和SO_RCVBUF,sbreserve只調(diào)整緩存的高水位標(biāo)記而不 協(xié) 議 pr_ctloutput函數(shù) 參 考 UDP

11、 TCPip_ctloutput tcp_ctloutput第 8.8 節(jié) 第30.6節(jié) ICMP IGMP原始IPrip_ctloutput和ip_ctloutput第8.8節(jié)和第32.8節(jié) 第 17 章 插 口 選 項435下載分配緩存。對于SO_SNDLOWAT和SO_RCVLOWAT,調(diào)整緩存的低水位標(biāo)記。 圖17-7sosetopt函數(shù):linger 和標(biāo)志選項圖17-8 sosetopt 函數(shù):插口緩存選項 436TCP/IP詳解 卷2:實現(xiàn) 圖17-9說明超時選項。 下載圖17-9 sosetopt 函數(shù):超時選項 8 1 6 - 8 2 4進程在timeval結(jié)構(gòu)中設(shè)置SO_S

12、NDTIMEO和SO_RCVTIMEO選項的超時值。如果傳入的數(shù)值不正確,則返回EINVAL。 8 2 5 - 8 3 0存儲在timeval結(jié)構(gòu)中的時間間隔值不能太大,因為 sb_timeo是一個短整數(shù), 當(dāng)時間間隔值的單位為一個時鐘滴答時,時間間隔值的大小就不能超過一個短整數(shù)的最大值。 第826行代碼是不正確的。在下列條件下,時間間隔不能表示為一個短整數(shù): tv_usectv_sec hz + SHRT_MAXtick其中,ticck= 1 000 000 /和h zSHRT_MAX=32767所以,如果下列不等式成立,則返回。 tv_sec SHRT_MAX - tv_usec = SH

13、RT_MAX - tv_usectick hzhzhz100000等式的最后一項不是代碼指明的hz。正確的測試代碼應(yīng)該是: if (tv-tv_sec * hz+tv-tv_usec/tickSHRT_MAX) error=EDOM;習(xí)題17.3中有更詳細(xì)的討論。 8 3 1 - 8 4 0將轉(zhuǎn)換后的時間, val,保存在請求的發(fā)送或接收緩存中。 sb_timeo限制了進程等待接收緩存中的數(shù)據(jù)或發(fā)送緩存中的閑置空間的時間。詳細(xì)討論參考第 16.7和16.11節(jié)。 超時值是傳給tsleep的最后一個參數(shù),因為tsleep要求超時值為一個整數(shù),所以進程最多只能等待65535個時鐘滴答。假設(shè)時鐘頻率

14、為100 Hz,則等待時間小于11分鐘。 第 17 章 插 口 選 項437下載17.4getsockopt系統(tǒng)調(diào)用 getsockopt返回進程請求的插口和協(xié)議選項。函數(shù)原型是: int getsockopt(int s, int level, int name, caddr_t val, int *valsize);該調(diào)用的源代碼如圖17-10所示。 圖17-10getsockopt 系統(tǒng)調(diào)用5 9 8 - 6 3 3 這段代碼現(xiàn)在看上去應(yīng)該很熟悉了。 getsock獲取插口的file結(jié)構(gòu),將選項緩存的大小復(fù)制到內(nèi)核,調(diào)用 sogetopt來獲取選項的值。將sogetopt返回的數(shù)據(jù)復(fù)制到

15、進程提供的緩存,可能還需修改緩存長度。如果進程提供的緩存不夠大,則返回的數(shù)據(jù)可能會 被截掉。通常情況下,存儲選項數(shù)據(jù)的mbuf在函數(shù)返回后被釋放。 sogetopt函數(shù) 同sosetopt一樣, sogetopt函數(shù)處理所有插口級的選項,并將其他的選項傳給與插口關(guān)聯(lián)的協(xié)議。圖17-11列出了sogetopt函數(shù)的開始和結(jié)束部分的代碼。 438TCP/IP詳解 卷2:實現(xiàn) 下載圖17-11 sogetopt 函數(shù):概述8 5 6 - 8 7 1同s o s e t o p t 一樣, 函數(shù) 將那 些與 插口 級選項 無關(guān) 的選 項立 即通過 PRCO_GETOPT協(xié)議請求傳遞給相應(yīng)的協(xié)議級。協(xié)議

16、將被請求的選項保存在 mp指向的mbuf中。對于插口級的選項,分配一塊標(biāo)準(zhǔn)的 mbuf緩存來保存選項值,選項值通常是一個整數(shù), 所以將m_len設(shè)成整數(shù)大小。相應(yīng)的選項值通過switch語句復(fù)制到mbuf中。 9 1 8 - 9 2 5如果執(zhí)行的是 s w i t c h中的d e f a u l t情況下的語句,則釋放 mbuf,并返回 ENOPROTOOPT。否則, switch語句執(zhí)行完成后,將指向mbuf的指針賦給*mp。當(dāng)函數(shù)返回后,getsockopt從該mbuf中將數(shù)據(jù)復(fù)制到進程提供的緩存,并釋放 mbuf。 圖17-12說明對SO_LINGER選項和作為布爾型標(biāo)志實現(xiàn)的選項的處

17、理。 8 7 2 - 8 7 7 SO_LINGER選項請求返回兩個值:一個是標(biāo)志值,賦給 l_onoff;另一個是拖延時間,賦給l_linger。 8 7 8 - 8 8 7 其余的選項作為布爾標(biāo)志實現(xiàn)。將so_options和optname執(zhí)行邏輯與操作,如果選項等于1。 開,則與操作的結(jié)果為非 0值;反之則結(jié)果為 0。注意:標(biāo)志開并不表示返回值sogetopt的下一部分代碼(圖17-13)將整型值選項的值復(fù)制到mbuf中。 8 8 8 - 9 0 6 將每一個選項作為一個整數(shù)復(fù)制到 mbuf中。注意:有些選項在內(nèi)核中是作為一個短整數(shù)存儲的(如緩存高低水位標(biāo)記 ),但是作為整數(shù)返回。一旦將

18、 so_error復(fù)制到mbuf中后,即清除so_error,這是唯一的一次getsockopt調(diào)用修改插口狀態(tài)。 第 17 章 插 口 選 項439下載圖 17-12 sogetopt選項:SO_LINGER選項和布爾選項圖17-13 sogetopt 函數(shù):整型值選項 圖17-14 sogetopt 函數(shù):超時選項 440TCP/IP詳解 卷2:實現(xiàn) 下載圖17-14列出了sogetopt的第三和第四部分代碼,它們的作用分別是處理SO_SNDTIMEO 和SO_RCVTIMEO選項。 9 0 7 - 9 1 7將發(fā)送或接收緩存中的 sb_ timeo值賦給var?;趘al中的時鐘滴答數(shù),

19、在mbuf中構(gòu)造一個timeval結(jié)構(gòu)。 計算tv_usec的代碼有一個差錯。表達式應(yīng)該為: (val % h z) * tick。 17.5fcntl和ioctl系統(tǒng)調(diào)用 因為歷史的原因而非有意這么做,插口API的幾個特點既能通過ioctl也能通過fcntl來訪問。關(guān)于ioctl命令,我們已經(jīng)討論了很多。我們也幾次提到 fcntl。 圖17-15顯示了本章描述的函數(shù)。 系統(tǒng)調(diào)用默認(rèn)得到配置圖17-15ioctl和fcntl的原型分別為: int ioctl(int fd, unsigned long result, char *argp); int fcntl(int fd, int cmd

20、,. /* int arg */);fcntl 和ioctl 函數(shù) 第 17 章 插 口 選 項441下載圖17-16總結(jié)了這兩個系統(tǒng)調(diào)用與插口有關(guān)的特點。我們在圖 17-16中還列出了一些傳統(tǒng)的 常數(shù),因為它們出現(xiàn)在代碼中??紤]與 P o s i x 的兼容性,可以用FNONBLOCK,用O_ASYNC來代替FASYNC。 O _ N O N B L O C K 來代替圖17-16 fcntl 和ioctl 命令 17.5.1 fcntl代碼 圖17-17列出了fcntl函數(shù)的部分代碼。 圖17-17 fcntl系統(tǒng)調(diào)用:概況 描 述 fcntlioctl通過打開或關(guān)閉so_state中的S

21、S_NBIO 來使能或禁止非阻塞功能 FNONBLOCK文件狀態(tài)標(biāo)志 FIONBIO命令 通過打開或關(guān)閉sb_flags中的 SB_ASYNC 來使能或禁止異步功能 FASYNC文件狀態(tài)標(biāo)志 FIOASYNC命令 設(shè)置或得到so_pgid,它是SIGIOG和 SIGURG信號的目標(biāo)進程或進程組 F_SETOWN或F_GETOWNSIOCSPGRP或SIOCGPGRP命令 得到接收緩存中的字節(jié)數(shù);返回 so_rcv.sb_ccFIONREAD返回OOB同步標(biāo)記;即so_state中的SS_RCVATMARK標(biāo)志 SIOCATMARK 442TCP/IP詳解 卷2:實現(xiàn) 下載1 3 3 - 1 5

22、 3 驗證完指向打開文件的描述符的正確性后, switch語句處理請求的命令。 2 5 3 - 2 5 7 對于不認(rèn)識的命令, fcntl返回EINVAL。圖17-18僅顯示fcntl中與插口有關(guān)的代碼。 圖17-18 fcntl 系統(tǒng)調(diào)用:插口處理1 6 8 - 1 8 5 F_GETFL返回與描述符相關(guān)的當(dāng)前文件狀態(tài)標(biāo)志, F_SETFL設(shè)置狀態(tài)標(biāo)志。通過調(diào)用fo_ioctl將FNONBLOCK和FASYNC的新設(shè)置傳遞給對應(yīng)的插口,而插口的新設(shè)置是通過圖17-20中描述的soo_ioctl函數(shù)來傳遞的。只有在第二個 fo_ioctl調(diào)用失敗后,才第三次調(diào)用fo_ioctl。該調(diào)用的功能是

23、清除FNONBLOCK標(biāo)志,但是應(yīng)該改為將這個標(biāo)志恢復(fù) 第 17 章 插 口 選 項443下載到原來的值。 1 8 6 - 1 9 4 F_GETOWN返回與插口相關(guān)聯(lián)的進程或進程組的標(biāo)識符, so_pgid。對于非插口描述符,將T I O C G P G R Pioc t l命令傳給對應(yīng)的 fo_ioctl函數(shù)。F_SETOWN的功能是給 so_pgid賦一個新值。 17.5.2 ioctl代碼 我們跳過 i o c t l系統(tǒng)調(diào)用本身而先從 s o o _ i o c t l開始討論,如圖 17 -20所示,因為ioctl的代碼中的大部分是從圖 17-17所示的代碼中復(fù)制的。我們已經(jīng)說過,

24、 soo_ioctl函數(shù)將選路命令發(fā)送給rtioctl,接口命令發(fā)送給ifioctl,任何其他的命令發(fā)送給底層協(xié)議的pr_usrreq函數(shù)。 5 5 - 68有幾個命令是由soo_ioctl直接處理的。如果*data非空,則FIONBIO打開非阻 塞方式,否則關(guān)閉非阻塞方式。正于我們已經(jīng)了解的,這個標(biāo)志將影響到 connect和close系統(tǒng)調(diào)用,也包括其他的讀和寫系統(tǒng)調(diào)用。 a c c e p t 、6 9 - 79FIOASYNC使能或禁止異步I/O功能。如果設(shè)置了SS_ASYNC,則無論什么時候 插口上有活動,就調(diào)用sowakeup,將信號SIGIO發(fā)送給相應(yīng)的進程或進程組。 8 0 -

25、 88FIONREAD返回接收緩存中的可讀字節(jié)數(shù)。 SIOCSPGRP設(shè)置與插口相關(guān)的進程組, SIOCGPGRP則是得到它。 so_pgid作為我們剛討論過的 SIGIO信號的目標(biāo)進程或進程組, 當(dāng)有帶外數(shù)據(jù)到達插口時,則作為SIGURG信號的目標(biāo)進程或進程組。 8 9 - 9 2 如果插口正處于帶外數(shù)據(jù)的同步標(biāo)記,則 SIOCATMARK返回真;否則返回假。ioctl命令,F(xiàn)IOxxx和SIOxxx常量,有一個內(nèi)部結(jié)構(gòu),如圖 17-19所示。 輸入 輸出 空 圖17-19 ioctl 命令的內(nèi)部結(jié)構(gòu) 圖17-20 soo_ioctl 函數(shù) 444TCP/IP詳解 卷2:實現(xiàn) 下載圖17-2

26、0 (續(xù))如果將ioctl的第三個參數(shù)作為輸入,則設(shè)置input。如果該參數(shù)作為輸出,則 output被置位。如果不用該參數(shù),則v o i d 被置位。length是參數(shù)的大小(字節(jié))。相關(guān)的命令在同一個g ro u p 中但每一個命令在組中都有各自的number。圖17-21中的宏用來解析ioctl命令中的元素。 圖17-21 ioctl 命令宏9 3 - 10 4宏IOCGROUP從命令中得到8 bit的group。接口命令由ifioctl處理。選路命令由 rtioctl處理。通過PRU_CONTROL請求將所有其他的命令傳遞給插口協(xié)議。 正如我們在第19章中描述的, Net/2定義了一個

27、新的訪問路由選擇表接口,在該接口中,報文是通過一個在PF_ROUTE域中產(chǎn)生的插口傳遞給路由選擇子系統(tǒng)。用這種方法來代替這里討論的ioctl。在不兼容的內(nèi)核中,rtioctl總是返回ENOTSUPP。 17.6getsockname系統(tǒng)調(diào)用getsockname系統(tǒng)調(diào)用的原型是: 宏 描 述 IOCPARM_LEN(cmd) IOCBASECMD(cmd) IOCGROUP(cmd)返回cmd中的length length 設(shè)為0 的命令返回cmd中的group 第 17 章 插 口 選 項445下載int getsockname(int fd, caddr_t asa, int * alen

28、);getsockname得到綁定在插口 fd上的本地地址,并將它存入 asa指向的緩存中。當(dāng)在一個隱式的綁定中內(nèi)核選擇了一個地址,或在一個顯式的 bind調(diào)用中進程指定了一個通配符地址(2.2.5節(jié))時,該函數(shù)就很有用。getsockname系統(tǒng)調(diào)用如圖17-22所示。 圖17-22 getsockname 系統(tǒng)調(diào)用 6 8 2 - 7 1 5 getsock返回描述符的file結(jié)構(gòu)。將進程指定的緩存的長度賦給len。這是我們第一次看到對m_getclr的調(diào)用:該函數(shù)分配一個標(biāo)準(zhǔn)的 mbuf,并調(diào)用bzero清零。當(dāng)協(xié)議收到PRU_SOCKADDR請求時,協(xié)議處理層負(fù)責(zé)將本地地址存入 m。 如果地址長度大于進程提供的緩存的長度,則返回的地址將被截掉。 *alen等于實際返回的字節(jié)數(shù)。最后,釋放mbuf,并返回。 17.7getpeername系統(tǒng)調(diào)用 getpeername系統(tǒng)調(diào)用的原型是: int getpeername(int fd, caddr_t asa, i

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論