This article from http://www.cublog.cn/u3/92327/showart_2255574.html
MTU: Maximum Transmission unit of maxitum transmission unit
MSS: maxitum Segment Size Maximum Segment Size
The abbreviation of the Maximum Transmission size of MSS is a concept in TCP.
MSS is the maximum data segment that TCP data packets can transmit each time. To achieve optimal Transmission Performance, TCP usually needs to negotiate the MSS value of both parties when establishing a connection, this value is often replaced by the MTU value when the TCP protocol is implemented (the size of the IP packet header is reduced by 20 bytes and the packet header of the TCP data segment is 20 bytes ), both parties will determine the maximum MSS value for this connection based on the MSS value provided by both parties.
Generally, the MTU of Ethernet is 1500, so in Ethernet, the tcp mss is usually 1460.
The specific process of tcp mss negotiation is as follows:
The tcp client sends a SYN packet, where the option field is generally (MTU-IP header size-TCP Header size), after the TCP server receives the SYN packet, the SYN + ACK message is sent, and the option is filled with the MSS field (MTU-IP header size-TCP Header size ); both parties will compare the size of the MSS field in the SYN message and SYN + ACK message, and select a smaller MSS as the size of the TCP part to be sent.
For networks that involve pppoe + NAT, IPSec, L2TP, and GRE, clustering is usually required because the packet size is too large, which will reduce the transmission rate. Therefore, selecting an appropriate MSS is important for data transmission. in Linux, you can set tcp mss through netfilter iptables.
Iptables-a forward-p tcp--TCP-flags SYN, RST syn-J tcpmss -- clamp-MSS-to-PMTU
The purpose of this rule is to change tcp mss to adapt to PMTU (path MTU)
Iptables-a forward-p tcp -- TCP-flags SYN, RST syn-J tcpmss -- Set-MSS 128
Set MSS to 128
The following code modifies tcp mss in the kernel:
static inline u32 set_tcp_mss(struct sk_buff *pskb, struct tcphdr *tcph, u16 mtu) { u32 optlen, i; u8 *op; u16 newmss, oldmss; u8 *mss;
if ( !tcph->syn ) return 0;
// Determine whether the TCP option is valid
If (tcph-> doff * 4 <sizeof (struct tcphdr )) Return 0;
optlen = tcph->doff*4 - sizeof(struct tcphdr); if (!optlen) return 0;
// Scan for MSS options
OP = (u8 *) tcph + sizeof (struct tcphdr )); For (I = 0; I <optlen ;){ If (OP [I] = tcpopt_mss & (Optlen-I)> = tcpolen_mss & OP [I + 1] = tcpolen_mss ){ B2mssval;
// Newmss = htons (1356 );
Oldmss = (OP [I + 3] <8) | op [I + 2]; Mssval = (OP [I + 2] <8) | op [I + 3];
// Whether the value is smaller than Mtu-(iphdr + tcphdr)
If (mssval> Mtu-40 ){ Newmss = htons (MTU-52 ); } Else { Break; } //
MSS = & newmss; OP [I + 2] = newmss & 0xff; OP [I + 3] = (newmss & 0xff00)> 8; // Calculate the checksum
Inet_proto_csum_replace2 (& tcph-> check, pskb, Oldmss, newmss, 0 );
Mssval = (OP [I + 2] <8) | op [I + 3]; Dprintf ("Change tcp mss % d to % d/N", ntohs (oldmss), mssval ); Break;
} If (OP [I] <2) I ++; Else I + = op [I + 1]? : 1; } Return 0; }
|
Windows can use a tool to modify the drtcp http://www.dslreports.com/drtcp