專利名稱:一種udp數(shù)據(jù)包的傳輸方法
技術(shù)領(lǐng)域:
本發(fā)明屬于計算機網(wǎng)絡(luò)和數(shù)據(jù)通信技術(shù)領(lǐng)域,涉及一種UDP (User Datagram Protocol) 數(shù)據(jù)包的傳輸方法,可用于應(yīng)用網(wǎng)關(guān)的設(shè)備和軟件中,以提高網(wǎng)關(guān)傳輸UDP數(shù)據(jù)包以及 處理其應(yīng)用層數(shù)據(jù)的效率,減少系統(tǒng)開銷和網(wǎng)絡(luò)延遲。
背景技術(shù):
應(yīng)用網(wǎng)關(guān)通常采用透明代理技術(shù),在客戶機和服務(wù)器之間充當(dāng)中間人的角色,接收流 經(jīng)的UDP數(shù)據(jù)包并重定向到內(nèi)核層的本地網(wǎng)絡(luò)協(xié)議棧中,由協(xié)議棧對數(shù)據(jù)包進行協(xié)議解 析處理,還原提取出應(yīng)用層數(shù)據(jù),然后通過數(shù)據(jù)報套接字(Datagram Socket)將應(yīng)用層數(shù) 據(jù)從內(nèi)核層拷貝到用戶層,傳送給用戶層的業(yè)務(wù)程序(如病毒檢測程序、關(guān)鍵詞過濾程序 等)進行各種處理和修改(如刪除、替換);用戶層業(yè)務(wù)程序?qū)⑻幚硇薷暮蟮臄?shù)據(jù)再通過 數(shù)據(jù)報套接字從用戶層拷貝到內(nèi)核層,交給本地網(wǎng)絡(luò)協(xié)議棧,并通知協(xié)議棧采用重定向前 原始數(shù)據(jù)包的目的IP地址和目的端口來重新構(gòu)建數(shù)據(jù)包并進行協(xié)議封裝,然后發(fā)送出去。 其中,流量重定向多采用網(wǎng)絡(luò)地址轉(zhuǎn)換技術(shù)(Network Address Translation,簡稱NAT), 這主要是由于傳統(tǒng)的套接字(如伯克利套接字,參見文獻W.R. Stevens, B.Fenner and A.M. Rodoff, "UNIX Network Programming, Volume 1: The Sockets Networking API" , Addison Wesley, 2003; IEEE Std 1003.1)和網(wǎng)絡(luò)協(xié)議棧的實現(xiàn)不能接收和處理非本地目的IP地址 和目的端口的數(shù)據(jù)包,也不能發(fā)送非本地源IP地址和源端口的數(shù)據(jù)包。因此,應(yīng)用網(wǎng)關(guān)對 接收到的數(shù)據(jù)包要進行目的地址轉(zhuǎn)換(DNAT),將其目的IP地址和目的端口改為網(wǎng)關(guān)的 本地IP地址和本地端口,從而將其重定向傳輸?shù)綉?yīng)用網(wǎng)關(guān)的本地網(wǎng)絡(luò)協(xié)議棧中;對于待發(fā) 送的數(shù)據(jù)包則要進行源地址轉(zhuǎn)換(SNAT),將其源IP地址和源端口從網(wǎng)關(guān)的本地IP地址 和本地端口改為DNAT前原始數(shù)據(jù)包的源IP地址和源端口。為了區(qū)分不同會話的數(shù)據(jù)包, 需要對會話進行跟蹤并在會話表中記錄NAT操作前后的IP地址和端口信息。上述技術(shù)存在如下幾個主要缺陷,造成應(yīng)用網(wǎng)關(guān)處理效率和容量的大幅下降,無法滿 足在高流量帶寬以及存在大量并發(fā)會話的網(wǎng)絡(luò)環(huán)境中的性能需求(1) NAT技術(shù)對每一 個數(shù)據(jù)包的IP地址和端口字段進行修改并需重新計算校驗和,對系統(tǒng)性能造成一定影響; (2) NAT技術(shù)依賴于會話跟蹤,需要建立會話表,為每一個UDP會話保存IP地址、端口等信息,而會話跟蹤和會話表管理任務(wù)的時空間開銷繁重,會嚴重影響系統(tǒng)的性能;(3) 數(shù)據(jù)在內(nèi)核層和用戶層之間多次拷貝傳遞,以及在發(fā)送數(shù)據(jù)時需要重新進行數(shù)據(jù)包構(gòu)建、 協(xié)議封裝、數(shù)據(jù)鏈路層或網(wǎng)絡(luò)層轉(zhuǎn)發(fā)信息查找等操作,也會嚴重降低系統(tǒng)性能。發(fā)明內(nèi)容本發(fā)明的目的在于提供一種UDP數(shù)據(jù)包的傳輸方法,通過將非本地UDP數(shù)據(jù)包直接 重定向到本地網(wǎng)絡(luò)協(xié)議棧進行處理(不依賴于網(wǎng)絡(luò)地址轉(zhuǎn)換技術(shù))、數(shù)據(jù)報套接字負載均 衡、減少內(nèi)核層和用戶層之間的數(shù)據(jù)拷貝傳遞以及減少網(wǎng)絡(luò)協(xié)議棧中執(zhí)行數(shù)據(jù)包構(gòu)建、協(xié) 議封裝、數(shù)據(jù)鏈路層或網(wǎng)絡(luò)層轉(zhuǎn)發(fā)信息查找等復(fù)雜操作的開銷,提高了內(nèi)核層內(nèi)部各模塊 間傳輸和處理UDP數(shù)據(jù)包以及內(nèi)核層與用戶層業(yè)務(wù)程序之間傳輸數(shù)據(jù)的效率。本發(fā)明的上述發(fā)明目的是通過如下的技術(shù)方案實現(xiàn)的 一種UDP數(shù)據(jù)包的傳輸方法,其步驟如下,1. 將應(yīng)用網(wǎng)關(guān)接收到的、目的IP地址為非本地IP地址的UDP數(shù)據(jù)包傳輸?shù)絻?nèi)核層 的數(shù)據(jù)包轉(zhuǎn)發(fā)模塊;2. 數(shù)據(jù)包轉(zhuǎn)發(fā)模塊根據(jù)負載均衡算法,從用戶層業(yè)務(wù)程序創(chuàng)建的數(shù)據(jù)報套接字池中選 出一個數(shù)據(jù)報套接字,將需要由業(yè)務(wù)程序處理的UDP數(shù)據(jù)包,分配給所述數(shù)據(jù)報套接字, 所述數(shù)據(jù)報套接字包含三個數(shù)據(jù)包換從隊列接收隊列、發(fā)送隊列和深度處理隊列;3. 將上述數(shù)據(jù)報套接字的本地監(jiān)聽端口、數(shù)據(jù)包轉(zhuǎn)發(fā)模塊的發(fā)送回調(diào)函數(shù)指針以及數(shù) 據(jù)鏈路層或網(wǎng)絡(luò)層轉(zhuǎn)發(fā)的目的信息保存到數(shù)據(jù)包內(nèi)核數(shù)據(jù)結(jié)構(gòu)中;4. 數(shù)據(jù)包轉(zhuǎn)發(fā)模塊將UDP數(shù)據(jù)包重定向到內(nèi)核層的本地網(wǎng)絡(luò)協(xié)議棧的UDP輸入處理模塊;5. UDP輸入處理模塊對UDP數(shù)據(jù)包的UDP包頭進行解析處理,并根據(jù)數(shù)據(jù)包內(nèi)核數(shù) 據(jù)結(jié)構(gòu)中保存的數(shù)據(jù)報套接字本地監(jiān)聽端口信息,找到數(shù)據(jù)包轉(zhuǎn)發(fā)模塊選出的數(shù)據(jù)報套接 字,將上述數(shù)據(jù)包加入到該套接字的接收隊列的隊尾;6. 用戶層的業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù),觸發(fā)UDP輸入處理模塊從數(shù)據(jù)報 套接字的接收隊列的隊首取出UDP數(shù)據(jù)包,還原提取出應(yīng)用層數(shù)據(jù)并拷貝到業(yè)務(wù)程序提 供的用戶層緩沖區(qū)中,其中所述函數(shù)均兼容伯克利套接字;如果所述函數(shù)的參數(shù)flags中包 含標(biāo)識MSG一PREINSPECTING,則將數(shù)據(jù)包加入到數(shù)據(jù)報套接字的深度處理隊列隊尾;7. 業(yè)務(wù)程序解析處理用戶層緩沖區(qū)中的數(shù)據(jù),調(diào)用套接字的系統(tǒng)調(diào)用函數(shù),并根據(jù)所述函數(shù)的參數(shù)flags中設(shè)置的不同標(biāo)識,執(zhí)行對數(shù)據(jù)報套接字深度處理隊列中的原始UDP 數(shù)據(jù)包的不同處理操作,包括丟棄;不做任何修改直接交由數(shù)據(jù)包轉(zhuǎn)發(fā)模塊發(fā)送出去; 采用業(yè)務(wù)程序提供的新數(shù)據(jù)替換UDP數(shù)據(jù)包的內(nèi)容后再交由數(shù)據(jù)包轉(zhuǎn)發(fā)模塊發(fā)送出去, 其中所述系統(tǒng)調(diào)用函數(shù)均兼容伯克利套接字。進一步,步驟6中所述的套接字的系統(tǒng)調(diào)用函數(shù)為recv()、 recvmsg()或recvfrom()。 進一步,步驟7中所述的套接字的系統(tǒng)調(diào)用函數(shù)為send()、 sendmsg()或sendto()。 進一步,所述的根據(jù)參數(shù)flags中設(shè)置的不同標(biāo)識,執(zhí)行對數(shù)據(jù)報套接字深度處理隊列 中的原始UDP數(shù)據(jù)包的處理步驟為-O若flags中不包含MSG一POSTINSPECTING標(biāo)識,則將業(yè)務(wù)程序提供的應(yīng)用層數(shù)據(jù) 從用戶層拷貝到內(nèi)核層,UDP輸出處理模塊重新構(gòu)建UDP數(shù)據(jù)包,并將其加入到數(shù)據(jù)報 套接字發(fā)送隊列隊尾,交由本地網(wǎng)絡(luò)協(xié)議棧完成協(xié)議封裝、數(shù)據(jù)鏈路層或網(wǎng)絡(luò)層轉(zhuǎn)發(fā)信息 査找等處理后,最終通過數(shù)據(jù)包轉(zhuǎn)發(fā)模塊發(fā)送出去;2) 若flags中包含MSG—POSTINSPECTING標(biāo)識,將內(nèi)核中的原始UDP數(shù)據(jù)包從數(shù) 據(jù)報套接字的深度處理隊列中移出;3) 若flags中包含MSG—POSTINSPECTING標(biāo)識但不包含MSG_DR0P標(biāo)識和 MSG—REPLACE標(biāo)識,則從數(shù)據(jù)包內(nèi)核數(shù)據(jù)結(jié)構(gòu)中得到發(fā)送回調(diào)函數(shù)指針以及作為函數(shù)參 數(shù)的數(shù)據(jù)鏈路層或網(wǎng)絡(luò)層轉(zhuǎn)發(fā)目的信息,然后調(diào)用該發(fā)送回調(diào)函數(shù)將UDP原始數(shù)據(jù)包交 給數(shù)據(jù)包轉(zhuǎn)發(fā)模塊直接發(fā)送出去;4) 若flags中包含MSG—POSTINSPECTING標(biāo)識和MSG—DROP標(biāo)識,則將原始UDP 數(shù)據(jù)包丟棄;5) 若flags中包含MSG—POSTINSPECTING標(biāo)識和MSG—REPLACE標(biāo)識,則將業(yè)務(wù) 程序提供的應(yīng)用層數(shù)據(jù)從用戶層拷貝到內(nèi)核層,替換原始UDP數(shù)據(jù)包的內(nèi)容;如果數(shù)據(jù) 長度超過原始UDP數(shù)據(jù)包內(nèi)容的長度,則拷貝新的UDP數(shù)據(jù)包來放置超長部分的數(shù)據(jù); 重新計算UDP數(shù)據(jù)包的校驗和,然后從數(shù)據(jù)包內(nèi)核數(shù)據(jù)結(jié)構(gòu)中得到發(fā)送回調(diào)函數(shù)指針以 及作為函數(shù)參數(shù)的數(shù)據(jù)鏈路層或網(wǎng)絡(luò)層轉(zhuǎn)發(fā)目的信息,調(diào)用該發(fā)送回調(diào)函數(shù)將UDP數(shù)據(jù) 包交給數(shù)據(jù)包轉(zhuǎn)發(fā)模塊直接發(fā)送出去。進一步,步驟2中所述的用戶層的業(yè)務(wù)程序創(chuàng)建數(shù)據(jù)報套接字池的步驟為1) 用戶層的業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)socket(),創(chuàng)建一個數(shù)據(jù)報套接字;2) 業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)bind(),設(shè)置數(shù)據(jù)報套接字的本地監(jiān)聽端口;3) 將上述數(shù)據(jù)報套接字以本地監(jiān)聽端口為鍵值,加入內(nèi)核中的數(shù)據(jù)報套接字散列表;4) 業(yè)務(wù)程序創(chuàng)建多個數(shù)據(jù)報套接字,形成一個數(shù)據(jù)報套接字池。本發(fā)明的優(yōu)點和積極效果如下1. 本發(fā)明通過將非本地UDP數(shù)據(jù)包直接重定向到本地網(wǎng)絡(luò)協(xié)議棧進行處理,以及通過數(shù)據(jù)包發(fā)送回調(diào)函數(shù)直接轉(zhuǎn)發(fā)數(shù)據(jù)包,提高了內(nèi)核層內(nèi)部各模塊間傳輸和處理UDP數(shù) 據(jù)包的效率;2. 本發(fā)明通過設(shè)置套接字的數(shù)據(jù)包緩沖深度處理隊列,以及根據(jù)系統(tǒng)調(diào)用參數(shù)flags 中設(shè)置的不同標(biāo)識對其中的原始UDP數(shù)據(jù)包執(zhí)行處理,減少了在內(nèi)核層和用戶層之間多 次拷貝傳遞數(shù)據(jù)以及在網(wǎng)絡(luò)協(xié)議棧中執(zhí)行數(shù)據(jù)包構(gòu)建、協(xié)議封裝、數(shù)據(jù)鏈路層或網(wǎng)絡(luò)層轉(zhuǎn) 發(fā)信息査找等復(fù)雜操作的開銷;3. 本發(fā)明通過上述技術(shù)手段以及數(shù)據(jù)報套接字負載均衡,實現(xiàn)了應(yīng)用網(wǎng)關(guān)對UDP流 量應(yīng)用層數(shù)據(jù)的在線高速處理、UDP數(shù)據(jù)包的快速轉(zhuǎn)發(fā)以及對大量并發(fā)UDP會話的支持。4. 本發(fā)明保證了應(yīng)用網(wǎng)關(guān)對于通信源端和目的端的透明性。
圖1本發(fā)明實施例的系統(tǒng)結(jié)構(gòu)圖;圖2本發(fā)明實施例的創(chuàng)建數(shù)據(jù)報套接字的流程圖;圖3本發(fā)明實施例的處理UDP數(shù)據(jù)包的流程圖。
具體實施方式
以防病毒應(yīng)用安全網(wǎng)關(guān)為例,參照附圖對本發(fā)明的一種UDP數(shù)據(jù)包的傳輸方法進行詳細說明。圖l為該實施例的系統(tǒng)結(jié)構(gòu)圖。數(shù)據(jù)包的內(nèi)核數(shù)據(jù)結(jié)構(gòu)中包含一個非本地數(shù)據(jù)包標(biāo)識字段bsepsocket,應(yīng)用網(wǎng)關(guān)的本 地網(wǎng)絡(luò)協(xié)議棧根據(jù)該字段是否置1來區(qū)分非本地數(shù)據(jù)包(即目的IP地址和源IP地址均不 為本地IP地址的數(shù)據(jù)包)和本地數(shù)據(jù)包。數(shù)據(jù)包的內(nèi)核數(shù)據(jù)結(jié)構(gòu)中還包含一個該數(shù)據(jù)包所屬套接字的本地監(jiān)聽端口字段 sepsocket—listen_port,通過設(shè)置該字段將數(shù)據(jù)包分配給業(yè)務(wù)程序創(chuàng)建的一個數(shù)據(jù)報套接字進行處理,并實現(xiàn)不同數(shù)據(jù)報套接字間的負載均衡。數(shù)據(jù)包的內(nèi)核數(shù)據(jù)結(jié)構(gòu)中包含一個回調(diào)函數(shù)指針字段sepsocket—forward_callback_fiinc 和一個函數(shù)參數(shù)字段sepsocket—forward—callback_params,用以實現(xiàn)UDP數(shù)據(jù)包的直接發(fā) 送。應(yīng)用網(wǎng)關(guān)的本地網(wǎng)絡(luò)協(xié)議棧中包含一個數(shù)據(jù)報套接字散列表,用以保存所有通過套接 字的系統(tǒng)調(diào)用socket()創(chuàng)建的數(shù)據(jù)報套接字,并實現(xiàn)對套接字的快速査找。套接字的內(nèi)核數(shù)據(jù)結(jié)構(gòu)中包含一個標(biāo)識字段sk—sepsocket,當(dāng)該字段置1時允許數(shù)據(jù) 報套接字處理非本地UDP數(shù)據(jù)包。同時為該標(biāo)識字段增加一個對應(yīng)的SOL—SOCKET級別 的套接字選項SO_SEPSOCKET,使得業(yè)務(wù)程序可以通過套接字的系統(tǒng)調(diào)用setsockopt()對 該標(biāo)識字段進行設(shè)置。每個數(shù)據(jù)報套接字包含三個數(shù)據(jù)包緩沖隊列接收隊列sk—receiVe_qUeUe、發(fā)送隊列 sk_write—queue和深度處理隊列sk—inspect—queue,用于分別保存從本地網(wǎng)絡(luò)協(xié)議棧接收到 的數(shù)據(jù)包、準(zhǔn)備通過本地網(wǎng)絡(luò)協(xié)議棧發(fā)送的數(shù)據(jù)包和正在由業(yè)務(wù)程序進行處理的數(shù)據(jù)包。如圖2所示,用戶層的業(yè)務(wù)程序創(chuàng)建數(shù)據(jù)報套接字的流程為(1) 用戶層的業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)socket(),新建一個數(shù)據(jù)報套接字。 socket()與伯克利套接字兼容,其調(diào)用形式如下int socketfd = socket(PF—INET, SOCK—DGRAM, IPPROTO—IP);(2) 業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)setsockopt(),將該數(shù)據(jù)報套接字的 sk—sepsocket字段置1,從而允許該數(shù)據(jù)報套接字處理非本地UDP數(shù)據(jù)包。sk—sepsocket 字段對應(yīng)的套接字選項為SO—SEPSOCKET,級別為SOL_SOCKET。 setsockopt()與伯克利套接字兼容,其調(diào)用形式如下-setsockopt(socketfd, SOL—SOCKET, SO—SEPSOCKET, 1, sizeof(int));(3) 業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)bind()——與伯克利套接字兼容,設(shè)置該數(shù) 據(jù)報套接字的本地監(jiān)聽端口;(4) 系統(tǒng)調(diào)用bind()在獲得業(yè)務(wù)程序給該數(shù)據(jù)報套接字分配的本地監(jiān)聽端口后,以監(jiān) 聽端口為鍵值將該數(shù)據(jù)報套接字加入內(nèi)核的數(shù)據(jù)報套接字散列表。業(yè)務(wù)程序通常按照上述步驟創(chuàng)建多個數(shù)據(jù)報套接字,形成一個數(shù)據(jù)報套接字池,再通 過并行和負載均衡將UDP會話分散到不同的數(shù)據(jù)報套接字進行處理,以提高UDP流量的 吞吐量。如圖3所示,防病毒應(yīng)用安全網(wǎng)關(guān)處理UDP數(shù)據(jù)包的流程為(1) 對于防病毒應(yīng)用安全網(wǎng)關(guān)接收到的、目的IP地址為非本地IP地址的UDP數(shù)據(jù) 包,送入內(nèi)核層的數(shù)據(jù)包轉(zhuǎn)發(fā)模塊進行處理,査找數(shù)據(jù)鏈路層或網(wǎng)絡(luò)層轉(zhuǎn)發(fā)目的信息并根 據(jù)一定的規(guī)則判斷數(shù)據(jù)包是否需要由用戶層業(yè)務(wù)程序進行處理;(2) 如果不需要,則將數(shù)據(jù)包直接轉(zhuǎn)發(fā)出去,結(jié)束;(3) 如果需要,則數(shù)據(jù)包轉(zhuǎn)發(fā)模塊將數(shù)據(jù)包內(nèi)核數(shù)據(jù)結(jié)構(gòu)的bsepsocket字段置l,標(biāo) 明其為非本地數(shù)據(jù)包;(4) 數(shù)據(jù)包轉(zhuǎn)發(fā)模塊根據(jù)負載均衡算法(參見文獻C. Kopparapu, "Load Balancing Servers, Firewalls, and Caches", Wiley, 2002)從業(yè)務(wù)程序創(chuàng)建的數(shù)據(jù)報套接字池中選出一個 數(shù)據(jù)報套接字,將該套接字的本地監(jiān)聽端口保存到數(shù)據(jù)包內(nèi)核數(shù)據(jù)結(jié)構(gòu)的 sepsocketJistenjort字段中。負載均衡算法可釆用簡單輪詢算法(round robin)算法,艮卩 假設(shè)套接字池中有n個套接字,則當(dāng)?shù)?個UDP數(shù)據(jù)包到來時,將其分配給第1個套接 字,后續(xù)到來的數(shù)據(jù)包順序分配給第2、 3、...直到第n個套接字,然后又重新從第l個套 接字開始分配,如此循環(huán)反復(fù);(5) 數(shù)據(jù)包轉(zhuǎn)發(fā)模塊將負責(zé)后續(xù)轉(zhuǎn)發(fā)操作的函數(shù)作為數(shù)據(jù)包的發(fā)送回調(diào)函數(shù),用于 在完成對數(shù)據(jù)包的病毒檢測處理后、重新發(fā)送數(shù)據(jù)包時進行調(diào)用。數(shù)據(jù)包轉(zhuǎn)發(fā)模塊將該函 數(shù)的指針和參數(shù)(即該數(shù)據(jù)包的數(shù)據(jù)鏈路層或網(wǎng)絡(luò)層轉(zhuǎn)發(fā)目的信息)分別保存到數(shù)據(jù)包內(nèi) 核數(shù)據(jù)結(jié)構(gòu)的sepsocket—forward—callback—fUnc字段禾口 sepsocket—forward—callback_params 字段中;(6) 數(shù)據(jù)包轉(zhuǎn)發(fā)模塊將UDP數(shù)據(jù)包直接重定向到內(nèi)核層的本地網(wǎng)絡(luò)協(xié)議棧;(7) 本地網(wǎng)絡(luò)協(xié)議棧的UDP輸入處理模塊得到bsepsocket字段置1的UDP數(shù)據(jù)包后, 對數(shù)據(jù)包的UDP包頭進行解析處理;(8) UDP輸入處理模塊以數(shù)據(jù)包內(nèi)核數(shù)據(jù)結(jié)構(gòu)的sepsocketjistenjport字段為散列鍵 值,在數(shù)據(jù)報套接字散列表中找到sk—sepsocket字段置1且本地監(jiān)聽端口與 sepsocket—liSten_port字段相同的數(shù)據(jù)報套接字;(9) 將數(shù)據(jù)包加入到該數(shù)據(jù)報套接字的sk—receive—queue隊尾,等待用戶層業(yè)務(wù)程序 對其應(yīng)用層數(shù)據(jù)進行防病毒檢測過濾;(10) 用戶層的業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)recv()、 recvmsg()或recvfrom() ——與伯克利套接字兼容,調(diào)用形式如下int i = recv(socketfd, buf, len, MSG_PREINSPECTING); int i = recvmsg(socketfd, msg, MSG—PREINSPECTING); int i = recvfrom(socketfd, buf, len, MSG一PREINSPECTING, sockaddr, addrlen); 其中,函數(shù)參數(shù)flags置為MSG_PREINSPECTING;(11) 套接字的系統(tǒng)調(diào)用recv()、 recvmsg()和recvfrom()觸發(fā)UDP輸入處理模塊,從 數(shù)據(jù)報套接字socketfd的sk—receive_queue隊首取出UDP數(shù)據(jù)包,將其應(yīng)用層數(shù)據(jù)還原提 取出來后拷貝到業(yè)務(wù)程序提供的用戶層緩沖區(qū)buf或msg中;(12) 由于上述函數(shù)的參數(shù)flags中包含標(biāo)識MSG—PREINSPECTING,因此執(zhí)行完上 述操作后數(shù)據(jù)報套接字并不立即釋放UDP數(shù)據(jù)包,而是將其加入到數(shù)據(jù)報套接字的 sk_inspect_queue隊尾,等待業(yè)務(wù)程序的處理結(jié)果;(13) 業(yè)務(wù)程序?qū)uf或msg中的數(shù)據(jù)進行應(yīng)用協(xié)議解析,提取出其中的數(shù)據(jù)進行病 毒掃描檢測,并針對不同的檢測結(jié)果執(zhí)行相應(yīng)的處理,包括如下幾種情況檢查通過,數(shù) 據(jù)中不含病毒,將原始UDP數(shù)據(jù)包轉(zhuǎn)發(fā)出去;未通過檢査,數(shù)據(jù)中含有病毒,將原始UDP 數(shù)據(jù)包丟棄;未通過檢査,數(shù)據(jù)中含有病毒,將原始UDP數(shù)據(jù)包的內(nèi)容進行替換后發(fā)送 出去;(14) 用戶層的業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)send()、 sendmsg()或sendto()—— 與伯克利套接字兼容,執(zhí)行對原始UDP數(shù)據(jù)包的處理,調(diào)用形式如下int i = send(socketfd, buf, len, flags);int i = sendmsg(socketfd, msg, flags);int i = sendto(socketfd, buf, len, flags, sockaddr, addr—len); 其中,函數(shù)參數(shù)flags根據(jù)不同的處理要求進行設(shè)置如果是通過檢査、轉(zhuǎn)發(fā),則置為 MSG_POSTINSPECTING;如果未通過檢査、丟棄,則置為MSG—POSTINSPECTING和 MSG_DROP;如果是未通過檢査、替換內(nèi)容后轉(zhuǎn)發(fā),則置為MSG—POSTINSPECTING和 MSG—REPLACE;(15) 如果flags中不包含MSG—POSTINSPECTING標(biāo)識,則套接字的系統(tǒng)調(diào)用send()、 sendmsg()和sendto()將業(yè)務(wù)程序提供的緩沖區(qū)buf或msg中的應(yīng)用層數(shù)據(jù)從用戶層拷貝到 內(nèi)核層,并將其連同flags、 socketaddr等交給本地網(wǎng)絡(luò)協(xié)議棧的UDP輸出處理模塊。UDP 輸出處理模塊基于此應(yīng)用層數(shù)據(jù)重新構(gòu)建UDP數(shù)據(jù)包,并判斷套接字的skjepsocket字段 是否為l,如果是,則置數(shù)據(jù)包內(nèi)核數(shù)據(jù)結(jié)構(gòu)的bsepsocket字段為1,然后將UDP數(shù)據(jù)包 加入sk—write—queue隊尾等待發(fā)送。sk—write—queue隊列中的UDP數(shù)據(jù)包還要在本地網(wǎng)絡(luò) 協(xié)議棧中經(jīng)協(xié)議封裝、數(shù)據(jù)鏈路層或網(wǎng)絡(luò)層轉(zhuǎn)發(fā)信息查找等處理后,最后交由數(shù)據(jù)包轉(zhuǎn)發(fā)模塊發(fā)送出去。結(jié)束;(16) 如果flags中包含MSG—POSTINSPECTING標(biāo)識,則將原始UDP數(shù)據(jù)包從套接 字socketfd的skjnspect—queue隊歹!j中移出;(17) 如果flags中包含MSG—POSTINSPECTING標(biāo)識但不包含MSG—DROP標(biāo)識和 MSG_REPLACE標(biāo)識,則無需拷貝buf和msg,只需調(diào)用數(shù)據(jù)包內(nèi)核數(shù)據(jù)結(jié)構(gòu)的 sepsocket—forward—callback_fUnc字段所指向的數(shù)據(jù)包發(fā)送回調(diào)函數(shù),并以 sepsocket—forward—callback_params字段中保存的數(shù)據(jù)鏈路層或網(wǎng)絡(luò)層轉(zhuǎn)發(fā)目的信息為函數(shù) 參數(shù),將原始UDP數(shù)據(jù)包交給數(shù)據(jù)包轉(zhuǎn)發(fā)模塊直接發(fā)送出去(即無需再經(jīng)過本地網(wǎng)絡(luò)協(xié) 議棧進行協(xié)議封裝、轉(zhuǎn)發(fā)信息查找等處理)——對于sendto(),如果參數(shù)sockaddr不為空 且其中的地址信息與數(shù)據(jù)包的目的IP地址和目的端口信息不一致,則不能執(zhí)行上述直接發(fā) 送數(shù)據(jù)包的操作,而是要轉(zhuǎn)到步驟(20)進行特殊處理;(18) 如果flags中包含MSG_POSTINSPECTING標(biāo)識和MSG—DROP標(biāo)識,則將原 始UDP數(shù)據(jù)包丟棄即可。結(jié)束;(19) 如果flags中包含MSG—POSTINSPECTING標(biāo)識和MSG—REPLACE標(biāo)識,則 將buf或msg中的應(yīng)用層數(shù)據(jù)從用戶層拷貝到內(nèi)核層,用此應(yīng)用層數(shù)據(jù)替換原始UDP數(shù) 據(jù)包的內(nèi)容。如果數(shù)據(jù)的長度超過原始UDP數(shù)據(jù)包內(nèi)容的長度,則拷貝若干新的UDP數(shù) 據(jù)包來放置超長部分的數(shù)據(jù)。重新計算UDP數(shù)據(jù)包的校驗和后,調(diào)用數(shù)據(jù)包內(nèi)核數(shù)據(jù)結(jié) 構(gòu)中的sepsocket—forward—callback_func字段所指向的數(shù)據(jù)包發(fā)送回調(diào)函數(shù),并以 sepsocket—forward—callback_paramS字段中保存的數(shù)據(jù)鏈路層或網(wǎng)絡(luò)層轉(zhuǎn)發(fā)目的信息為函數(shù) 參數(shù),將UDP數(shù)據(jù)包交給數(shù)據(jù)包轉(zhuǎn)發(fā)模塊直接發(fā)送出去一一對于sendto(),如果參數(shù) sockaddr不為空且其中的地址信息與數(shù)據(jù)包的目的IP地址和目的端口信息不一致,則不能 執(zhí)行上述直接發(fā)送數(shù)據(jù)包的操作,而是要轉(zhuǎn)到步驟(20)進行特殊處理;(20) 當(dāng)sendto()的參數(shù)sockaddr不為空且其中的地址信息與數(shù)據(jù)包的目的IP地址和 目的端口信息不一致時,用sockaddr中的地址信息填充UDP數(shù)據(jù)包的目的IP地址字段和 目的端口字段,并重新計算數(shù)據(jù)包的校驗和,然后判斷套接字socket的sk—sepsocket字段 是否為1,如果是,則置數(shù)據(jù)包內(nèi)核數(shù)據(jù)結(jié)構(gòu)中的bsepsocket字段為1后將數(shù)據(jù)包加入 sk—write—queue隊尾,交由本地網(wǎng)絡(luò)內(nèi)核協(xié)議棧發(fā)送出去。最后應(yīng)說明的是以上實施例僅用以說明而非限制本發(fā)明的技術(shù)方案,盡管參照上述 實施例對本發(fā)明進行了詳細說明,本領(lǐng)域的技術(shù)人員應(yīng)當(dāng)理解依然可以對本發(fā)明進行修改或者等同替換,而不脫離本發(fā)明的精神和范圍的任何修改或局部替換,其均應(yīng)涵蓋在本 發(fā)明的權(quán)利要求范圍當(dāng)中。
權(quán)利要求
1.一種UDP數(shù)據(jù)包的傳輸方法,其步驟如下1)將應(yīng)用網(wǎng)關(guān)接收到的、目的IP地址為非本地IP地址的UDP數(shù)據(jù)包傳輸?shù)絻?nèi)核層的數(shù)據(jù)包轉(zhuǎn)發(fā)模塊;2)數(shù)據(jù)包轉(zhuǎn)發(fā)模塊根據(jù)負載均衡算法,從用戶層業(yè)務(wù)程序創(chuàng)建的數(shù)據(jù)報套接字池中選出一個數(shù)據(jù)報套接字,將需要由業(yè)務(wù)程序處理的UDP數(shù)據(jù)包,分配給所述數(shù)據(jù)報套接字,所述數(shù)據(jù)報套接字包含三個數(shù)據(jù)包緩沖隊列接收隊列、發(fā)送隊列和深度處理隊列;3)將上述數(shù)據(jù)報套接字的本地監(jiān)聽端口、數(shù)據(jù)包轉(zhuǎn)發(fā)模塊的發(fā)送回調(diào)函數(shù)指針以及數(shù)據(jù)鏈路層或網(wǎng)絡(luò)層轉(zhuǎn)發(fā)的目的信息保存到數(shù)據(jù)包內(nèi)核數(shù)據(jù)結(jié)構(gòu)中;4)數(shù)據(jù)包轉(zhuǎn)發(fā)模塊將UDP數(shù)據(jù)包重定向到內(nèi)核層的本地網(wǎng)絡(luò)協(xié)議棧的UDP輸入處理模塊;5)UDP輸入處理模塊對UDP數(shù)據(jù)包的UDP包頭進行解析處理,并根據(jù)數(shù)據(jù)包內(nèi)核數(shù)據(jù)結(jié)構(gòu)中保存的數(shù)據(jù)報套接字本地監(jiān)聽端口信息,找到數(shù)據(jù)包轉(zhuǎn)發(fā)模塊選出的數(shù)據(jù)報套接字,將上述數(shù)據(jù)包加入到該套接字的接收隊列的隊尾;6)用戶層的業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù),觸發(fā)UDP輸入處理模塊從數(shù)據(jù)報套接字的接收隊列的隊首取出UDP數(shù)據(jù)包,還原提取出應(yīng)用層數(shù)據(jù)并拷貝到業(yè)務(wù)程序提供的用戶層緩沖區(qū)中,其中所述函數(shù)均兼容伯克利套接字;如果所述函數(shù)的參數(shù)flags中包含標(biāo)識MSG_PREINSPECTING,則將數(shù)據(jù)包加入到數(shù)據(jù)報套接字的深度處理隊列隊尾;7)業(yè)務(wù)程序解析處理用戶層緩沖區(qū)中的數(shù)據(jù),調(diào)用套接字的系統(tǒng)調(diào)用函數(shù),并根據(jù)所述函數(shù)的參數(shù)flags中設(shè)置的不同標(biāo)識,執(zhí)行對數(shù)據(jù)報套接字深度處理隊列中的原始UDP數(shù)據(jù)包的處理操作,包括丟棄;不做任何修改直接交由數(shù)據(jù)包轉(zhuǎn)發(fā)模塊發(fā)送出去;采用業(yè)務(wù)程序提供的數(shù)據(jù)替換UDP數(shù)據(jù)包的內(nèi)容后再交由數(shù)據(jù)包轉(zhuǎn)發(fā)模塊發(fā)送出去;其中所述系統(tǒng)調(diào)用函數(shù)均兼容伯克利套接字。
2. 如權(quán)利要求1所述的一種UDP數(shù)據(jù)包的傳輸方法,其特征在于步驟7)所述的根據(jù)參 數(shù)flags中設(shè)置的不同標(biāo)識,執(zhí)行對數(shù)據(jù)報套接字深度處理隊列中的原始UDP數(shù)據(jù)包的處 理方法為1)若flags中不包含MSG—POSTINSPECTING標(biāo)識,則將業(yè)務(wù)程序提供的應(yīng)用層數(shù)據(jù) 從用戶層拷貝到內(nèi)核層,UDP輸出處理模塊重新構(gòu)建UDP數(shù)據(jù)包,并將其加入到數(shù)據(jù)報 套接字發(fā)送隊列隊尾,交由本地網(wǎng)絡(luò)協(xié)議棧完成協(xié)議封裝、數(shù)據(jù)鏈路層或網(wǎng)絡(luò)層轉(zhuǎn)發(fā)信息 查找等處理后,最終通過數(shù)據(jù)包轉(zhuǎn)發(fā)模塊發(fā)送出去;2) 若flags中包含MSG—POSTINSPECTING標(biāo)識,將內(nèi)核中的原始UDP數(shù)據(jù)包從數(shù) 據(jù)報套接字的深度處理隊列中移出;3) 若flags中包含MSG_POSTINSPECTING標(biāo)識但不包含MSG—DROP標(biāo)識和 MSG_REPLACE標(biāo)識,則從數(shù)據(jù)包內(nèi)核數(shù)據(jù)結(jié)構(gòu)中得到發(fā)送回調(diào)函數(shù)指針以及作為函數(shù)參 數(shù)的數(shù)據(jù)鏈路層或網(wǎng)絡(luò)層轉(zhuǎn)發(fā)目的信息,然后調(diào)用該發(fā)送回調(diào)函數(shù)將UDP原始數(shù)據(jù)包交 給數(shù)據(jù)包轉(zhuǎn)發(fā)模塊直接發(fā)送出去;4) 若flags中包含MSG—POSTINSPECTING標(biāo)識和MSG—DROP標(biāo)識,則將原始UDP 數(shù)據(jù)包丟棄;5) 若flags中包含MSG—POSTINSPECTING標(biāo)識和MSG—REPLACE標(biāo)識,則將業(yè)務(wù) 程序提供的應(yīng)用層數(shù)據(jù)從用戶層拷貝到內(nèi)核層,替換原始UDP數(shù)據(jù)包的內(nèi)容;如果數(shù)據(jù) 長度超過原始UDP數(shù)據(jù)包內(nèi)容的長度,則拷貝新的UDP數(shù)據(jù)包來放置超長部分的數(shù)據(jù); 重新計算UDP數(shù)據(jù)包的校驗和,然后從數(shù)據(jù)包內(nèi)核數(shù)據(jù)結(jié)構(gòu)中得到發(fā)送回調(diào)函數(shù)指針以 及作為函數(shù)參數(shù)的數(shù)據(jù)鏈路層或網(wǎng)絡(luò)層轉(zhuǎn)發(fā)目的信息,調(diào)用該發(fā)送回調(diào)函數(shù)將UDP數(shù)據(jù) 包交給數(shù)據(jù)包轉(zhuǎn)發(fā)模塊直接發(fā)送出去。
3. 如權(quán)利要求1所述的一種UDP數(shù)據(jù)包的傳輸方法,其特征在于步驟2)中所述的數(shù)據(jù) 報套接字池的創(chuàng)建方法如下1) 用戶層的業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)socket(),創(chuàng)建一個數(shù)據(jù)報套接字;2) 業(yè)務(wù)程序調(diào)用套接字的系統(tǒng)調(diào)用函數(shù)bind(),設(shè)置數(shù)據(jù)報套接字的本地監(jiān)聽端口;3) 將上述數(shù)據(jù)報套接字以本地監(jiān)聽端口為鍵值,加入內(nèi)核中的數(shù)據(jù)報套接字散列表;4) 業(yè)務(wù)程序創(chuàng)建多個數(shù)據(jù)報套接字,形成一個數(shù)據(jù)報套接字池。
4. 如權(quán)利要求1所述的一種UDP數(shù)據(jù)包的傳輸方法,其特征在于步驟6)中所述的系統(tǒng) 調(diào)用函數(shù)為recv()、 recvmsg()或recvfrom()。
5. 如權(quán)利要求1所述的一種UDP數(shù)據(jù)包的傳輸方法,其特征在于步驟7)中所述的系統(tǒng) 調(diào)用函數(shù)為send()、 sendmsg()或sendto()。
全文摘要
本發(fā)明的目的是提供一種UDP數(shù)據(jù)包的傳輸方法,該方法通過將非本地UDP數(shù)據(jù)包直接重定向到本地網(wǎng)絡(luò)協(xié)議棧進行處理(不依賴于網(wǎng)絡(luò)地址轉(zhuǎn)換技術(shù))、數(shù)據(jù)報套接字負載均衡、減少內(nèi)核層和用戶層之間的數(shù)據(jù)拷貝傳遞以及減少網(wǎng)絡(luò)協(xié)議棧中執(zhí)行數(shù)據(jù)包構(gòu)建、協(xié)議封裝、數(shù)據(jù)鏈路層或網(wǎng)絡(luò)層轉(zhuǎn)發(fā)信息查找等復(fù)雜操作的開銷,提高了內(nèi)核層內(nèi)部各模塊間傳輸和處理UDP數(shù)據(jù)包以及內(nèi)核層與用戶層業(yè)務(wù)程序之間傳輸數(shù)據(jù)的效率,實現(xiàn)了應(yīng)用網(wǎng)關(guān)對UDP流量應(yīng)用層數(shù)據(jù)的在線高速處理、UDP數(shù)據(jù)包的快速轉(zhuǎn)發(fā)以及對大量并發(fā)UDP會話的支持,并保證了應(yīng)用網(wǎng)關(guān)對于通信源端和目的端的透明性。
文檔編號H04L12/56GK101217464SQ200710304578
公開日2008年7月9日 申請日期2007年12月28日 優(yōu)先權(quán)日2007年12月28日
發(fā)明者劉曉舟, 嘉 姚, 廖唯棨, 張建宇, 維 鄒 申請人:北京大學(xué)