UDP 丢包的艺术_udp丢包

不像 TCP 内置端到端流控机制,无连接的 UDP 在 Buffer 满了之后,只能丢弃当前收到的数据包,这是一个常规操作。

但注意,如果这是一条 UDP 隧道,即 UDP 运载了 TCP 载荷,简单丢弃该 UDP 报文就是一个针对 TCP 的尾丢操作:
在这里插入图片描述

尾丢往往会持续,进而引发 TCP 超时,如果多流共享隧道,还可能全局同步。总之,尾丢至少会引起 TCP (以及同样使能 Loss-based cc 的 AIMD 流量,如 CUBIC-QUIC)载荷带宽随时间呈大锯齿形波动。

这个地方做个 RED(random early detection)/WRED(weighted random early detection) 就好了,但只针对隧道 UDP,可以通过 iptables 命令模拟:

iptables -I INPUT -p udp --dport $隧道服务端口  -m statistic --mode random --probability 0.005 -j DROP

但这显然无法体现随机丢包的阈值,大突发流量下以稳定换吞吐(额外的丢包率"有可能"降低平均吞吐)。
下面的 HOOK 函数挂在 NF_INET_LOCAL_IN 上将会很高尚:

static unsigned int red_hook(void *priv, struct sk_buff *skb, const struct nf_hook_state *state)
{
        struct iphdr *iph;
        struct sock *sk;
        int rmem;
        unsigned long rand[1];

        iph = ip_hdr(skb);

        if (iph->protocol != IPPROTO_UDP)
                return NF_ACCEPT;

        if (!skb->sk) {
                return NF_ACCEPT;
        }
        sk = skb->sk;
        rmem = atomic_read(&sk->sk_rmem_alloc);
        if (rmem > (sk->sk_rcvbuf - (sk->sk_rcvbuf >> 2))) {
                get_random_bytes(&rand[0], sizeof(unsigned long));
                if (rand[0] % 200 == 0) {
                        return NF_DROP;
                }
        }

        return NF_ACCEPT;
}

RED/WRED 不仅可用于 UDP 隧道,对于普通 UDP 流量,RED/WRED 替换尾丢的高尚之处在于:

  • 避开了连续丢包,统计分辨率和公平性更好。
  • 应用层若做拥塞控制,拥塞更容易被感知。

端主机的 UDP Buffer,是 UDP 端到端的最后一个拥塞点,就像它在链路上一样好咯。

全局同步,准全局同步( RTT 一般都不同)都不是高尚的,对文件传输虽慢点倒还无害,但对流媒体传输就是咔咔咔了,瞬时速率无征兆跌零,给人一种失控之感觉。祸首是 Buffer 尾丢,这种风格的丢包会导致同一连接连续丢包,这也是时间局部性和 Bursty style 的结果。把丢包损失在事前分担给所有流量,最廉价的方案就是随机,就是 RED 背后的思想。

浙江温州皮鞋湿,下雨进水不会胖。

原文链接: https://blog.csdn.net/dog250/article/details/126262347

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍;

也有高质量的技术群,里面有嵌入式、搜广推等BAT大佬

    UDP 丢包的艺术_udp丢包

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/405421

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年4月26日 上午9:11
下一篇 2023年4月26日 上午9:11

相关推荐