TCP/IP协议:最大报文段长度(MSS)是如何确定的(3)

来源:互联网 发布:iphone录制屏幕软件 编辑:程序博客网 时间:2024/06/05 08:48

一.实际使用中的问题

用户在使用路由器访问Internet时,经常会反馈不能访问网页(或部分网页)以及使用Outlook收发邮件(这些应用是基于TCP或UDP的),但进行Ping包时没有问题,这时候检查配置时也没有错误。出现这种情况的时候,多半是因为在设备上进行了NAT应用,同时设备对报文进行了分片操作。

(没有支持路径MTU;设备没有参与MSS协商;结果TCP协商的MSS大于了设备的MTU-TCP头部-IP头部)

IP报文里是有五元组的,但报文要进行分片时,只有第一片报文带有IP的五元组信息(源目的ip位址,源目的端口号,协议号),后续的分片不会保留TCP/UDP报文所有的标识信息,如端口号信息等,这种情况下,如果设备又实现了NAT转换操作(NAT转换过程中,会随机地做埠转换),并且应用又是基于TCP/UDP的,这就导致报文不能正确组包,会出现上述的问题现象。

(不是所有TCP报文都指定IP报文不分片,特殊报文会指定,比如路径MTU发现机制)

TCP/IP连接时建立的过程中会协商很多参数的,其中TCP MSS参数就是用于协商TCP报文大小的,如果协商出来的TCP MSS的参数值小于设备的MTU的值时,TCP报文在设备上就不会被分片,否则就会出现报文分片并导致上述现象的发生,因此,为了避免上述情况的发生,一定要保证协商的TCP MSS参数小于设备的MTU的值。为此,Quidway路由器上有一个设置TCP MSS值的命令,如果配置了这条命令,路由器设备在建立TCP/IP连接的过程中就按照这个配置的值来修改协商报文中关于TCP MSS的值,在同对端协商的过程中也就能够协商出这个值来,如果不配置这条命令,路由器设备就不会修改报文中的这个值(有时对端设备发送过来的协商报文中的这个值会很大,如8000)。一般来说,默认或配置的MTU的值一般在1500左右,将TCP MSS的值设备为小于1500就可以,如1400或1024等。

如果TCP MSS值设置的过小,报文数量明显增多又导致效率下降,特别是没有配置NAT应用的情况下,限制TCP报文大小更没有必要,由于应用情况比较复杂,设置默认的TCP MSS的值也不是特别合适(设备会在建立连接时均要修改TCP MSS的值),因此,还是在应用中加以注意比较好,思科设备也是有这个配置命令的。

MTU: Maxitum Transmission Unit 最大传输单元

MSS: Maxitum Segment Size 最大分段大小

MSS最大传输大小的缩写,是TCP协议里面的一个概念。
MSS就是TCP数据包每次能够传输的最大数据分段。为了达到最佳的传输效能TCP协议在建立连接的时候通常要协商双方的MSS值,这个值TCP协议在实现的时候往往用MTU值代替(需要减去IP数据包包头的大小20Bytes和TCP数据段的包头20Bytes), 通讯双方会根据双方提供的MSS值得最小值确定为这次连接的最大MSS值。

而一般以太网MTU都为1500, 所以在以太网中, 往往TCP MSS为1460。

协商TCP MSS大小具体过程如下:
TCP client发出SYN报文,其中option选项填充的MSS字段一般为(MTU-IP头大小-TCP头大小),同样TCP server收到SYN报文后,会发送SYN+ACK报文应答,option选项填充的mss字段也为(MTU-IP头大小-TCP头大小);协商双方会比较SYN和SYN+ACK报文中MSS字段大小,选择较小的MSS作为发送TCP分片的大小。

对于涉及PPPOE+NAT、IPsec、L2TP、GRE等组网,通常由于报文太大需要分片,这样会降低传输速率; 所以选择一个合适的MSS对传输数据来说比较重要. linux中一般可以通过netfilter iptables设置TCP MSS来解决。

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

这条规则的目的就是改变TCP MSS以适应PMTU(Path MTU)

iptables -A FORWARD -p tcp --tcp-flags SYN,RST SYN- j TCPMSS --set-mss 128

设置MSS为128

1)Linux主机接口MTU可通过如下命令设置

ifconfig mtu

2)PPPoE MTU设置,可以通过在配置文件中添加

mtu

mru

3)NAT自动设置MSS值

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

二.路径发现MTU机制

当在同一个网络上的两台主机互相进行通信时,该网络的M T U是非常重要的。但是如果两台主机之间的通信要通过多个网络,那么每个网络的链路层就可能有不同的M T U。重要的不是两台主机所在网络的M T U的值,重要的是两台通信主机路径中的最小M T U。它被称作路径M T U。
两台主机之间的路径M T U不一定是个常数。它取决于当时所选择的路由。而选路不一定是对称的(从A到B的路由可能与从B到A的路由不同),因此路径M T U在两个方向上不一定是一致的。RFC 1191[Mogul and Deering 1990]描述了路径M T U的发现机制,即在任何时候确定路径M T U的方法。

当前的大多数IP主机都支持使用路径MTU发现机制,这种机制使得IP主机能够动态的发现从源主机到目的主机的路径上运行的最小MTU长度。

路径MTU发现的基本思想是源主机最初假设到目的主机的路径MTU为源主机发送这个报文的第一跳接口的MTU,并把发送到主机的所有IP报文的IP头中的DF位置一。在这个转发路径中的某个路由器收到某个报文,要从某个出接口出去的时候发现该报文大于出接口的MTU,并且其FD位4为1,该路由器将会丢弃本报文,并且返回一个ICMP目的地址不可达报文通知被丢弃报文的源主机,源主机收到这个ICMP报文后就减小假定的这条路径上的PMTU值。

如果网络中的每台设备都遵守上述机制,发送报文的主机发出的报文在整个路径上不用分片就可以到达目的主机了。但是实际的情况,有一些主机不适用路径MTU发现机制,并且发送1500字节DF位为1的IP报文,另外一些防火墙会过滤掉ICMP不可达报文,这就破坏了路径MTU发现机制。

两台主机之间的路径MTU不一定是个常数。它取决于但是所选择的路由。而选路不一定是对称的(从A到B的路由可能与从B到A的路由不同),因此路径MTU在两个方向上不一定是一致的。就是说通一台主机的路径MTU在入和出方向上是不同的。

三.什么是MSS

最大报文段长度表示TCP传往另一端的最大块数据的长度。当一个连接建立时,连接的双方都要通告各自的MSS。它是一个可“协商”选项,当建立一个连接是,每一方都有用于通告它期望接收的MSS选项。而且在协商过后,该选项内容可以改变,也可以没有。在协商MSS时,一般是建立TCP连接的两端发送【SYN】标志报文时互相通报,然后选取最小MSS作为双方的约定。如果双方都不通报,或有一方不通报,一般选择MSS的默认值536.

一般说来,如果没有分段发送,MSS还是越大越好。报文段越大允许每个报文段传送的数据就越多,相对IP和TCP首部有更高的网络利用率。当TCP发送一个SYN时,或者是因为一个本地应用进程想发起一个连接,或者是因为另一端的主机收到了一个连接请求,它能将MSS值设置为外出接口上的MTU长度减去固定的IP首部和TCP首部长度。对于一个以太网,MSS值可达1460字节。

四.TCP/IP协议 路径MTU发现

T C P的路径M T U发现按如下方式进行:在连接建立时, T C P使用输出接口或对端声明的M S S中的最小M T U作为起始的报文段大小。路径M T U发现不允许T C P超过对端声明的M S S。如果对端没有指定一个M S S,则默认为5 3 6。

一旦选定了起始的报文段大小,在该连接上的所有被T C P发送的I P数据报都将被设置D F比特。如果某个中间路由器需要对一个设置了D F标志的数据报进行分片,它就丢弃这个数据报,并产生一个我们在11 . 6节介绍的I C M P的“不能分片”差错。如果收到这个I C M P差错, T C P就减少段大小并进行重传。如果路由器产生的是一个较新的该类I C M P差错,则报文段大小被设置为下一跳的M T U减去I P和T C P的首部长度。如果是一个较旧的该类I C M P差错,则必须尝试下一个可能的最小M T U(见图2 - 5)。当由这个I C M P差错引起的重传发生时,拥塞窗口不需要变化,但要启动慢启动。由于路由可以动态变化,因此在最后一次减少路径M T U的一段时间以后,可以尝试使用一个较大的值(直到等于对端声明的M S S或输出接口M T U的最小值)。RFC 11 9 1推荐这个时间间隔为1 0分钟(Solaris 2.2使用一个3 0分钟的时间间隔)。在对非本地目的地,默认的M S S通常为5 3 6字节,路径M T U发现可以避免在通过M T U小于5 7 6(这非常罕见)的中间链路时进行分片。对于本地目的主机,也可以避免在中间链路(如以太网)的M T U小于端点网络(如令牌环网)的情况下进行分片。但为了能使路径M T U更加有用和充分利用M T U大于5 7 6的广域网,一个实现必须停止使用为非本地目的制定的5 3 6的M T U默认值。M S S的一个较好的选择是输出接口的M T U(当然要减去I P和T C P的首部大小)
(大多数的实现都允许系统管理员改变这个默认的M S S值,一些操作系统针对非本地目的地址使用默认值)。

TCP/IP协议卷1中:涉及B S D / 3 8 6和S V R 4的M S S为1 0 2 4,这是因为许多B S D的实现版本需要M S S为5 1 2的倍数。其他的系统,如SunOS 4.1.3、Solaris 2.2 和AIX 3.2.2,当双方都在一个本地以太网上时都规定M S S为1 4 6 0。[Mogul 1993] 的比较显示了在以太网上1 4 6 0的M S S在性能上比1 0 2 4的M S S更好。如果目的I P地址为“非本地的( n o n l o c a l )”,M S S通常的默认值为5 3 6。而区分地址是本地还是非本地是简单的,如果目的I P地址的网络号与子网号都和我们的相同,则是本地的;如果目的I P地址的网络号与我们的完全不同,则是非本地的;如果目的I P地址的网络号与我们的相同而子网号与我们的不同,则可能是本地的,也可能是非本地的。大多数T C P实现版都提供了一个配置选项(附录E和图E - 1),让系统管理员说明不同的子网是属于本地还是非本地。这个选项的设置将确定M S S可以选择尽可能的大(达到外出接口的M T U长度)或是默认值5 3 6。

(现在TCP实现上针对非本地目的地址不使用默认MTU 576,使用输出接口的MTU)

支持路径发现机制的主机,发送的TCP报文都指定DF位置1.一旦防火墙过滤到ICMP报文,路径MTU发现机制就废了。




0 0
原创粉丝点击