一种udp数据包的传输方法

文档序号:7669292阅读:186来源:国知局
专利名称:一种udp数据包的传输方法
技术领域
本发明属于计算机网络和数据通信技术领域,涉及一种UDP (User Datagram Protocol) 数据包的传输方法,可用于应用网关的设备和软件中,以提高网关传输UDP数据包以及 处理其应用层数据的效率,减少系统开销和网络延迟。
背景技术
应用网关通常采用透明代理技术,在客户机和服务器之间充当中间人的角色,接收流 经的UDP数据包并重定向到内核层的本地网络协议栈中,由协议栈对数据包进行协议解 析处理,还原提取出应用层数据,然后通过数据报套接字(Datagram Socket)将应用层数 据从内核层拷贝到用户层,传送给用户层的业务程序(如病毒检测程序、关键词过滤程序 等)进行各种处理和修改(如删除、替换);用户层业务程序将处理修改后的数据再通过 数据报套接字从用户层拷贝到内核层,交给本地网络协议栈,并通知协议栈采用重定向前 原始数据包的目的IP地址和目的端口来重新构建数据包并进行协议封装,然后发送出去。 其中,流量重定向多采用网络地址转换技术(Network Address Translation,简称NAT), 这主要是由于传统的套接字(如伯克利套接字,参见文献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)和网络协议栈的实现不能接收和处理非本地目的IP地址 和目的端口的数据包,也不能发送非本地源IP地址和源端口的数据包。因此,应用网关对 接收到的数据包要进行目的地址转换(DNAT),将其目的IP地址和目的端口改为网关的 本地IP地址和本地端口,从而将其重定向传输到应用网关的本地网络协议栈中;对于待发 送的数据包则要进行源地址转换(SNAT),将其源IP地址和源端口从网关的本地IP地址 和本地端口改为DNAT前原始数据包的源IP地址和源端口。为了区分不同会话的数据包, 需要对会话进行跟踪并在会话表中记录NAT操作前后的IP地址和端口信息。上述技术存在如下几个主要缺陷,造成应用网关处理效率和容量的大幅下降,无法满 足在高流量带宽以及存在大量并发会话的网络环境中的性能需求(1) NAT技术对每一 个数据包的IP地址和端口字段进行修改并需重新计算校验和,对系统性能造成一定影响; (2) NAT技术依赖于会话跟踪,需要建立会话表,为每一个UDP会话保存IP地址、端口等信息,而会话跟踪和会话表管理任务的时空间开销繁重,会严重影响系统的性能;(3) 数据在内核层和用户层之间多次拷贝传递,以及在发送数据时需要重新进行数据包构建、 协议封装、数据链路层或网络层转发信息查找等操作,也会严重降低系统性能。发明内容本发明的目的在于提供一种UDP数据包的传输方法,通过将非本地UDP数据包直接 重定向到本地网络协议栈进行处理(不依赖于网络地址转换技术)、数据报套接字负载均 衡、减少内核层和用户层之间的数据拷贝传递以及减少网络协议栈中执行数据包构建、协 议封装、数据链路层或网络层转发信息查找等复杂操作的开销,提高了内核层内部各模块 间传输和处理UDP数据包以及内核层与用户层业务程序之间传输数据的效率。本发明的上述发明目的是通过如下的技术方案实现的 一种UDP数据包的传输方法,其步骤如下,1. 将应用网关接收到的、目的IP地址为非本地IP地址的UDP数据包传输到内核层 的数据包转发模块;2. 数据包转发模块根据负载均衡算法,从用户层业务程序创建的数据报套接字池中选 出一个数据报套接字,将需要由业务程序处理的UDP数据包,分配给所述数据报套接字, 所述数据报套接字包含三个数据包换从队列接收队列、发送队列和深度处理队列;3. 将上述数据报套接字的本地监听端口、数据包转发模块的发送回调函数指针以及数 据链路层或网络层转发的目的信息保存到数据包内核数据结构中;4. 数据包转发模块将UDP数据包重定向到内核层的本地网络协议栈的UDP输入处理模块;5. UDP输入处理模块对UDP数据包的UDP包头进行解析处理,并根据数据包内核数 据结构中保存的数据报套接字本地监听端口信息,找到数据包转发模块选出的数据报套接 字,将上述数据包加入到该套接字的接收队列的队尾;6. 用户层的业务程序调用套接字的系统调用函数,触发UDP输入处理模块从数据报 套接字的接收队列的队首取出UDP数据包,还原提取出应用层数据并拷贝到业务程序提 供的用户层缓冲区中,其中所述函数均兼容伯克利套接字;如果所述函数的参数flags中包 含标识MSG一PREINSPECTING,则将数据包加入到数据报套接字的深度处理队列队尾;7. 业务程序解析处理用户层缓冲区中的数据,调用套接字的系统调用函数,并根据所述函数的参数flags中设置的不同标识,执行对数据报套接字深度处理队列中的原始UDP 数据包的不同处理操作,包括丢弃;不做任何修改直接交由数据包转发模块发送出去; 采用业务程序提供的新数据替换UDP数据包的内容后再交由数据包转发模块发送出去, 其中所述系统调用函数均兼容伯克利套接字。进一步,步骤6中所述的套接字的系统调用函数为recv()、 recvmsg()或recvfrom()。 进一步,步骤7中所述的套接字的系统调用函数为send()、 sendmsg()或sendto()。 进一步,所述的根据参数flags中设置的不同标识,执行对数据报套接字深度处理队列 中的原始UDP数据包的处理步骤为-O若flags中不包含MSG一POSTINSPECTING标识,则将业务程序提供的应用层数据 从用户层拷贝到内核层,UDP输出处理模块重新构建UDP数据包,并将其加入到数据报 套接字发送队列队尾,交由本地网络协议栈完成协议封装、数据链路层或网络层转发信息 査找等处理后,最终通过数据包转发模块发送出去;2) 若flags中包含MSG—POSTINSPECTING标识,将内核中的原始UDP数据包从数 据报套接字的深度处理队列中移出;3) 若flags中包含MSG—POSTINSPECTING标识但不包含MSG_DR0P标识和 MSG—REPLACE标识,则从数据包内核数据结构中得到发送回调函数指针以及作为函数参 数的数据链路层或网络层转发目的信息,然后调用该发送回调函数将UDP原始数据包交 给数据包转发模块直接发送出去;4) 若flags中包含MSG—POSTINSPECTING标识和MSG—DROP标识,则将原始UDP 数据包丢弃;5) 若flags中包含MSG—POSTINSPECTING标识和MSG—REPLACE标识,则将业务 程序提供的应用层数据从用户层拷贝到内核层,替换原始UDP数据包的内容;如果数据 长度超过原始UDP数据包内容的长度,则拷贝新的UDP数据包来放置超长部分的数据; 重新计算UDP数据包的校验和,然后从数据包内核数据结构中得到发送回调函数指针以 及作为函数参数的数据链路层或网络层转发目的信息,调用该发送回调函数将UDP数据 包交给数据包转发模块直接发送出去。进一步,步骤2中所述的用户层的业务程序创建数据报套接字池的步骤为1) 用户层的业务程序调用套接字的系统调用函数socket(),创建一个数据报套接字;2) 业务程序调用套接字的系统调用函数bind(),设置数据报套接字的本地监听端口;3) 将上述数据报套接字以本地监听端口为键值,加入内核中的数据报套接字散列表;4) 业务程序创建多个数据报套接字,形成一个数据报套接字池。本发明的优点和积极效果如下1. 本发明通过将非本地UDP数据包直接重定向到本地网络协议栈进行处理,以及通过数据包发送回调函数直接转发数据包,提高了内核层内部各模块间传输和处理UDP数 据包的效率;2. 本发明通过设置套接字的数据包缓冲深度处理队列,以及根据系统调用参数flags 中设置的不同标识对其中的原始UDP数据包执行处理,减少了在内核层和用户层之间多 次拷贝传递数据以及在网络协议栈中执行数据包构建、协议封装、数据链路层或网络层转 发信息査找等复杂操作的开销;3. 本发明通过上述技术手段以及数据报套接字负载均衡,实现了应用网关对UDP流 量应用层数据的在线高速处理、UDP数据包的快速转发以及对大量并发UDP会话的支持。4. 本发明保证了应用网关对于通信源端和目的端的透明性。


图1本发明实施例的系统结构图;图2本发明实施例的创建数据报套接字的流程图;图3本发明实施例的处理UDP数据包的流程图。
具体实施方式
以防病毒应用安全网关为例,参照附图对本发明的一种UDP数据包的传输方法进行详细说明。图l为该实施例的系统结构图。数据包的内核数据结构中包含一个非本地数据包标识字段bsepsocket,应用网关的本 地网络协议栈根据该字段是否置1来区分非本地数据包(即目的IP地址和源IP地址均不 为本地IP地址的数据包)和本地数据包。数据包的内核数据结构中还包含一个该数据包所属套接字的本地监听端口字段 sepsocket—listen_port,通过设置该字段将数据包分配给业务程序创建的一个数据报套接字进行处理,并实现不同数据报套接字间的负载均衡。数据包的内核数据结构中包含一个回调函数指针字段sepsocket—forward_callback_fiinc 和一个函数参数字段sepsocket—forward—callback_params,用以实现UDP数据包的直接发 送。应用网关的本地网络协议栈中包含一个数据报套接字散列表,用以保存所有通过套接 字的系统调用socket()创建的数据报套接字,并实现对套接字的快速査找。套接字的内核数据结构中包含一个标识字段sk—sepsocket,当该字段置1时允许数据 报套接字处理非本地UDP数据包。同时为该标识字段增加一个对应的SOL—SOCKET级别 的套接字选项SO_SEPSOCKET,使得业务程序可以通过套接字的系统调用setsockopt()对 该标识字段进行设置。每个数据报套接字包含三个数据包缓冲队列接收队列sk—receiVe_qUeUe、发送队列 sk_write—queue和深度处理队列sk—inspect—queue,用于分别保存从本地网络协议栈接收到 的数据包、准备通过本地网络协议栈发送的数据包和正在由业务程序进行处理的数据包。如图2所示,用户层的业务程序创建数据报套接字的流程为(1) 用户层的业务程序调用套接字的系统调用函数socket(),新建一个数据报套接字。 socket()与伯克利套接字兼容,其调用形式如下int socketfd = socket(PF—INET, SOCK—DGRAM, IPPROTO—IP);(2) 业务程序调用套接字的系统调用函数setsockopt(),将该数据报套接字的 sk—sepsocket字段置1,从而允许该数据报套接字处理非本地UDP数据包。sk—sepsocket 字段对应的套接字选项为SO—SEPSOCKET,级别为SOL_SOCKET。 setsockopt()与伯克利套接字兼容,其调用形式如下-setsockopt(socketfd, SOL—SOCKET, SO—SEPSOCKET, 1, sizeof(int));(3) 业务程序调用套接字的系统调用函数bind()——与伯克利套接字兼容,设置该数 据报套接字的本地监听端口;(4) 系统调用bind()在获得业务程序给该数据报套接字分配的本地监听端口后,以监 听端口为键值将该数据报套接字加入内核的数据报套接字散列表。业务程序通常按照上述步骤创建多个数据报套接字,形成一个数据报套接字池,再通 过并行和负载均衡将UDP会话分散到不同的数据报套接字进行处理,以提高UDP流量的 吞吐量。如图3所示,防病毒应用安全网关处理UDP数据包的流程为(1) 对于防病毒应用安全网关接收到的、目的IP地址为非本地IP地址的UDP数据 包,送入内核层的数据包转发模块进行处理,査找数据链路层或网络层转发目的信息并根 据一定的规则判断数据包是否需要由用户层业务程序进行处理;(2) 如果不需要,则将数据包直接转发出去,结束;(3) 如果需要,则数据包转发模块将数据包内核数据结构的bsepsocket字段置l,标 明其为非本地数据包;(4) 数据包转发模块根据负载均衡算法(参见文献C. Kopparapu, "Load Balancing Servers, Firewalls, and Caches", Wiley, 2002)从业务程序创建的数据报套接字池中选出一个 数据报套接字,将该套接字的本地监听端口保存到数据包内核数据结构的 sepsocketJistenjort字段中。负载均衡算法可釆用简单轮询算法(round robin)算法,艮卩 假设套接字池中有n个套接字,则当第1个UDP数据包到来时,将其分配给第1个套接 字,后续到来的数据包顺序分配给第2、 3、...直到第n个套接字,然后又重新从第l个套 接字开始分配,如此循环反复;(5) 数据包转发模块将负责后续转发操作的函数作为数据包的发送回调函数,用于 在完成对数据包的病毒检测处理后、重新发送数据包时进行调用。数据包转发模块将该函 数的指针和参数(即该数据包的数据链路层或网络层转发目的信息)分别保存到数据包内 核数据结构的sepsocket—forward—callback—fUnc字段禾口 sepsocket—forward—callback_params 字段中;(6) 数据包转发模块将UDP数据包直接重定向到内核层的本地网络协议栈;(7) 本地网络协议栈的UDP输入处理模块得到bsepsocket字段置1的UDP数据包后, 对数据包的UDP包头进行解析处理;(8) UDP输入处理模块以数据包内核数据结构的sepsocketjistenjport字段为散列键 值,在数据报套接字散列表中找到sk—sepsocket字段置1且本地监听端口与 sepsocket—liSten_port字段相同的数据报套接字;(9) 将数据包加入到该数据报套接字的sk—receive—queue队尾,等待用户层业务程序 对其应用层数据进行防病毒检测过滤;(10) 用户层的业务程序调用套接字的系统调用函数recv()、 recvmsg()或recvfrom() ——与伯克利套接字兼容,调用形式如下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); 其中,函数参数flags置为MSG_PREINSPECTING;(11) 套接字的系统调用recv()、 recvmsg()和recvfrom()触发UDP输入处理模块,从 数据报套接字socketfd的sk—receive_queue队首取出UDP数据包,将其应用层数据还原提 取出来后拷贝到业务程序提供的用户层缓冲区buf或msg中;(12) 由于上述函数的参数flags中包含标识MSG—PREINSPECTING,因此执行完上 述操作后数据报套接字并不立即释放UDP数据包,而是将其加入到数据报套接字的 sk_inspect_queue队尾,等待业务程序的处理结果;(13) 业务程序对buf或msg中的数据进行应用协议解析,提取出其中的数据进行病 毒扫描检测,并针对不同的检测结果执行相应的处理,包括如下几种情况检查通过,数 据中不含病毒,将原始UDP数据包转发出去;未通过检査,数据中含有病毒,将原始UDP 数据包丢弃;未通过检査,数据中含有病毒,将原始UDP数据包的内容进行替换后发送 出去;(14) 用户层的业务程序调用套接字的系统调用函数send()、 sendmsg()或sendto()—— 与伯克利套接字兼容,执行对原始UDP数据包的处理,调用形式如下int i = send(socketfd, buf, len, flags);int i = sendmsg(socketfd, msg, flags);int i = sendto(socketfd, buf, len, flags, sockaddr, addr—len); 其中,函数参数flags根据不同的处理要求进行设置如果是通过检査、转发,则置为 MSG_POSTINSPECTING;如果未通过检査、丢弃,则置为MSG—POSTINSPECTING和 MSG_DROP;如果是未通过检査、替换内容后转发,则置为MSG—POSTINSPECTING和 MSG—REPLACE;(15) 如果flags中不包含MSG—POSTINSPECTING标识,则套接字的系统调用send()、 sendmsg()和sendto()将业务程序提供的缓冲区buf或msg中的应用层数据从用户层拷贝到 内核层,并将其连同flags、 socketaddr等交给本地网络协议栈的UDP输出处理模块。UDP 输出处理模块基于此应用层数据重新构建UDP数据包,并判断套接字的skjepsocket字段 是否为l,如果是,则置数据包内核数据结构的bsepsocket字段为1,然后将UDP数据包 加入sk—write—queue队尾等待发送。sk—write—queue队列中的UDP数据包还要在本地网络 协议栈中经协议封装、数据链路层或网络层转发信息查找等处理后,最后交由数据包转发模块发送出去。结束;(16) 如果flags中包含MSG—POSTINSPECTING标识,则将原始UDP数据包从套接 字socketfd的skjnspect—queue队歹!j中移出;(17) 如果flags中包含MSG—POSTINSPECTING标识但不包含MSG—DROP标识和 MSG_REPLACE标识,则无需拷贝buf和msg,只需调用数据包内核数据结构的 sepsocket—forward—callback_fUnc字段所指向的数据包发送回调函数,并以 sepsocket—forward—callback_params字段中保存的数据链路层或网络层转发目的信息为函数 参数,将原始UDP数据包交给数据包转发模块直接发送出去(即无需再经过本地网络协 议栈进行协议封装、转发信息查找等处理)——对于sendto(),如果参数sockaddr不为空 且其中的地址信息与数据包的目的IP地址和目的端口信息不一致,则不能执行上述直接发 送数据包的操作,而是要转到步骤(20)进行特殊处理;(18) 如果flags中包含MSG_POSTINSPECTING标识和MSG—DROP标识,则将原 始UDP数据包丢弃即可。结束;(19) 如果flags中包含MSG—POSTINSPECTING标识和MSG—REPLACE标识,则 将buf或msg中的应用层数据从用户层拷贝到内核层,用此应用层数据替换原始UDP数 据包的内容。如果数据的长度超过原始UDP数据包内容的长度,则拷贝若干新的UDP数 据包来放置超长部分的数据。重新计算UDP数据包的校验和后,调用数据包内核数据结 构中的sepsocket—forward—callback_func字段所指向的数据包发送回调函数,并以 sepsocket—forward—callback_paramS字段中保存的数据链路层或网络层转发目的信息为函数 参数,将UDP数据包交给数据包转发模块直接发送出去一一对于sendto(),如果参数 sockaddr不为空且其中的地址信息与数据包的目的IP地址和目的端口信息不一致,则不能 执行上述直接发送数据包的操作,而是要转到步骤(20)进行特殊处理;(20) 当sendto()的参数sockaddr不为空且其中的地址信息与数据包的目的IP地址和 目的端口信息不一致时,用sockaddr中的地址信息填充UDP数据包的目的IP地址字段和 目的端口字段,并重新计算数据包的校验和,然后判断套接字socket的sk—sepsocket字段 是否为1,如果是,则置数据包内核数据结构中的bsepsocket字段为1后将数据包加入 sk—write—queue队尾,交由本地网络内核协议栈发送出去。最后应说明的是以上实施例仅用以说明而非限制本发明的技术方案,尽管参照上述 实施例对本发明进行了详细说明,本领域的技术人员应当理解依然可以对本发明进行修改或者等同替换,而不脱离本发明的精神和范围的任何修改或局部替换,其均应涵盖在本 发明的权利要求范围当中。
权利要求
1.一种UDP数据包的传输方法,其步骤如下1)将应用网关接收到的、目的IP地址为非本地IP地址的UDP数据包传输到内核层的数据包转发模块;2)数据包转发模块根据负载均衡算法,从用户层业务程序创建的数据报套接字池中选出一个数据报套接字,将需要由业务程序处理的UDP数据包,分配给所述数据报套接字,所述数据报套接字包含三个数据包缓冲队列接收队列、发送队列和深度处理队列;3)将上述数据报套接字的本地监听端口、数据包转发模块的发送回调函数指针以及数据链路层或网络层转发的目的信息保存到数据包内核数据结构中;4)数据包转发模块将UDP数据包重定向到内核层的本地网络协议栈的UDP输入处理模块;5)UDP输入处理模块对UDP数据包的UDP包头进行解析处理,并根据数据包内核数据结构中保存的数据报套接字本地监听端口信息,找到数据包转发模块选出的数据报套接字,将上述数据包加入到该套接字的接收队列的队尾;6)用户层的业务程序调用套接字的系统调用函数,触发UDP输入处理模块从数据报套接字的接收队列的队首取出UDP数据包,还原提取出应用层数据并拷贝到业务程序提供的用户层缓冲区中,其中所述函数均兼容伯克利套接字;如果所述函数的参数flags中包含标识MSG_PREINSPECTING,则将数据包加入到数据报套接字的深度处理队列队尾;7)业务程序解析处理用户层缓冲区中的数据,调用套接字的系统调用函数,并根据所述函数的参数flags中设置的不同标识,执行对数据报套接字深度处理队列中的原始UDP数据包的处理操作,包括丢弃;不做任何修改直接交由数据包转发模块发送出去;采用业务程序提供的数据替换UDP数据包的内容后再交由数据包转发模块发送出去;其中所述系统调用函数均兼容伯克利套接字。
2. 如权利要求1所述的一种UDP数据包的传输方法,其特征在于步骤7)所述的根据参 数flags中设置的不同标识,执行对数据报套接字深度处理队列中的原始UDP数据包的处 理方法为1)若flags中不包含MSG—POSTINSPECTING标识,则将业务程序提供的应用层数据 从用户层拷贝到内核层,UDP输出处理模块重新构建UDP数据包,并将其加入到数据报 套接字发送队列队尾,交由本地网络协议栈完成协议封装、数据链路层或网络层转发信息 查找等处理后,最终通过数据包转发模块发送出去;2) 若flags中包含MSG—POSTINSPECTING标识,将内核中的原始UDP数据包从数 据报套接字的深度处理队列中移出;3) 若flags中包含MSG_POSTINSPECTING标识但不包含MSG—DROP标识和 MSG_REPLACE标识,则从数据包内核数据结构中得到发送回调函数指针以及作为函数参 数的数据链路层或网络层转发目的信息,然后调用该发送回调函数将UDP原始数据包交 给数据包转发模块直接发送出去;4) 若flags中包含MSG—POSTINSPECTING标识和MSG—DROP标识,则将原始UDP 数据包丢弃;5) 若flags中包含MSG—POSTINSPECTING标识和MSG—REPLACE标识,则将业务 程序提供的应用层数据从用户层拷贝到内核层,替换原始UDP数据包的内容;如果数据 长度超过原始UDP数据包内容的长度,则拷贝新的UDP数据包来放置超长部分的数据; 重新计算UDP数据包的校验和,然后从数据包内核数据结构中得到发送回调函数指针以 及作为函数参数的数据链路层或网络层转发目的信息,调用该发送回调函数将UDP数据 包交给数据包转发模块直接发送出去。
3. 如权利要求1所述的一种UDP数据包的传输方法,其特征在于步骤2)中所述的数据 报套接字池的创建方法如下1) 用户层的业务程序调用套接字的系统调用函数socket(),创建一个数据报套接字;2) 业务程序调用套接字的系统调用函数bind(),设置数据报套接字的本地监听端口;3) 将上述数据报套接字以本地监听端口为键值,加入内核中的数据报套接字散列表;4) 业务程序创建多个数据报套接字,形成一个数据报套接字池。
4. 如权利要求1所述的一种UDP数据包的传输方法,其特征在于步骤6)中所述的系统 调用函数为recv()、 recvmsg()或recvfrom()。
5. 如权利要求1所述的一种UDP数据包的传输方法,其特征在于步骤7)中所述的系统 调用函数为send()、 sendmsg()或sendto()。
全文摘要
本发明的目的是提供一种UDP数据包的传输方法,该方法通过将非本地UDP数据包直接重定向到本地网络协议栈进行处理(不依赖于网络地址转换技术)、数据报套接字负载均衡、减少内核层和用户层之间的数据拷贝传递以及减少网络协议栈中执行数据包构建、协议封装、数据链路层或网络层转发信息查找等复杂操作的开销,提高了内核层内部各模块间传输和处理UDP数据包以及内核层与用户层业务程序之间传输数据的效率,实现了应用网关对UDP流量应用层数据的在线高速处理、UDP数据包的快速转发以及对大量并发UDP会话的支持,并保证了应用网关对于通信源端和目的端的透明性。
文档编号H04L12/56GK101217464SQ200710304578
公开日2008年7月9日 申请日期2007年12月28日 优先权日2007年12月28日
发明者刘晓舟, 嘉 姚, 廖唯棨, 张建宇, 维 邹 申请人:北京大学
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1