TCP分片机制介绍

MTU,MSS概念

tcp帧

tcp协议规定的帧长度如下如所示
tcp协议帧结构
通常情况下各个帧长度如下:
以太网帧:1518bytes
网卡MTU:1500bytes
TCP最大段:1460bytes
数据在网络中传输时,长度大于MTU的包会被IP层分片传输,到达目的地后再中心组装成一个完整的包。但是ip分片存在着严重的性能问题:

  • 影响效率,消耗cpu和内存,server,router,and client都会进行分片
  • 一个ip分片丢失将导致整个TCP数据包重传(ip层提供不可靠服务,无法知晓哪个分片丢失)

因此TCP协议在TCP层,利用MSS避免数据分片问题。具体方法是:

通信双方进行三次握手传递SYN包时,将自己的最大MSS值(根据MTU值计算)写在header中,传递给对方。最终双方将选取一个最小的MSS值作为TCP层可发送的最大数据长度。这个过程叫做MSS协商

TCP的MSS只能保证通信的两端数据不会被分片,无法保证整个传输路径中数据不被分片,例如网络中的路由器。PMTUD就是为了解决这个问题的。

PMTUD

PMTUD was developed in order to avoid fragmentation in the path between the endpoints. It is used to dynamically determine the lowest MTU along the path from a packet’s source to its destination.

PMTUD机制主要用于在两个tcp连接端动态选择mtu值从而避免tcp包被分片.
df标识都将被启用(==即不允许分片==)。
/proc/sys/net/ipv4/ip_no_pmtu_disc值默认为0,表示启用PMTUD

当源端主机发送一个报文段给目的主机时,如果目的主机无法接收将会返回一个icmp包错误:主机不可达-不可分片:

fragmentation needed and DF set

接收到此消息后,PMTUD会自动减小MSS大小,以保证数据都可以不分片在链路上传输。
PMTUD主要依赖于ICMP返回的错误报文信息,但依然存在问题:icmp black hole(icmp黑洞)
即icmp报文丢失

  • A router can drop a packet and not send an ICMP message. (Uncommon)
  • A router can generate and send an ICMP message, but the ICMP message gets blocked by a router or firewall between this router and the sender. (Common)
  • A router can generate and send an ICMP message, but the sender ignores the message. (Uncommon)

解决办法:ICMP黑洞检测
Enable smart MTU black hole detection.

1
2
echo 1 > /proc/sys/net/ipv4/tcp_mtu_probing
echo 1024 > /proc/sys/net/ipv4/tcp_base_mss

iptable设置MSS与MTUD

1
iptables -I FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu