时间:2024-09-03
高建行
桂林理工大学信息科学与工程学院 广西 541004
随着网络应用范围的不断扩展,对网络带宽资源的要求也随着网络应用范围的扩大而提高,网络带宽资源相对应用的需求总是有限的;另外不同的网络应用业务对网络的带宽、可靠性和时延的要求也不一样。因此如何合理的根据不同业务的具体需求分配带宽并进行精确的流量控制已经成为目前网络管理中一个迫切需要解决的问题。在目前的网络通信中,大多数流量是以 TCP/IP协议为基础的,即所有的通信是交互的,当接收端收到数据包后,总要发送一个确认消息以便发送方采取下一步动作。目前由于P2P业务的大量应用造成大量的带宽被占用,更需要对网络进行更精确的流量控制与带宽分配。目前Linux平台下以Netfilter和Iptables构建的Traffic Control下提供了多种流量控制策略,但由于其粒度过大无法提供精确的流量控制。
Linux内核中的防火墙 Netfilter是用于扩展各类网络服务的结构化的底层架构,主要包含:数据报过滤模块、连接跟踪模块、网络地址转换模块、数据报修改模块和其它高级功能模块。Netfilter的这种架构设计使得其生成的任何一个结构模块比较容易扩展,因此一些新的特性的加入只需通过构建相应的内核模块,并不需要对内核进行重启,有利于扩展底层网络的特性。Netfilter主要通过HOOK机制、Iptables基础模块来实现。其处理流程如下:数据报进入系统后,经IP校验以后,先由第一个HOOK函数NF_IP_PRE_ROUTING进行处理;然后路由选择模块决定该数据报的去向,是否需要转发或是留在本机;发给本机的数据报,则由HOOK函数NF_IP_LOCAL_IN处理后发送给上层协议;转发的数据报,则交由 NF_IP_FORWARD的 HOOK函数处理;最后一个HOOK函数NF_IP_POST_ROUTING处理转发的数据报后,再将其传输到网络上。HOOK函数NF_IP_LOCAL_OUT将本地所产生的数据报处理之后,经路由选择,由HOOK函数NF_IP_POST_ROUTING处理并转发。
Linux内核模块中的Netfilter扩展可以在5个HOOK函数中进行,如图1所示。控制和监听相应的数据包。在每个HOOK函数处,可以任意对数据报进行处理,且使每个HOOK函数的处理结果都反馈给Nefilter,以便Netfilter对数据报的类型标记、转发路径等进行相应处理。
图1 Linux内核数据包处理流程
Netfilter的Iptables提供了limit和hashlimit的模块,用于匹配单位时间内通过的数据包的数量。其中hashlimit相比limit模块多了hash功能,是有limit模块扩展而来,可以根据IP地址进行数据包发送数量的限制。netfilter提供的limit和limit-burst两个选项可以对发送数据包的数量进行限制,但是其存在如下问题。
由于 netfilter架构下的 limit模块只是实现了一个match,用于计算单位时间内通过的数据包的数目。这是一种基于数据包数量的统计方法,而不是基于单位时间内的流量进行统计的,因此很难准确的统计流量。例如,限制某个IP地址单位时间内发50个数据包,然而这50个数据包有可能是50个mtu大小的数据包,也有可能是50个单字节大小载荷的数据包或者是TCP的ACK包,因此很难实现真正的流控。另外这个模块仅仅实现了一个netfilter的match函数,其使用方法为:
没有任何策略队列对超发的流量进行缓存,只能简单的丢弃。这种简单的直接丢弃方式会影响突发流量较多的业务开展的质量。另外,这种方式需要把所有的要需要基于IP限速的IP地址全要作为filter的匹配规则显示标示出来,会导致策略表的快速膨胀消耗大量的内存。
Netfilter的limit模块限定的速度最快为每秒发送10000个数据包,即发送一个数据包耗费0.1毫秒。然而由于此算法是基于平台宏HZ的,即系统的jiffy计数器。由于不同平台的HZ是不一样的,Linux 2.4内核中规定为100,ARM平台也规定为100。例如在linux 2.6版本内核上规定其为1000,也就是说jiffy计数器在此平台上没1ms加1。由以上可得出,jiffy计数器的频率在一定程度上影响着发包的数量。
根据如图1所示的数据包在Linux防火墙Netfilter的处理流程中,数据包进来时首先经过PREROUTING而流出的数据包经过 POSTROUTING。因此对于流入的数据包的控制,在NF_IP_PRE_ROUTING处的HOOK函数处进行控制,对于流出的数据包,在NF_IP_POST_ROUTING处的HOOK函数处进行控制,这样能降低系统控制的成本。Netfilter的limit模块目前支持对单位时间内发送和接收数据包的数量进行限制,我们可以通过修改limit模块的实现来限制单位时间内所发送的数据量的大小,并通过重新设计令牌桶算法结合limit模块来控制指定Ip地址的流量。
根据 Netfilter的框架结构,将扩展分为两大部分,在Netfilter部分实现了一个match,能控制其网络内部的每台计算机单位时间内通过的流量,以此为基础可以控制单个IP地址下的单位时间内流量的大小,并重新构造了一个令牌桶实现了对流量的整形控制;在 Iptables中实现一个用户态的Iptables扩展库,实现了一个match的配置接口。Match函数的设计为,在源IP链表中寻找数据包所携带源IP地址,若在源IP链表中找到相匹配的IP地址,则取出相应的统计信息,看令牌桶中是否有足够的令牌,若有则匹配,若源 IP地址链表中没有找到,则创建一个链表项,并记录下当前时间和当前数据包的大小并返回无匹配项信息;若找到,将找到的匹配项的源链表项取出,插入到HEAD位置,若没有找到则将刚刚创建的链表项插入到链表的HEAD位置。
Linux内核中对流量进行控制和整形的令牌桶算法是著名的网络流限速算法,它通过令牌来控制网络数据包发送或接收的速度,令牌既然可以代表数据包的数量,也就可以代表数据量的多少。之所以可以用此方法限速,是因为系统可以按照用户事先约定的速度,向令牌桶中放置令牌并且令牌桶容量有限,桶满后不能再放入令牌。当数据包到达后,首先计算当前数据包所需要的令牌数并查看令牌桶中令牌数量,若当前令牌桶中的令牌数量满足数据包发送的要求,则放行数据包,且从令牌桶中减去与当前发送的数据包相同当量的令牌。基于上述的思路,构造了一个令牌桶原理的新算法,对单位时间内发送的字节数进行限制,并且需要显示指定限制的单位时间内的流量、允许的突发缓冲区大小,缓冲区用于流量整形。通过下面的算法来计算令牌数量,每一个令牌所代表的可发送的字节数和每个 jiffy所产生的令牌数(一个 jiffy是计算机内部硬件计时器的一个嘀嗒声,例如内部处理器的频率为100hz那么就是10ms产生一个jiffy)。根据当前到达数据包的长度与当前数据包所需要的令牌数进行计算与比较,若当前到达的数据包所需要的令牌数大于当前令牌桶中所拥有的令牌数,则不允许此数据包发送,可以将此数据包放到缓冲区暂存,等有足够令牌后发送。反之,允许此数据包的发送。
下面是令牌桶算法的计算方法,当指定好限定的流量后,令牌桶中的令牌数量按照如下数量关系来计算:
根据 Netfilter提供的框架,可以扩展 Table、Match和Target等。在这里我们将用Match构件扩展来限制发包的速度,使其成为Iptables的match扩展模块。程序包含用户态和内核态两部分,用户态主要在 Iptables模块,用来供用户输入流量控制参数并向内核态传递用户输入的流量控制参数,内核态部分根据用户输入的控制参数执行实际流量控制。
内核实现如下:
(1) 定义一个 struct st_rateinfo, 用来存放限速信息;
(2) 维护一个IP地址链表,用于保存到达本地本机的IP数据包的IP地址;
(3) 实现一个 match函数,并在此函数中实现令牌桶控制和流量的整形处理。
例如要对来自192.168.0.1 这个地址进行限流至200k,则添加如下两条规则即可:
本文研究了根据IP地址进行流量限速的方法。该方法改进了 linux内核本身令牌桶算法存在的在不同平台上的流量不一致问题和流量统计不精确问题。在linux的netfilter框架中存在的精确控制流量的问题和不同平台统计不一致问题都可以用改进的令牌桶算法解决。实现了单个IP地址的出入数据流的控制。
[1]杨虎,张大方,谢鲲等.Netfilter/Iptables框架下基于TCP滑动窗口的串行流量控制算法[J].计算机工程与科学.2009.
[2]李君.P2P 业务流量识别、分析和控制研究[J].计算机工程.2006.
[3]程克勤,顾栋梁,周健.Per_IP流量控制方法[J].计算机工程与设计.2010.
[4]Nicolas Bouliane.Limit TBF analysis[EB/OL].http://people.netfilter.org/acidfu/papers/limit-tbf-analysis.pdf.2007.
我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自各大过期杂志,内容仅供学习参考,不准确地方联系删除处理!