自动 TCP 连接减慢(整形)

自动 TCP 连接减慢(整形)

我想自动塑造与已传输的数据相对应的耗带宽的 TCP 连接。

总结如下:“第一个Mbit以全带宽传输,然后当达到10Mbit时逐渐下降到带宽的1%,并保持在这个水平”。

一个例子胜过千言万语:

 b-w  ^
      |        .         .
100%  | ********         .
      |        . *       .
      |        .    *    .
      |        .       * .
  1%  |        .         .********
      +----------------------------> Data transfered.
         1Mbit .         . 10Mbit

我知道完整的流量整形会更好,因为它允许突发和使用剩余带宽,但其想法是具体地自动限制大数据传输而无需任何进一步的配置。

我如何在 Linux 主机上实现这个

更新:虽然不是很明显,但数据计量表很重要两个都方式(上传和下载),因为我故意没有精确下载或上传。

答案1

HTB 队列规定实现的概念爆发这正是您想要的 - 它以全硬件速率发送“burst”参数中指定的数据量。要逐渐减少,您需要嵌套 HTB 类,并且您可能不想过度这样做,因为这会大大增加设置的复杂性。但是 Linux 流量整形引擎本身是无状态的,它只对数据包起作用,而不是对连接起作用。单独使用 tc 过滤器,您只能根据 IP/TCP 标头区分数据包。

因此,如果您需要根据连接进行不同的分类,最直接的方法可能是使用 iptables“--connbytes”匹配和数据包标记(-j MARK 目标)将连接的数据包推入正确的队列(快速/减速)

查看LARTC 指南中关于带宽管理的冗长部分和/或综合“开源带宽解决方案”白皮书以获得更多见解。

此外,如果你需要塑造上游和下游,请查看虚拟 IMQ 接口- 它是专门为此目的而设计的。

答案2

我受到 @the-wabbit 解决方案的启发,并设法解决了这个问题。我在个人 wiki 中发布了关于此解决方案的博文:https://giki.wiki/@nubela/Software-Engineering/Per-Connection-Throttling

下面是我使用实际的 shell 脚本对此问题的解决方案:

#!/bin/sh

dev=eth0
ip_port=3002
rate_limit=512kbit
rate_ceil=1024kbit
htb_class=10
max_byte=10485760

if [ "$(id -u)" != "0" ]; then
    echo "This script must be run as root" 1>&2
    exit 1
fi

if [ "$1" = "enable" ]; then
    echo "enabling rate limits"
    tc qdisc del dev $dev root > /dev/null 2>&1
    tc qdisc add dev $dev root handle 1: htb

    tc class add dev $dev parent 1: classid 1:$htb_class htb rate $rate_limit ceil $rate_ceil
    tc filter add dev $dev parent 1: prio 0 protocol ip handle $htb_class fw flowid 1:$htb_class

    #iptables -t mangle -A OUTPUT -p tcp --sport $ip_port -j MARK --set-mark $htb_class

    # small packet is probably interactive or flow control
    iptables -t mangle -A OUTPUT -p tcp --sport $ip_port -m length --length 0:500 -j RETURN

    # small packet connections: multi purpose (don't harm since not maxed out)
    iptables -t mangle -A OUTPUT -p tcp --sport $ip_port -m connbytes --connbytes 0:250 --connbytes-dir both --connbytes-mode avgpkt -j RETURN

    #after 10 megabyte a connection is considered a download
    iptables -t mangle -A OUTPUT -p tcp --sport $ip_port -m connbytes --connbytes $max_byte: --connbytes-dir both --connbytes-mode bytes -j MARK --set-mark $htb_class
    iptables -t mangle -A OUTPUT -j RETURN

elif [ "$1" = "disable" ]; then
    echo "disabling rate limits"
    tc qdisc del dev $dev root > /dev/null 2>&1

    iptables -t mangle -F
    iptables -t mangle -X

elif [ "$1" = "show" ]; then
    tc qdisc show dev $dev
    tc class show dev $dev
    tc filter show dev $dev
    iptables -t mangle -vnL INPUT
    iptables -t mangle -vnL OUTPUT
else
    echo "invalid arg $1"
fi

相关内容