基礎(chǔ)信息
權(quán)利要求
說(shuō)明書(shū)
PDF全文
法律信息
引證文獻(xiàn)
著錄項(xiàng)信息
專(zhuān)利名稱(chēng) | 一種TCP數(shù)據(jù)包的傳輸方法 |
申請(qǐng)?zhí)?/td> | CN200810055730.6 | 申請(qǐng)日期 | 2008-01-08 |
法律狀態(tài) | 權(quán)利終止 | 申報(bào)國(guó)家 | 中國(guó) |
公開(kāi)/公告日 | 2008-07-09 | 公開(kāi)/公告號(hào) | CN101217493 |
優(yōu)先權(quán) | 暫無(wú) | 優(yōu)先權(quán)號(hào) | 暫無(wú) |
主分類(lèi)號(hào) | H04L12/56 | IPC分類(lèi)號(hào) | H;0;4;L;1;2;/;5;6;;;H;0;4;L;2;9;/;0;6查看分類(lèi)表>
|
申請(qǐng)人 | 北京大學(xué) | 申請(qǐng)人地址 | 北京市海淀區(qū)頤和園路5號(hào)
變更
專(zhuān)利地址、主體等相關(guān)變化,請(qǐng)及時(shí)變更,防止失效 |
權(quán)利人 | 北京大學(xué) | 當(dāng)前權(quán)利人 | 北京大學(xué) |
發(fā)明人 | 張建宇;姚嘉;劉曉舟;廖唯棨;鄒維 |
代理機(jī)構(gòu) | 北京君尚知識(shí)產(chǎn)權(quán)代理事務(wù)所(普通合伙) | 代理人 | 余長(zhǎng)江 |
摘要
本發(fā)明的目的在于提供一種TCP數(shù)據(jù)包的傳輸方法,該方法通過(guò)將非本地TCP數(shù)據(jù)包直接重定向到本地網(wǎng)絡(luò)協(xié)議棧進(jìn)行處理(不依賴(lài)于網(wǎng)絡(luò)地址轉(zhuǎn)換技術(shù))、流套接字負(fù)載均衡、減少內(nèi)核層和用戶層之間的數(shù)據(jù)拷貝傳遞、在內(nèi)核層的流套接字之間直接傳遞TCP數(shù)據(jù)包以及減少網(wǎng)絡(luò)協(xié)議棧中執(zhí)行數(shù)據(jù)包構(gòu)建等復(fù)雜操作的開(kāi)銷(xiāo),提高了內(nèi)核層內(nèi)部各模塊間傳輸和處理TCP數(shù)據(jù)包以及內(nèi)核層與用戶層業(yè)務(wù)程序之間傳輸數(shù)據(jù)的效率,實(shí)現(xiàn)了應(yīng)用網(wǎng)關(guān)對(duì)TCP流量應(yīng)用層數(shù)據(jù)的在線高速處理、TCP數(shù)據(jù)包的快速轉(zhuǎn)發(fā)以及對(duì)大量并發(fā)TCP會(huì)話的支持,并保證了應(yīng)用網(wǎng)關(guān)對(duì)于通信源端和目的端的透明性。
1.一種TCP數(shù)據(jù)包的傳輸方法,其步驟如下:
1)將應(yīng)用網(wǎng)關(guān)接收到的、目的IP地址為非本地IP地址的TCP數(shù)據(jù)包傳輸?shù)絻?nèi)核層的數(shù)據(jù)包轉(zhuǎn)發(fā)模塊,數(shù)據(jù)包轉(zhuǎn)發(fā)模塊將數(shù)據(jù)包內(nèi)核數(shù)據(jù)結(jié)構(gòu)的bsepsocket字段置1;
2)數(shù)據(jù)包轉(zhuǎn)發(fā)模塊根據(jù)負(fù)載均衡算法從用戶層業(yè)務(wù)程序創(chuàng)建的“監(jiān)聽(tīng)”流套接字池中選出一個(gè)“監(jiān)聽(tīng)”流套接字,將其本地監(jiān)聽(tīng)端口保存到數(shù)據(jù)包的內(nèi)核數(shù)據(jù)結(jié)構(gòu)中;
3)所述“監(jiān)聽(tīng)”流套接字響應(yīng)新建TCP連接握手請(qǐng)求,并創(chuàng)建“數(shù)據(jù)”流套接字,所述“監(jiān)聽(tīng)”流套接字和“數(shù)據(jù)”流套接字包含三個(gè)數(shù)據(jù)包緩沖隊(duì)列:接收隊(duì)列、發(fā)送隊(duì)列和深度處理隊(duì)列;“監(jiān)聽(tīng)”流套接字還包含一個(gè)監(jiān)聽(tīng)隊(duì)列和一個(gè)新建TCP連接隊(duì)列;
4)數(shù)據(jù)包轉(zhuǎn)發(fā)模塊將TCP數(shù)據(jù)包重定向到內(nèi)核層的本地網(wǎng)絡(luò)協(xié)議棧;
5)本地網(wǎng)絡(luò)協(xié)議棧的TCP輸入處理模塊對(duì)TCP數(shù)據(jù)包的TCP包頭進(jìn)行解析處理,在“數(shù)據(jù)”流套接字散列表中查找是否存在與數(shù)據(jù)包對(duì)應(yīng)的“數(shù)據(jù)”流套接字;
6)若存在“數(shù)據(jù)”流套接字,則將數(shù)據(jù)包加入到“數(shù)據(jù)”流套接字的接收隊(duì)列的隊(duì)尾,并跳到步驟9;
7)若不存在“數(shù)據(jù)”流套接字,則在“監(jiān)聽(tīng)”流套接字散列表中找到數(shù)據(jù)包轉(zhuǎn)發(fā)模塊選出的“監(jiān)聽(tīng)”流套接字,將數(shù)據(jù)包加入到“監(jiān)聽(tīng)”流套接字的監(jiān)聽(tīng)隊(duì)列的隊(duì)尾;
8)TCP新建連接模塊從監(jiān)聽(tīng)隊(duì)列隊(duì)首取出TCP數(shù)據(jù)包,完成與客戶機(jī)的新建TCP連接握手,創(chuàng)建與客戶機(jī)進(jìn)行通信的“數(shù)據(jù)”流套接字,將該流套接字加入到內(nèi)核中的“數(shù)據(jù)”流套接字散列表以及“監(jiān)聽(tīng)”流套接字的新建TCP連接隊(duì)列隊(duì)尾;
9)用戶層的業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)accept(),從“監(jiān)聽(tīng)”流套接字的新建TCP連接隊(duì)列隊(duì)首取出“數(shù)據(jù)”流套接字并返回其信息給業(yè)務(wù)程序;調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)socket(),創(chuàng)建與服務(wù)器通信的“數(shù)據(jù)”流套接字,調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)setsockopt(),將其內(nèi)核數(shù)據(jù)結(jié)構(gòu)的sk_sepsocket字段置1;調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)connect(),建立應(yīng)用網(wǎng)關(guān)與服務(wù)器間的TCP連接;
10)業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù),所述的系統(tǒng)調(diào)用函數(shù)為recv()、recvmsg()或recvfrom(),觸發(fā)TCP輸入處理模塊從“數(shù)據(jù)”流套接字的接收隊(duì)列的隊(duì)首取出TCP數(shù)據(jù)包,還原提取出應(yīng)用層數(shù)據(jù)并拷貝到業(yè)務(wù)程序提供的用戶層緩沖區(qū)中,如果所述recv()、recvmsg()或recvfrom()函數(shù)的參數(shù)flags中包含標(biāo)識(shí)MSG_PREINSPECTING,則將數(shù)據(jù)包加入到“數(shù)據(jù)”流套接字的深度處理隊(duì)列隊(duì)尾;
11)業(yè)務(wù)程序解析處理用戶層緩沖區(qū)中的數(shù)據(jù),調(diào)用套接字的系統(tǒng)調(diào)用函數(shù),所述的系統(tǒng)調(diào)用函數(shù)為transfer()、send()、sendmsg()或sendto(),并根據(jù)所述transfer()、send()、sendmsg()或sendto()函數(shù)的參數(shù)flags中設(shè)置的不同標(biāo)識(shí),執(zhí)行對(duì)“數(shù)據(jù)”流套接字深度處理隊(duì)列中的原始TCP數(shù)據(jù)包的處理操作,包括:丟棄;對(duì)TCP數(shù)據(jù)包的內(nèi)容不做任何修改原樣發(fā)送出去;采用業(yè)務(wù)程序提供的數(shù)據(jù)替換TCP數(shù)據(jù)包的內(nèi)容后發(fā)送出去;其中上述步驟中所有系統(tǒng)調(diào)用函數(shù)均兼容伯克利套接字。
2.如權(quán)利要求1所述的一種TCP數(shù)據(jù)包的傳輸方法,其特征在于步驟2)中所述的“監(jiān)聽(tīng)”流套接字池的創(chuàng)建方法如下:
1)用戶層的業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)socket(),創(chuàng)建一個(gè)流套接字;
2)業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)bind(),設(shè)置流套接字的本地監(jiān)聽(tīng)端口;
3)業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)listen(),將流套接字設(shè)置為“監(jiān)聽(tīng)”流套接字,并以本地監(jiān)聽(tīng)端口為鍵值將其加入內(nèi)核中的“監(jiān)聽(tīng)”流套接字散列表;
4)業(yè)務(wù)程序創(chuàng)建多個(gè)“監(jiān)聽(tīng)”流套接字,形成一個(gè)“監(jiān)聽(tīng)”流套接字池。
3.如權(quán)利要求1所述的一種TCP數(shù)據(jù)包的傳輸方法,其特征在于步驟2)中所述的負(fù)載均衡算法采用對(duì)源IP地址、源端口、目的IP地址和目的端口進(jìn)行哈希的方法。
4.如權(quán)利要求1所述的一種TCP數(shù)據(jù)包的傳輸方法,其特征在于步驟5)中,TCP輸入處理模塊根據(jù)數(shù)據(jù)包的目的IP地址、目的端口、源IP地址和源端口信息查找是否存在對(duì)應(yīng)的“數(shù)據(jù)”流套接字。
5.如權(quán)利要求1所述的一種TCP數(shù)據(jù)包的傳輸方法,其特征在于步驟7)中在TCP輸入處理模塊根據(jù)數(shù)據(jù)包內(nèi)核數(shù)據(jù)結(jié)構(gòu)中保存的“監(jiān)聽(tīng)”流套接字的本地監(jiān)聽(tīng)端口信息,找到數(shù)據(jù)包轉(zhuǎn)發(fā)模塊選出的“監(jiān)聽(tīng)”流套接字。
6.如權(quán)利要求1所述的一種TCP數(shù)據(jù)包的傳輸方法,其特征在于步驟9)中所述信息包括目的IP地址、目的端口、源IP地址和源端口。
7.如權(quán)利要求1所述的一種TCP數(shù)據(jù)包的傳輸方法,其特征在于步驟11)所述的執(zhí)行對(duì)“數(shù)據(jù)”流套接字深度處理隊(duì)列中原始TCP數(shù)據(jù)包的丟棄操作的處理步驟為:用戶層的業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)send()、sendmsg()或sendto(),所述send()、sendmsg()或sendto()函數(shù)的參數(shù)flags置為MSG_POSTINSPECTING和MSG_DROP,將“數(shù)據(jù)”流套接字的深度處理隊(duì)列中當(dāng)前所有原始TCP數(shù)據(jù)包全部移出并丟棄。
8.如權(quán)利要求1所述的一種TCP數(shù)據(jù)包的傳輸方法,其特征在于步驟11)所述的執(zhí)行對(duì)“數(shù)據(jù)”流套接字深度處理隊(duì)列中原始TCP數(shù)據(jù)包內(nèi)容的發(fā)送操作的處理步驟為:
1)用戶層的業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)transfer(),調(diào)用函數(shù)均兼容伯克利套接字;
2)transfer()將“數(shù)據(jù)”流套接字的深度處理隊(duì)列中當(dāng)前所有原始TCP數(shù)據(jù)包全部移出;
3)如果transfer()函數(shù)的參數(shù)flags中包含MSG_POSTINSPECTING標(biāo)識(shí),但不包含MSG_REPLACE標(biāo)識(shí),則將上述原始TCP數(shù)據(jù)包去掉TCP包頭后加入要發(fā)送TCP數(shù)據(jù)包的流套接字dsocket的發(fā)送隊(duì)列隊(duì)尾,經(jīng)本地網(wǎng)絡(luò)協(xié)議棧和數(shù)據(jù)包轉(zhuǎn)發(fā)模塊執(zhí)行完協(xié)議封裝、TCP狀態(tài)機(jī)維護(hù)、數(shù)據(jù)鏈路層或網(wǎng)絡(luò)層轉(zhuǎn)發(fā)信息查找這些處理工作后,將其發(fā)送出去;
4)如果flags中同時(shí)包含MSG_POSTINSPECTING標(biāo)識(shí)和MSG_REPLACE標(biāo)識(shí),則將業(yè)務(wù)程序提供的應(yīng)用層數(shù)據(jù)從用戶層拷貝到內(nèi)核層,然后復(fù)用上述原始TCP數(shù)據(jù)包,去掉其TCP包頭并用應(yīng)用層數(shù)據(jù)替換數(shù)據(jù)包的內(nèi)容,如果數(shù)據(jù)的長(zhǎng)度超過(guò)原始TCP數(shù)據(jù)包內(nèi)容的總長(zhǎng)度,則拷貝新的TCP數(shù)據(jù)包來(lái)放置超長(zhǎng)部分的數(shù)據(jù),將數(shù)據(jù)包加入要發(fā)送TCP數(shù)據(jù)包的流套接字dsocket的發(fā)送隊(duì)列隊(duì)尾,經(jīng)本地網(wǎng)絡(luò)協(xié)議棧和數(shù)據(jù)包轉(zhuǎn)發(fā)模塊發(fā)送出去。
一種TCP數(shù)據(jù)包的傳輸方法 \n技術(shù)領(lǐng)域\n[0001] 本發(fā)明屬于計(jì)算機(jī)網(wǎng)絡(luò)和數(shù)據(jù)通信技術(shù)領(lǐng)域,涉及一種TCP(Transmission ControlProtocol)數(shù)據(jù)包的傳輸方法,可用于應(yīng)用網(wǎng)關(guān)的設(shè)備和軟件中,以提高網(wǎng)關(guān)傳輸TCP數(shù)據(jù)包以及處理其應(yīng)用層數(shù)據(jù)的效率,減少系統(tǒng)開(kāi)銷(xiāo)和網(wǎng)絡(luò)延遲。 \n背景技術(shù)\n[0002] 應(yīng)用網(wǎng)關(guān)通常采用透明代理技術(shù),在客戶機(jī)和服務(wù)器之間充當(dāng)中間人的角色,接收流經(jīng)的TCP數(shù)據(jù)包并重定向到內(nèi)核層的本地網(wǎng)絡(luò)協(xié)議棧中,由協(xié)議棧對(duì)數(shù)據(jù)包進(jìn)行協(xié)議解析處理和TCP流重組,還原提取出應(yīng)用層數(shù)據(jù),然后通過(guò)流套接字(Stream Socket)將應(yīng)用層數(shù)據(jù)從內(nèi)核層拷貝到用戶層,傳送給用戶層的業(yè)務(wù)程序(如病毒檢測(cè)程序、關(guān)鍵詞過(guò)濾程序等)進(jìn)行各種處理和修改(如刪除、替換);用戶層業(yè)務(wù)程序?qū)⑻幚硇薷暮蟮臄?shù)據(jù)再通過(guò)流套接字從用戶層拷貝到內(nèi)核層,交給本地網(wǎng)絡(luò)協(xié)議棧,并通知協(xié)議棧采用重定向前原始數(shù)據(jù)包的目的IP地址和目的端口來(lái)重新構(gòu)建數(shù)據(jù)包并進(jìn)行協(xié)議封裝,然后發(fā)送出去。\n其中,流量重定向多采用網(wǎng)絡(luò)地址轉(zhuǎn)換技術(shù)(Network Address Translation,簡(jiǎn)稱(chēng)NAT),這主要是由于傳統(tǒng)的套接字實(shí)現(xiàn)(如伯克利套接字,參見(jiàn)文獻(xiàn):W.R.Stevens,B.Fenner andA.M.Rodoff,“UNIX Network Programming,Volume 1:The Sockets Networking API”,Addison Wesley,2003;IEEE Std 1003.1)和網(wǎng)絡(luò)協(xié)議棧的實(shí)現(xiàn)不能接收和處理非本地目的IP地址和目的端口的數(shù)據(jù)包,也不能發(fā)送非本地源IP地址和源端口的數(shù)據(jù)包。因此,應(yīng)用網(wǎng)關(guān)對(duì)接收到的數(shù)據(jù)包要進(jìn)行目的地址轉(zhuǎn)換(DNAT),將其目的IP地址和目的端口改為網(wǎng)關(guān)的本地IP地址和本地端口,從而將其重定向到應(yīng)用網(wǎng)關(guān)的本地網(wǎng)絡(luò)協(xié)議棧中;對(duì)于待發(fā)送的數(shù)據(jù)包則要進(jìn)行源地址轉(zhuǎn)換(SNAT),將其源IP地址和源端口從網(wǎng)關(guān)的本地IP地址和本地端口改為DNAT前原始數(shù)據(jù)包的源IP地址和源端口。為了區(qū)分屬于不同TCP連接的數(shù)據(jù)包,需要對(duì)TCP流量進(jìn)行連接跟蹤并在連接表中記錄NAT操作前后的IP地址和端口信息。 \n[0003] 上述技術(shù)存在如下幾個(gè)主要缺陷,造成應(yīng)用網(wǎng)關(guān)處理效率和容量的大幅下降,無(wú)法滿足在高流量帶寬以及存在大量并發(fā)會(huì)話的網(wǎng)絡(luò)環(huán)境中的性能需求:(1)NAT技術(shù)對(duì)每一個(gè)數(shù)據(jù)包的IP地址和端口字段進(jìn)行修改并需重新計(jì)算校驗(yàn)和,對(duì)系統(tǒng)性能造成一定影響; (2)NAT技術(shù)依賴(lài)于連接跟蹤,需要建立會(huì)話表,為每一個(gè)TCP會(huì)話保存IP地址、端口等信息,而會(huì)話跟蹤和會(huì)話表管理任務(wù)的時(shí)空間開(kāi)銷(xiāo)繁重,會(huì)嚴(yán)重影響系統(tǒng)的性能;(3)為了保持NAT轉(zhuǎn)換前后TCP連接的一一對(duì)應(yīng)關(guān)系,在執(zhí)行DNAT操作時(shí)需要將不同的TCP連接的數(shù)據(jù)包目的端口轉(zhuǎn)換為不同的本地端口,因而系統(tǒng)能夠支持的最大并發(fā)連接數(shù)受限于可用的本地端口數(shù)目(不多于65535個(gè));(4)數(shù)據(jù)在內(nèi)核層和用戶層之間多次拷貝傳遞,以及在發(fā)送數(shù)據(jù)時(shí)需要重新進(jìn)行數(shù)據(jù)包構(gòu)建等操作,也會(huì)嚴(yán)重降低系統(tǒng)性能。 發(fā)明內(nèi)容\n[0004] 本發(fā)明的目的在于提供一種TCP數(shù)據(jù)包傳輸方法,通過(guò)將非本地TCP數(shù)據(jù)包直接重定向到本地網(wǎng)絡(luò)協(xié)議棧進(jìn)行處理(不依賴(lài)于網(wǎng)絡(luò)地址轉(zhuǎn)換技術(shù))、流套接字負(fù)載均衡、減少內(nèi)核層和用戶層之間的數(shù)據(jù)拷貝傳遞、在內(nèi)核層的流套接字之間直接傳遞TCP數(shù)據(jù)包以及減少網(wǎng)絡(luò)協(xié)議棧中執(zhí)行數(shù)據(jù)包構(gòu)建等復(fù)雜操作的開(kāi)銷(xiāo),提高了內(nèi)核層內(nèi)部各模塊間傳輸和處理TCP數(shù)據(jù)包以及內(nèi)核層與用戶層業(yè)務(wù)程序之間傳輸數(shù)據(jù)的效率。 \n[0005] 本發(fā)明的上述發(fā)明目的是通過(guò)如下的技術(shù)方案實(shí)現(xiàn):一種TCP數(shù)據(jù)包的傳輸方法,其步驟如下: \n[0006] 1.將應(yīng)用網(wǎng)關(guān)接收到的、目的IP地址為非本地IP地址的TCP數(shù)據(jù)包傳輸?shù)絻?nèi)核層的數(shù)據(jù)包轉(zhuǎn)發(fā)模塊,數(shù)據(jù)包轉(zhuǎn)發(fā)模塊將數(shù)據(jù)包內(nèi)核數(shù)據(jù)結(jié)構(gòu)的bsepsocke字段置1; [0007] 2.數(shù)據(jù)包轉(zhuǎn)發(fā)模塊根據(jù)負(fù)載均衡算法從用戶層業(yè)務(wù)程序創(chuàng)建的“監(jiān)聽(tīng)”流套接字池中選出一個(gè)“監(jiān)聽(tīng)”流套接字,將其本地監(jiān)聽(tīng)端口保存到數(shù)據(jù)包的內(nèi)核數(shù)據(jù)結(jié)構(gòu)中; [0008] 3.所述“監(jiān)聽(tīng)”流套接字響應(yīng)新建TCP連接握手請(qǐng)求,并創(chuàng)建“數(shù)據(jù)”流套接字,所述“監(jiān)聽(tīng)”流套接字和“數(shù)據(jù)”流套接字包含三個(gè)數(shù)據(jù)包緩沖隊(duì)列:接收隊(duì)列、發(fā)送隊(duì)列和深度處理隊(duì)列;“監(jiān)聽(tīng)”流套接字還包含一個(gè)監(jiān)聽(tīng)隊(duì)列和一個(gè)新建TCP連接隊(duì)列; [0009] 4.數(shù)據(jù)包轉(zhuǎn)發(fā)模塊將TCP數(shù)據(jù)包重定向到內(nèi)核層的本地網(wǎng)絡(luò)協(xié)議棧; [0010] 5.本地網(wǎng)絡(luò)協(xié)議棧的TCP輸入處理模塊對(duì)TCP數(shù)據(jù)包的TCP包頭進(jìn)行解析處理,在“數(shù)據(jù)”流套接字散列表中查找是否存在與數(shù)據(jù)包對(duì)應(yīng)的“數(shù)據(jù)”流套接字; [0011] 6.若存在“數(shù)據(jù)”流套接字,則將數(shù)據(jù)包加入到“數(shù)據(jù)”流套接字的接收隊(duì)列的隊(duì)尾,跳到步驟9; \n[0012] 7.若不存在“數(shù)據(jù)”流套接字,則在“監(jiān)聽(tīng)”流套接字散列表中找到數(shù)據(jù)包轉(zhuǎn)發(fā)模塊選出的“監(jiān)聽(tīng)”流套接字,將數(shù)據(jù)包加入到“監(jiān)聽(tīng)”流套接字的監(jiān)聽(tīng)隊(duì)列的隊(duì)尾; [0013] 8.TCP新建連接模塊從監(jiān)聽(tīng)隊(duì)列隊(duì)首取出TCP數(shù)據(jù)包,完成與客戶機(jī)的新建TCP連接握手,創(chuàng)建與客戶機(jī)進(jìn)行通信的“數(shù)據(jù)”流套接字,將該流套接字加入到內(nèi)核中的“數(shù)據(jù)”流套接字散列表以及“監(jiān)聽(tīng)”流套接字的新建TCP連接隊(duì)列隊(duì)尾; \n[0014] 9.用戶層的業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)accept(),從“監(jiān)聽(tīng)”流套接字的新建TCP連接隊(duì)列隊(duì)首取出“數(shù)據(jù)”流套接字并返回其信息給業(yè)務(wù)程序;調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)socket(),創(chuàng)建與服務(wù)器通信的“數(shù)據(jù)”流套接字,調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)setsockopt(),將其內(nèi)核數(shù)據(jù)結(jié)構(gòu)的sk_sepsocket字段置1;調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)connect(),建立應(yīng)用網(wǎng)關(guān)與服務(wù)器間的TCP連接; \n[0015] 10.業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù),所述的系統(tǒng)調(diào)用函數(shù)為recv()、recvmsg()或recvfrom(),觸發(fā)TCP輸入處理模塊從“數(shù)據(jù)”流套接字的接收隊(duì)列的隊(duì)首取出TCP數(shù)據(jù)包,還原提取出應(yīng)用層數(shù)據(jù)并拷貝到業(yè)務(wù)程序提供的用戶層緩沖區(qū)中,如果所述recv()、recvmsg()或recvfrom()函數(shù)的參數(shù)flags中包含標(biāo)識(shí)MSG_PREINSPECTING,則將數(shù)據(jù)包加入到“數(shù)據(jù)”流套接字的深度處理隊(duì)列隊(duì)尾; \n[0016] 11.業(yè)務(wù)程序解析處理用戶層緩沖區(qū)中的數(shù)據(jù),調(diào)用套接字的系統(tǒng)調(diào)用函數(shù),所述的系統(tǒng)調(diào)用函數(shù)為transfer()、send()、sendmsg()或sendto(),并根據(jù)所述transfer()、send()、sendmsg()或sendto()函數(shù)的參數(shù)flags中設(shè)置的不同標(biāo)識(shí),執(zhí)行對(duì)“數(shù)據(jù)”流套接字深度處理隊(duì)列中的原始TCP數(shù)據(jù)包的處理操作,包括:丟棄;對(duì)TCP數(shù)據(jù)包的內(nèi)容不做任何修改原樣發(fā)送出去;采用業(yè)務(wù)程序提供的數(shù)據(jù)替換TCP數(shù)據(jù)包的內(nèi)容后發(fā)送出去;其中上述步驟中所有系統(tǒng)調(diào)用函數(shù)均兼容伯克利套接字。 \n[0017] 進(jìn)一步,步驟2中所述的用戶層的業(yè)務(wù)程序創(chuàng)建“監(jiān)聽(tīng)”流套接字池的步驟為: [0018] 1)用戶層的業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)socket(),創(chuàng)建一個(gè)流套接字; [0019] 2)業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)bind(),設(shè)置流套接字的本地監(jiān)聽(tīng)端口; [0020] 3)業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)listen(),將流套接字設(shè)置為“監(jiān)聽(tīng)”流套接字,并以本地監(jiān)聽(tīng)端口為鍵值將其加入內(nèi)核中的“監(jiān)聽(tīng)”流套接字散列表; [0021] 4)業(yè)務(wù)程序創(chuàng)建多個(gè)“監(jiān)聽(tīng)”流套接字,形成一個(gè)“監(jiān)聽(tīng)”流套接字池。 [0022] 上述步驟2中,負(fù)載均衡算法采用對(duì)源IP地址、源端口、目的IP地址和目的端口進(jìn)行哈希的方法。 \n[0023] 上述步驟5中,TCP輸入處理模塊根據(jù)數(shù)據(jù)包的目的IP地址、目的端口、源IP地址和源端口信息查找是否存在對(duì)應(yīng)的“數(shù)據(jù)”流套接字。 \n[0024] 上述步驟7中,TCP輸入處理模塊根據(jù)數(shù)據(jù)包內(nèi)核數(shù)據(jù)結(jié)構(gòu)中保存的“監(jiān)聽(tīng)”流套接 字的本地監(jiān)聽(tīng)端口信息,找到數(shù)據(jù)包轉(zhuǎn)發(fā)模塊選出的“監(jiān)聽(tīng)”流套接字。 [0025] 上述步驟9中所述信息包括客戶機(jī)的IP地址和端口、服務(wù)器的IP地址和端口。 [0026] 上述步驟10中,所述的系統(tǒng)調(diào)用函數(shù)為recv()、recvmsg()或recvfrom()。 [0027] 進(jìn)一步,上述步驟11中所述的執(zhí)行對(duì)“數(shù)據(jù)”流套接字深度處理隊(duì)列中原始TCP數(shù)據(jù)包的丟棄操作的處理步驟為:用戶層的業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)send()、sendmsg()或sendto(),函數(shù)參數(shù)flags置為MSG_POSTINSPECTING和MSG_DROP,將流套接字的深度處理隊(duì)列中當(dāng)前所有原始TCP數(shù)據(jù)包全部移出并丟棄;所述函數(shù)均兼容伯克利套接字。 \n[0028] 進(jìn)一步,上述步驟11中所述的執(zhí)行對(duì)“數(shù)據(jù)”流套接字深度處理隊(duì)列中原始TCP數(shù)據(jù)包內(nèi)容的發(fā)送操作的處理步驟為: \n[0029] 1)用戶層的業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)transfer(),其函數(shù)定義如下: [0030] int transfer(int ssocket,int dsocket,void*buf,int len,int flags); [0031] 其中,參數(shù)ssocket為原始TCP數(shù)據(jù)包所在的套接字,dsocket為要發(fā)送TCP數(shù)據(jù)包的套接字,buf為業(yè)務(wù)程序提供的應(yīng)用層數(shù)據(jù)緩沖區(qū)指針,len為數(shù)據(jù)緩沖區(qū)中數(shù)據(jù)的字節(jié)數(shù),flags為標(biāo)識(shí)字段。transfer()的返回值為實(shí)際上成功發(fā)送出去的應(yīng)用層數(shù)據(jù)的字節(jié)數(shù); \n[0032] 2)transfer()將流套接字ssocket的深度處理隊(duì)列中當(dāng)前所有原始TCP數(shù)據(jù)包全部移出; \n[0033] 3)如果函數(shù)參數(shù)flags中包含MSG_POSTINSPECTING標(biāo)識(shí)但不包含MSG_REPLACE標(biāo)識(shí),則將上述原始TCP數(shù)據(jù)包去掉TCP包頭后加入流套接字dsocket的發(fā)送隊(duì)列隊(duì)尾,等待經(jīng)本地網(wǎng)絡(luò)協(xié)議棧(包括TCP輸出處理模塊)和數(shù)據(jù)包轉(zhuǎn)發(fā)模塊執(zhí)行完協(xié)議封裝、TCP狀態(tài)機(jī)維護(hù)、數(shù)據(jù)鏈路層或網(wǎng)絡(luò)層轉(zhuǎn)發(fā)信息查找這些處理工作后,將其發(fā)送出去; [0034] 4)如果flags中包含MSG_POSTINSPECTING標(biāo)識(shí)和MSG_REPLACE標(biāo)識(shí),則將業(yè)務(wù)程序提供的應(yīng)用層數(shù)據(jù)從用戶層拷貝到內(nèi)核層,然后復(fù)用上述原始TCP數(shù)據(jù)包,去掉其TCP包頭并用上述應(yīng)用層數(shù)據(jù)替換數(shù)據(jù)包的內(nèi)容——如果數(shù)據(jù)的長(zhǎng)度超過(guò)這些原始TCP數(shù)據(jù)包內(nèi)容的總長(zhǎng)度,則拷貝新的TCP數(shù)據(jù)包來(lái)放置超長(zhǎng)部分的數(shù)據(jù)——然后將數(shù)據(jù)包加入流套接字dsocket的發(fā)送隊(duì)列隊(duì)尾,等待經(jīng)本地網(wǎng)絡(luò)協(xié)議棧和數(shù)據(jù)包轉(zhuǎn)發(fā)模塊發(fā)送出去。 [0035] 本發(fā)明的優(yōu)點(diǎn)和積極效果如下: \n[0036] 1.本發(fā)明通過(guò)將非本地TCP數(shù)據(jù)包直接重定向到本地網(wǎng)絡(luò)協(xié)議棧進(jìn)行處理,以及通過(guò)在內(nèi)核的流套接字間直接傳遞TCP數(shù)據(jù)包,提高了內(nèi)核層內(nèi)部各模塊間傳輸和處理TCP數(shù)據(jù)包的效率; \n[0037] 2.本發(fā)明通過(guò)設(shè)置套接字的數(shù)據(jù)包緩沖深度處理隊(duì)列,以及根據(jù)系統(tǒng)調(diào)用參數(shù)flags中設(shè)置的不同標(biāo)識(shí)對(duì)其中的原始TCP數(shù)據(jù)包執(zhí)行處理,減少了在內(nèi)核層和用戶層之間多次拷貝傳遞數(shù)據(jù)以及在網(wǎng)絡(luò)協(xié)議棧中執(zhí)行數(shù)據(jù)包構(gòu)建等復(fù)雜操作的開(kāi)銷(xiāo); [0038] 3.本發(fā)明通過(guò)上述技術(shù)手段以及數(shù)據(jù)報(bào)套接字負(fù)載均衡,實(shí)現(xiàn)了應(yīng)用網(wǎng)關(guān)對(duì)TCP流量應(yīng)用層數(shù)據(jù)的在線高速處理、TCP數(shù)據(jù)包的快速轉(zhuǎn)發(fā)以及對(duì)大量并發(fā)TCP連接的支持。 [0039] 4.本發(fā)明保證了應(yīng)用網(wǎng)關(guān)對(duì)于通信源端和目的端的透明性。 \n附圖說(shuō)明\n[0040] 圖1本發(fā)明實(shí)施例的系統(tǒng)結(jié)構(gòu)圖; \n[0041] 圖2本發(fā)明實(shí)施例的創(chuàng)建“監(jiān)聽(tīng)”流套接字的流程圖; \n[0042] 圖3本發(fā)明實(shí)施例的處理TCP數(shù)據(jù)包的流程圖。 \n具體實(shí)施方式\n[0043] 以防病毒應(yīng)用安全網(wǎng)關(guān)為例,參照附圖對(duì)本發(fā)明的一種面向應(yīng)用網(wǎng)關(guān)的TCP協(xié)議處理與流套接字實(shí)現(xiàn)方法進(jìn)行詳細(xì)說(shuō)明。 \n[0044] 圖1為該實(shí)施例的系統(tǒng)結(jié)構(gòu)圖。 \n[0045] TCP數(shù)據(jù)包的內(nèi)核數(shù)據(jù)結(jié)構(gòu)包含一個(gè)非本地?cái)?shù)據(jù)包標(biāo)識(shí)字段bsepsocket,應(yīng)用網(wǎng)關(guān)的本地網(wǎng)絡(luò)協(xié)議棧根據(jù)該字段是否置1來(lái)區(qū)分非本地?cái)?shù)據(jù)包(即目的IP地址和源IP地址均不為本地IP地址的數(shù)據(jù)包)和本地?cái)?shù)據(jù)包。 \n[0046] 數(shù)據(jù)包的內(nèi)核數(shù)據(jù)結(jié)構(gòu)包含一個(gè)該數(shù)據(jù)包所屬套接字的本地監(jiān)聽(tīng)端口字段sepsocket_listen_port,通過(guò)設(shè)置該字段,將新建TCP連接握手階段的數(shù)據(jù)包分配給業(yè)務(wù)程序創(chuàng)建的“監(jiān)聽(tīng)”流套接字進(jìn)行處理,并實(shí)現(xiàn)不同“監(jiān)聽(tīng)”流套接字間的負(fù)載均衡?!氨O(jiān)聽(tīng)”流套接字負(fù)責(zé)響應(yīng)處理新建TCP連接握手請(qǐng)求并創(chuàng)建對(duì)應(yīng)的“數(shù)據(jù)”流套接字,由“數(shù)據(jù)”流套接字負(fù)責(zé)在TCP連接建立后響應(yīng)處理該連接后續(xù)的TCP數(shù)據(jù)包。 \n[0047] 本地網(wǎng)絡(luò)協(xié)議棧中包含兩個(gè)流套接字散列表:一個(gè)是“監(jiān)聽(tīng)”流套接字散列表,用以保存所有通過(guò)套接字的系統(tǒng)調(diào)用socket()和listen()進(jìn)行創(chuàng)建和設(shè)置的“監(jiān)聽(tīng)”流套接字;另一個(gè)是“數(shù)據(jù)”流套接字散列表,用以保存所有由“監(jiān)聽(tīng)”流套接字創(chuàng)建的“數(shù)據(jù)”流套接字。通過(guò)這兩個(gè)散列表實(shí)現(xiàn)對(duì)流套接字的快速查找。 \n[0048] 套接字的內(nèi)核數(shù)據(jù)結(jié)構(gòu)包含一個(gè)標(biāo)識(shí)字段sk_sepsocket,當(dāng)該字段置1時(shí)允許流套接 字處理非本地TCP數(shù)據(jù)包。同時(shí)為該標(biāo)識(shí)字段增加一個(gè)對(duì)應(yīng)的SOL_SOCKET級(jí)別的套接字選項(xiàng)SO_SEPSOCKET,使得業(yè)務(wù)程序可以通過(guò)套接字的系統(tǒng)調(diào)用setsockopt()對(duì)該標(biāo)識(shí)字段進(jìn)行設(shè)置。 \n[0049] 套接字的內(nèi)核數(shù)據(jù)結(jié)構(gòu)包含如下四個(gè)字段:源IP地址、源端口、目的IP地址、目的端口,用于保存通信雙方的IP地址和端口信息。 \n[0050] 每個(gè)流套接字包含三個(gè)數(shù)據(jù)包緩沖隊(duì)列:接收隊(duì)列sk_receive_queue、發(fā)送隊(duì)列sk_write_queue和深度處理隊(duì)列sk_inspect_queue,用于分別保存從本地網(wǎng)絡(luò)協(xié)議棧接收到的數(shù)據(jù)包、準(zhǔn)備通過(guò)本地網(wǎng)絡(luò)協(xié)議棧發(fā)送的數(shù)據(jù)包以及正在由業(yè)務(wù)程序進(jìn)行處理的數(shù)據(jù)包。 \n[0051] 每個(gè)“監(jiān)聽(tīng)”流套接字還包含一個(gè)數(shù)據(jù)包緩沖隊(duì)列:監(jiān)聽(tīng)隊(duì)列prequeue,用于保存“監(jiān)聽(tīng)”流套接字接收到的數(shù)據(jù)包。 \n[0052] 每個(gè)“監(jiān)聽(tīng)”流套接字包含一個(gè)新建TCP連接隊(duì)列accept_queue,保存由該“監(jiān)聽(tīng)”流套接字完成TCP握手的新建TCP連接的信息。 \n[0053] 如圖2所示,創(chuàng)建“監(jiān)聽(tīng)”流套接字的流程為: \n[0054] (1)用戶層的業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)socket(),創(chuàng)建一個(gè)流套接字。socket()與伯克利套接字兼容,其調(diào)用形式如下: \n[0055] int socketfd=socket(PF_INET,SOCK_STREAM,IPPROTO_IP); [0056] (2)業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)setsockopt(),將該流套接字的sk_sepsocket字段置1,從而允許該流套接字處理非本地TCP數(shù)據(jù)包。setsockopt()與伯克利套接字兼容,其調(diào)用形式如下: \n[0057] setsockopt(socketfd,SOL_SOCKET,SO_SEPSOCKET,1,sizeof(int)); [0058] (3)業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)bind()——與伯克利套接字兼容,設(shè)置該流套接字的本地監(jiān)聽(tīng)端口; \n[0059] (4)業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)listen()——與伯克利套接字兼容,將該流套接字設(shè)置為“監(jiān)聽(tīng)”流套接字,并將其加入“監(jiān)聽(tīng)”流套接字散列表。 [0060] 此外,業(yè)務(wù)程序通常創(chuàng)建多個(gè)“監(jiān)聽(tīng)”流套接字,形成一個(gè)“監(jiān)聽(tīng)”流套接字池,再通過(guò)并行和負(fù)載均衡將TCP新建連接的請(qǐng)求分散到不同的“監(jiān)聽(tīng)”流套接字進(jìn)行處理,以提高TCP連接的新建速率。 \n[0061] 如圖3所示,防病毒應(yīng)用安全網(wǎng)關(guān)處理TCP數(shù)據(jù)包的流程為: \n[0062] (1)對(duì)于防病毒應(yīng)用安全網(wǎng)關(guān)接收到的、目的IP地址為非本地IP地址的TCP數(shù)據(jù)包,送入內(nèi)核層的數(shù)據(jù)包轉(zhuǎn)發(fā)模塊進(jìn)行處理,根據(jù)一定的規(guī)則判斷數(shù)據(jù)包是否需要由用戶層業(yè)務(wù)程序進(jìn)行處理; \n[0063] (2)如果不需要,則將數(shù)據(jù)包直接轉(zhuǎn)發(fā)出去,結(jié)束; \n[0064] (3)如果需要,則數(shù)據(jù)包轉(zhuǎn)發(fā)模塊將數(shù)據(jù)包內(nèi)核數(shù)據(jù)結(jié)構(gòu)的bsepsocket字段置1,標(biāo)明其為非本地?cái)?shù)據(jù)包; \n[0065] (4)數(shù)據(jù)包轉(zhuǎn)發(fā)模塊根據(jù)負(fù)載均衡算法(參見(jiàn)文獻(xiàn):C.Kopparapu,“Load BalancingServers,F(xiàn)irewalls,and Caches”,Wiley,2002)從業(yè)務(wù)程序創(chuàng)建的“監(jiān)聽(tīng)”流套接字池中選出一個(gè)“監(jiān)聽(tīng)”流套接字,將該套接字的本地監(jiān)聽(tīng)端口保存到數(shù)據(jù)包內(nèi)核數(shù)據(jù)結(jié)構(gòu)的sepsocket_listen_port字段中。為了保證一個(gè)確定的TCP連接對(duì)應(yīng)到一個(gè)確定的“監(jiān)聽(tīng)”流套接字,TCP負(fù)載均衡算法可采用對(duì)源IP地址、源端口、目的IP地址和目的端口進(jìn)行哈希(Hash)的方法,如:假設(shè)“監(jiān)聽(tīng)”流套接字池中有n個(gè)套接字,則當(dāng)一個(gè)TCP的syn包到來(lái)時(shí),計(jì)算其源端口、目標(biāo)端口、源IP地址的低16位和目的IP地址的低16位之和,然后除以n取余,得到余數(shù)m,從而將該TCP syn包分配給編號(hào)為m的“監(jiān)聽(tīng)”流套接字; [0066] (5)數(shù)據(jù)包轉(zhuǎn)發(fā)模塊將TCP數(shù)據(jù)包直接重定向到內(nèi)核層的本地網(wǎng)絡(luò)協(xié)議棧; [0067] (6)本地網(wǎng)絡(luò)協(xié)議棧的TCP輸入處理模塊得到bsepsocket字段置1的TCP數(shù)據(jù)包后,對(duì)數(shù)據(jù)包的TCP包頭進(jìn)行解析處理; \n[0068] (7)TCP輸入處理模塊在“數(shù)據(jù)”流套接字散列表中查找是否存在sk_sepsocket字段置1且目的IP地址、目的端口、源IP地址和源端口與數(shù)據(jù)包的對(duì)應(yīng)字段信息一致的套接字; \n[0069] 如果存在,則將TCP數(shù)據(jù)包加入該“數(shù)據(jù)”流套接字的sk_receive_queue隊(duì)尾,等待用戶層業(yè)務(wù)程序?qū)ζ鋺?yīng)用層數(shù)據(jù)進(jìn)行防病毒檢測(cè)過(guò)濾; \n[0070] 如果不存在,則在“監(jiān)聽(tīng)”流套接字散列表中查找sk_sepsocket字段置1且本地監(jiān)聽(tīng)端口與數(shù)據(jù)包內(nèi)核數(shù)據(jù)結(jié)構(gòu)的sepsocket_listen_port字段相同的“監(jiān)聽(tīng)”流套接字。\n如果找到,則將數(shù)據(jù)包加入該“監(jiān)聽(tīng)”流套接字的prequeue隊(duì)尾;否則丟棄該TCP數(shù)據(jù)包,結(jié)束; \n[0071] TCP新建連接模塊從“監(jiān)聽(tīng)”流套接字的prequeue隊(duì)首取出一個(gè)TCP數(shù)據(jù)包,檢查T(mén)CP包頭中的syn、ack和rst字段。若TCP包頭的syn字段為1,ack字段和rst字段為0,則該數(shù)據(jù)包是TCP syn包;若TCP包頭的ack字段為1,syn字段和rst字段為0,則該數(shù) 據(jù)包是TCP ack包;若TCP包頭的ack字段為1,syn字段、rst字段和fin字段為0,則該數(shù)據(jù)包是TCP syn-ack包。對(duì)于TCP syn包,TCP新建連接模塊用該數(shù)據(jù)包的目的IP地址、源IP地址為源IP地址和目的IP地址構(gòu)建構(gòu)建一個(gè)TCP syn-ack包發(fā)送給客戶機(jī)。對(duì)于TCPack包,TCP新建連接模塊創(chuàng)建一個(gè)與客戶機(jī)進(jìn)行通信的“數(shù)據(jù)”流套接字,將該流套接字內(nèi)核數(shù)據(jù)結(jié)構(gòu)的sk_sepsocket字段置1,然后將數(shù)據(jù)包的源IP地址、源端口(即客戶機(jī)的IP地址和端口)和目的IP地址、目的端口(即服務(wù)器的IP地址和端口)信息分別填入該流套接字內(nèi)核數(shù)據(jù)結(jié)構(gòu)的目的IP地址、目的端口、源IP地址和源端口字段中。然后,將該流套接字加入到內(nèi)核中的“數(shù)據(jù)”流套接字散列表以及“監(jiān)聽(tīng)”流套接字的accept_queue隊(duì)尾; \n[0072] (8)用戶層的業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)accept()——與伯克利套接字兼容,調(diào)用形式如下: \n[0073] int csockfd=accept(socketfd,addr,addrlen); \n[0074] 其中參數(shù)socketfd為“監(jiān)聽(tīng)”流套接字。accept()從socketfd的accept_queue隊(duì)首取出一個(gè)“數(shù)據(jù)”流套接字,將其內(nèi)核數(shù)據(jù)結(jié)構(gòu)中的源IP地址、源端口(即服務(wù)器的IP地址和端口)和目的IP地址、目的端口(即客戶機(jī)的IP地址和端口)字段等信息通過(guò)參數(shù)addr返回給業(yè)務(wù)程序; \n[0075] (9)業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)socket(),創(chuàng)建一個(gè)與服務(wù)器通信的“數(shù)據(jù)”流套接字,并調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)setsockopt()將其內(nèi)核數(shù)據(jù)結(jié)構(gòu)的sk_sepsocket字段置1,從而允許其處理非本地TCP數(shù)據(jù)包; \n[0076] (10)業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)connect()——與伯克利套接字兼容,與服務(wù)器建立TCP連接。調(diào)用的形式如下: \n[0077] connect(ssockfd,addr,addrlen); \n[0078] 其中,參數(shù)addr中包含客戶機(jī)的IP地址和端口、服務(wù)器的IP地址和端口。\nconnect()將套接字內(nèi)核數(shù)據(jù)結(jié)構(gòu)中的源IP地址、源端口、目的IP地址和目的端口字段分別置為客戶機(jī)IP地址和端口、服務(wù)器IP地址和端口,觸發(fā)TCP新建連接模塊向服務(wù)器發(fā)起新建TCP連接請(qǐng)求并完成TCP連接握手過(guò)程; \n[0079] (11)業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)recv()、recvmsg()或recvfrom()——與伯克利套接字兼容,調(diào)用形式如下: \n[0080] int i=recv(socketfd,buf,len,MSG_PREINSPECTING); \n[0081] inti=recvmsg(socketfd,msg,MSG_PREINSPECTING); \n[0082] int i = recvfrom(socketfd,buf,len,MSG_PREINSPECTING,sockaddr,addrlen); \n[0083] 其中,函數(shù)參數(shù)flags置為MSG_PREINSPECTING。recv()、recvmsg()和recvfrom()觸發(fā)TCP輸入處理模塊從“數(shù)據(jù)”流套接字socketfd的sk_receive_queue隊(duì)首取出TCP數(shù)據(jù)包進(jìn)行流重組,將應(yīng)用層數(shù)據(jù)還原提取出來(lái)后拷貝到業(yè)務(wù)程序提供的用戶層緩沖區(qū)buf或msg中。執(zhí)行完上述操作后,由于函數(shù)參數(shù)flags中包含MSG_PREINSPECTING標(biāo)識(shí),則不釋放TCP數(shù)據(jù)包,而是將其加入到流套接字的sk_inspect_queue隊(duì)尾,等待業(yè)務(wù)程序的處理結(jié)果; \n[0084] (12)業(yè)務(wù)程序?qū)uf或msg中的數(shù)據(jù)進(jìn)行應(yīng)用協(xié)議解析,提取出其中的數(shù)據(jù)進(jìn)行病毒掃描檢測(cè),并針對(duì)不同的檢測(cè)結(jié)果執(zhí)行相應(yīng)的處理,包括如下幾種情況:通過(guò)檢查,數(shù)據(jù)中不含病毒,原始TCP數(shù)據(jù)包的凈荷不做修改、直接轉(zhuǎn)發(fā)出去;未通過(guò)檢查,數(shù)據(jù)中含有病毒,將原始TCP數(shù)據(jù)包丟棄;未通過(guò)檢查,數(shù)據(jù)中含有病毒,將原始TCP數(shù)據(jù)包的凈荷進(jìn)行替換后發(fā)送出去; \n[0085] (13)如果需要丟棄TCP數(shù)據(jù)包,則用戶層的業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)send()、sendmsg()或sendto()——與伯克利套接字兼容,將流套接字的sk_inspect_queue隊(duì)列中當(dāng)前所有原始TCP數(shù)據(jù)包全部移出并丟棄。調(diào)用形式如下: \n[0086] int i=send(socketfd,buf,len,MSG_POSTINSPECTING|MSG_DROP); [0087] int i=sendmsg(socketfd,msg,MSG_POSTINSPECTING|MSG_DROP); [0088] int i=sendto(socketfd,buf,len,MSG_POSTINSPECTING|MSG_DROP,sockaddr,addr_len); \n[0089] 其中,函數(shù)參數(shù)flags置為MSG_POSTINSPECTING和MSG_DROP的組合; [0090] (14)如果需要轉(zhuǎn)發(fā)TCP數(shù)據(jù)包,則用戶層的業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)transfer()執(zhí)行對(duì)流套接字深度處理隊(duì)列中原始TCP數(shù)據(jù)包的處理,即在與客戶機(jī)通信的“數(shù)據(jù)”流套接字和與服務(wù)器通信的“數(shù)據(jù)”流套接字之間傳遞并發(fā)送TCP數(shù)據(jù)包。\ntransfer()的定義如下: \n[0091] int transfer(int ssocket,int dsocket,void*buf,int len,int flags); [0092] 其中,參數(shù)ssocket為原始TCP數(shù)據(jù)包所在的套接字,dsocket為要發(fā)送TCP數(shù)據(jù)包的套接字,buf為數(shù)據(jù)緩沖區(qū)指針,len為數(shù)據(jù)緩沖區(qū)中數(shù)據(jù)的字節(jié)數(shù),flags為標(biāo)識(shí)字段。transfer()的返回值為實(shí)際上成功發(fā)送出去的應(yīng)用層數(shù)據(jù)的字節(jié)數(shù)。 [0093] transfer()執(zhí)行如下操作:1)將流套接字ssocket的sk_inspect_queue隊(duì)列中當(dāng)前所有原始TCP數(shù)據(jù)包全部移出;2)如果flags中包含MSG_POSTINSPECTING標(biāo)識(shí)但不包含MSG_REPLACE標(biāo)識(shí),則將上述原始TCP數(shù)據(jù)包去掉TCP包頭后加入流套接字dsocket的 sk_write_queue隊(duì)尾,等待經(jīng)本地網(wǎng)絡(luò)協(xié)議棧(包括TCP輸出處理模塊)和數(shù)據(jù)包轉(zhuǎn)發(fā)模塊執(zhí)行完協(xié)議封裝、TCP狀態(tài)機(jī)維護(hù)、數(shù)據(jù)鏈路層或網(wǎng)絡(luò)層轉(zhuǎn)發(fā)信息查找等處理工作后,將其發(fā)送出去;3)如果flags中包含MSG_POSTINSPECTING標(biāo)識(shí)和MSG_REPLACE標(biāo)識(shí),則將buf或msg所指向的應(yīng)用層數(shù)據(jù)從用戶層拷貝到內(nèi)核層,然后復(fù)用上述原始TCP數(shù)據(jù)包,去掉其TCP包頭并用上述應(yīng)用層數(shù)據(jù)替換數(shù)據(jù)包的內(nèi)容。如果數(shù)據(jù)的長(zhǎng)度超過(guò)這些原始TCP數(shù)據(jù)包內(nèi)容的總長(zhǎng)度,則拷貝新的TCP數(shù)據(jù)包來(lái)放置超長(zhǎng)部分的數(shù)據(jù)。最后,將這些TCP數(shù)據(jù)包內(nèi)核數(shù)據(jù)結(jié)構(gòu)的bsepsocket字段置1,然后將其加入流套接字dsocket的sk_write_queue隊(duì)尾,等待經(jīng)本地網(wǎng)絡(luò)協(xié)議棧和數(shù)據(jù)包轉(zhuǎn)發(fā)模塊發(fā)送出去。 \n[0094] 最后應(yīng)說(shuō)明的是:以上實(shí)施例僅用以說(shuō)明而非限制本發(fā)明的技術(shù)方案,盡管參照上述實(shí)施例對(duì)本發(fā)明進(jìn)行了詳細(xì)說(shuō)明,本領(lǐng)域的技術(shù)人員應(yīng)當(dāng)理解:依然可以對(duì)本發(fā)明進(jìn)行修改或者等同替換,而不脫離本發(fā)明的精神和范圍的任何修改或局部替換,其均應(yīng)涵蓋在本發(fā)明的權(quán)利要求范圍當(dāng)中。
法律信息
- 2016-03-02
未繳年費(fèi)專(zhuān)利權(quán)終止
IPC(主分類(lèi)): H04L 12/56
專(zhuān)利號(hào): ZL 200810055730.6
申請(qǐng)日: 2008.01.08
授權(quán)公告日: 2011.05.04
- 2011-05-04
- 2008-09-03
實(shí)質(zhì)審查的生效
實(shí)質(zhì)審查的生效
- 2008-07-09
引用專(zhuān)利(該專(zhuān)利引用了哪些專(zhuān)利)
序號(hào) | 公開(kāi)(公告)號(hào) | 公開(kāi)(公告)日 | 申請(qǐng)日 | 專(zhuān)利名稱(chēng) | 申請(qǐng)人 |
1
| |
2004-07-14
|
2002-12-31
| | |
2
| |
2007-06-20
|
2006-11-15
| | |
3
| |
2005-04-06
|
2004-10-29
| | |
被引用專(zhuān)利(該專(zhuān)利被哪些專(zhuān)利引用)
序號(hào) | 公開(kāi)(公告)號(hào) | 公開(kāi)(公告)日 | 申請(qǐng)日 | 專(zhuān)利名稱(chēng) | 申請(qǐng)人 | 該專(zhuān)利沒(méi)有被任何外部專(zhuān)利所引用! |