首先介绍一下背景,TCP有一个概念叫最大段大小(MSS)。这是TCP协议栈可以接受的最大段(数据)。当建立连接时,它会在SYN段中向远程对等体预告。下面的数据包解码显示了高亮显示TCP MSS选项的SYN段。所有的TCP选项都有相同的格式,1个字节表示选项号,本例中为2,1个字节表示选项的总长度(4)和选项的值,本例中为5b4十六进制或1460十进制。
packet_monitor -interface #sdlmux.m16.11-3 -hex_dump -numeric -time_stamp -verbo +se -pkt_hdr -filter -host 10.64.77.50 dir icmp type + tcp hh:mm:ss.ttt dir len proto source destination src port ds +t port type 10:11:56.751 Xmit Ether Dst 00:23:54:52:18:6e Src 00:00:a8:43:52:22 Type 0800 +(IP) IP Ver/HL 45, ToS 0, Len 2c, ID be0b, Flg/Frg 0, TTL 3c, Prtl 6 Cksum dcdd, Src a404d80, Dst a404d32 TCP from 10.64.77.128.55911 to 10.64.77.50.telnet seq 1305537174, ack n.a., window 8192, 4 data bytes, flags Syn. X/Off 06, Flags 02, Cksum 815d, Urg-> 0000 offset 0 . . . 4 . . . 8 . . . C . . . 0...4...8...C... 0 2 4 5 b4 <<<4
对于在本地网络上与主机的连接,STCP使用1460的值。一旦你加上所有的协议开销,你最终会得到一个1518字节的以太网帧--最大的以太网帧大小。对于连接到非本地网段的主机,STCP使用从min_mss参数中得出的值。使用默认的min_mss值将导致MSS值为536。这个值是所有基于IP的网络设备,即路由器必须愿意转发而不产生IP碎片的最小大小,将536确定为最小值的规范是1983年写在RFC 879--"TCP最大网段大小和相关主题"中。
今天,很可能你的所有路由器都能处理更大的尺寸。因此,你可以将STCP的最小值从536提高到更大。大多少是个关键问题。使其过大的危险是碎片化。最坏的情况,但最容易诊断,是路由器会选择丢弃TCP段,而不是将其碎片化。在这种情况下,你将能够建立一个连接,但当传输数据时,连接将失败。发送主机上的跟踪会显示大的TCP段的多次重传,直到连接超时。跟踪还可能显示来自丢弃段的路由器的ICMP目标不可达消息。如果路由器选择对网段进行碎片化处理,很可能会给碎片化处理赋予较低的优先级,这实际上可能会导致吞吐量的降低。同时由于损坏或拥塞而丢失网段的概率也会随着碎片数量的增加而增加。最简单的方法是在模块上运行packet_monitor跟踪来判断是否是这种情况。如果TCP段以碎片的形式出现,你就知道发生了碎片。
下面的三个以太网帧代表一个TCP段被分割成三个部分。因为Flg/Frg值是2000,所以可以判断第一个帧是一个碎片。2表示设置了More Fragments位,000是碎片偏移量,本例中0表示是第一个碎片。Packet monitor实际上将后面2个帧标记为碎片。第2帧的Flg/Frg值为2048,同样是2表示More Fragments位被设置,48是原始IP数据报中数据的偏移量(8字节的倍数)。第3帧的Flg/Flag仅为90,更准确的说是0090。由于More Fragments位为0,我们知道这是最后一个片段。我们知道这些帧都属于一起,因为它们都有相同的IP ID值,2e87。第一帧的数据长度是应该设置的MSS值的指示,在本例中是556。
15:52:27.081 Rcvd Ether Dst 00:00:a8:43:52:22 Src 00:12:3f:82:57:10 Type 0800 +(IP) IP Ver/HL 45, ToS 8, Len 254, ID 2e87, Flg/Frg 2000, TTL 3f, Prtl 6 Cksum 1422, Src c0a86432, Dst a404d80 TCP from 192.168.100.50.32781 to 10.64.77.128.ftp-data seq 568258166, ack 840605671, window 5440, 556 data bytes, flags Ack. X/Off 05, Flags 10, Cksum d149, Urg-> 0000 offset 0 . . . 4 . . . 8 . . . C . . . 0…4… 8…C… 0 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 * 5678901234567890 10 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 * 1234567890123456 20 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 * 7890123456789012 30 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 * 3456789012345678 40 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 * 9012345678901234 50 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 * 5678901234567890 60 d a 31 32 33 34 35 36 37 38 39 30 31 32 33 34 * <<12345678901234 70 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 * 5678901234567890
15:52:33.793 Rcvd Ether Dst 00:00:a8:43:52:22 Src 00:12:3f:82:57:10 Type 0800 +(IP) IP Ver/HL 45, ToS 8, Len 254, ID 2e87, Flg/Frg 2048, TTL 3f, Prtl 6 Cksum 13da, Src c0a86432, Dst a404d80 TCP from 192.168.100.50. to 10.64.77.128. *fragments*, 576 bytes data offset 0 . . . 4 . . . 8 . . . C . . . 0…4… 8…C… 0 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 * 1234567890123456 10 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 * 7890123456789012 20 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 * 3456789012345678 30 39 30 d a 31 32 33 34 35 36 37 38 39 30 31 32 * 90<<123456789012 40 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 * 3456789012345678 50 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 * 9012345678901234 60 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 * 5678901234567890 70 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 * 1234567890123456
15:52:33.793 Rcvd Ether Dst 00:00:a8:43:52:22 Src 00:12:3f:82:57:10 Type 0800 +(IP) IP Ver/HL 45, ToS 8, Len f8, ID 2e87, Flg/Frg 90, TTL 3f, Prtl 6 Cksum 34ee, Src c0a86432, Dst a404d80 TCP from 192.168.100.50. to 10.64.77.128. *fragments., 228 bytes data offset 0 . . . 4 . . . 8 . . . C . . . 0…4… 8…C… 0 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 * 5678901234567890 10 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 * 1234567890123456 20 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 * 7890123456789012 30 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 * 3456789012345678 40 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 * 9012345678901234 50 35 36 37 38 39 30 d a 31 32 33 34 35 36 37 38 * 567890<<12345678 60 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 * 9012345678901234 70 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 * 5678901234567890
增加MSS值的问题是,它会增加所有TCP连接的MSS值。你不能只增加一个或几个目的地的MSS值。因此,您需要仔细测试这一变化,以衡量其对所有连接的影响。
您可以通过以下两个命令查看当前的MSS值并进行更改。
analyze_system -request_line 'list_stcp_params min_mss' -quit
OpenVOS Release 17.0.1as, analyze_system Release 17.0.1as
Current process is 357, ptep 8FA86000, Noah_Davids.SysAdmin
maximum tcp segment size [500-1480] (min_mss) 556
ready 10:52:07
analyze_system -request_line 'set_stcp_param min_mss 1480' -quit
OpenVOS Release 17.0.1as, analyze_system Release 17.0.1as
Current process is 357, ptep 8FA86000, Noah_Davids.SysAdmin
Changing maximum tcp segment size (min_mss)
from 556 to 1480
ready 10:52:24
参数名称min_mss暗示了它是MSS值,但它实际上是MSS值加上20字节的TCP头长度。在上面的例子中,你可以将min_mss值设置为556+20或576。
那么增加MSS值能有多大的提升呢?由于VPN连接普遍会增加开销字节,我不建议设置最大值1480(实际TCP MSS为1460)。我建议用小一点的,比如1220(实际MSS 1200)字节。假设你使用536字节段发送10兆字节的数据将需要18657个帧,总的字节数--包括开销(8字节以太网前言+14字节以太网头+20字节IP头+20字节TCP头+4字节以太网预告片+有效的12字节以太网帧间空隙)将是11,455,246字节。如果你使用1200字节的段,将需要8334个帧,总字节数为10,650,052或略微超过9%。然而,请记住,MSS值是一个将被接受的最大段的广告,没有要求发送主机实际发送那么大的段。然而,假设它是这样做的,并且没有其他瓶颈,你只是在吞吐量上得到了9%的引导。
UDP那边能不能做什么?
UDP没有最大段大小的概念,所以没有参数来调整它。