IMPORTANT: Per accedir als fitxer de subversion: http://acacha.org/svn (sense password). Poc a poc s'aniran migrant els enllaços. Encara però funciona el subversion de la farga però no se sap fins quan... (usuari: prova i la paraula de pas 123456)

Introducció

El maximum segment size (aka MSS) és un paràmetre del protocol TCP que especifica la mida màxima de dades TCP (en bytes) que un ordinador o dispositiu de comunicacions pot transportar en un sol paquet IP i per tant que pot transmetre sense fragmentar. Fixeu-vos que parlem de dades, per tant no s'inclouen les capçaleres.

NOTA: Vegeu la wiki Fragmentació per més detalls sobre aquest efecte. Vegeu també Encapsulació

The TCP MSS value specifies the maximum amount of TCP data in a single IP datagram that the local system can accept (reassemble). The IP datagram can be fragmented into multiple packets when sent. Theoretically, this value can be as large as 65495, but such a large value is never used. Typically, an end system uses the "outgoing interface MTU" minus 40 as its reported MSS. For example, an Ethernet MSS value is 1460 (1500 - 40 = 1460).


NOTA: Observeu l'ús especific de la paraula segment, per entendre'ns un "paquet TCP" , que és similar al concepte paquet en protocol IP

Per sota de TCP està IP, i per tant al indicar la mida màxima del paquet TCP també estem indicant la mida màxima del paquet IP.

Per contar el MSS no es conta ni la mida del TCP header, ni la mida del IP header

The IP datagram containing a TCP segment may be self-contained within a single packet, or it may be reconstructed from several fragmented pieces; either way, the MSS limit applies to the total amount of data contained within the final reconstructed TCP segment.

Cal tenir en compte la següent formula:

Headers + MSSMTU

Per evitar la Fragmentació el nombre màxim de MSS ha de ser:

Màxim MSS per evitar fragmentació = mida màxima del datagrama sense tenir que reagrupar paquets - IP header size - TCP header size

La majoria de hosts IPv4 requereixen ser capaços de gestionar un MSS de 536 octets:

536 = 576 - 20 - 20

i els hosts IPv6

1220 = 1280 - 40 - 20

Un MSS inferior assegura que no hi haguí Fragmentació en cap punt del camí pel que passa el paquet, però en canvi el ratio data/header serà inferior.

El valor de MSS normalment l'estableix el sistema operatiu mitjançant el paquet SYN del TCP handshake. Cada direcció del fluxe de dades pot utilitzar un MSS diferent.

Recursos:

Com seleccionar el valor de Maximum Segment Size?

El protocol TCP estàndard original (RFC 793) no discuteix gaire el valor MSS i això va provocar confusió. Posteriorment el RFC 879 es va publicar un parell d'anys més tard per aclarir aquest valor i els problemes al seu voltant. Alguns problemes són bastant mundans com per exemple el fet de que alguns dispositius estan limitats en la memòria buffer que tenen per als segments TCP i per aquesta raó han de treballar amb valors baixos de MSS.

La selecció del valor de MSS no és una llei exacte ja que cal un compromís entre:

  • Overhead Management: El TCP header ocupa 20 bytes com a mínim ( pot utilitzar més amb opcions); el IP header ocupa 20 bytes més. Si posem un valor de MSS molt petit (per exemple de 40) aleshores hi ha un ús molt ineficient de l'ampla de banda. Amb l'exemple de 40 estariem desaprofitant el 50% de l'ampla de banda.
  • IP Fragmentation: Els segments TCP s'han de transportar o han de ser "empaquetats" en paquets IP (aka datagrames IP). Els datagrames IP tenen el seu propi límit en la mida màxima del paquet. A la capçalera IP el camp Total Length indica la mida del paquet IP en bytes i per tant la mida màxima teòrica és de 65535 bytes. Cal però tenir en compte el maximum transmission unit (MTU) i el valor típic de MTU 1500, ja que si un segment TCP és massa gran aleshores apareixerà la fragmentació. La fragmentació redueix la eficiència i augmenta la possibilitat d'haver de retransmetre els paquets, ja que si es perd un sol fragment cap reenviar tot el paquet TCP de nou.

Valor per defecte ( TCP Default Maximum Segment Size)

La solució ha estat buscar un valor per defecte de compromís. Aquest valor es computa a partir del valor mínim de MTU per a xarxes IP, que és de 576 (IPv4). Totes les xarxes IPv4 estan obligades a gestionar un paquet IP d'aquesta mida sense fragmentació IP. D'aquest número calculem el MSS restant els 20 bytes de la capçalera IP i els 20 bytes de la capçalera TCP:

MSS = 536 bytes

Aquest és valor l'estàndard del MSS per a TCP amb IPv4. Amb IPv6:

1220 = 1280 - 40 - 20

És un valor de compromís. Si s'utilitza aquest valor la majoria de paquets IP passen sense Fragmentació en xarxes IP com Internet. Cal tenir en compte que si s'utilitzen opcions TCP o IP i les capçaleres són més gran aleshores hi ha fragmentació, però no és el més habitual.

Tot i així té més sentit permetre segments que acabaran sent fragmentats, que no pas utilitzar un valor més petit de MSS. Per exemple un valor de 400, segurament mai hi haurà fragmentació per el data/header ratio passa de :

536:40 (93% data aprox) 

a

400:40 (90% data aprox)

Per a tots els segments.

iptables

> iptables -nvL -t filter
...
Chain FORWARD (policy ACCEPT 18100 packets, 1796K bytes)
pkts bytes target     prot opt in     out     source               destination         
   0     0 TCPMSS     tcp  --  ppp0_1 *       0.0.0.0/0            0.0.0.0/0           tcp flags:0x06/0x02 TCPMSS set 1452 
   0     0 TCPMSS     tcp  --  *      ppp0_1  0.0.0.0/0            0.0.0.0/0           tcp flags:0x06/0x02 TCPMSS set 1452 
   0     0 TCPMSS     tcp  --  ppp0_1 *       0.0.0.0/0            0.0.0.0/0           tcp flags:0x06/0x02 TCPMSS set 1452 
   0     0 TCPMSS     tcp  --  *      ppp0_1  0.0.0.0/0            0.0.0.0/0           tcp flags:0x06/0x02 TCPMSS set 1452 
   0     0 ACCEPT     all  --  ppp0_1 *       0.0.0.0/0            0.0.0.0/0           state RELATED,ESTABLISHED 
   0     0 LOG        tcp  --  ppp0_1 *       0.0.0.0/0            0.0.0.0/0           tcp flags:0x17/0x02 limit: avg 6/hour burst 5 LOG flags 0 level 1 prefix `Intrusion -> ' 
   0     0 DROP       all  --  ppp0_1 *       0.0.0.0/0            0.0.0.0/0           

Del manual:

$ man iptables
...
   TCPMSS
      This  target allows to alter the MSS value of TCP SYN packets, to control the maximum size for that connection (usually limiting it to your outgoing
      interface's MTU minus 40 for IPv4 or 60 for IPv6, respectively).  Of course, it can only be used in conjunction with -p tcp.

      This target is used to overcome criminally braindead ISPs or servers which block "ICMP Fragmentation Needed" or "ICMPv6  Packet  Too  Big"  packets.
      The  symptoms  of this problem are that everything works fine from your Linux firewall/router, but machines behind it can never exchange large pack‐
      ets:
       1) Web browsers connect, then hang with no data received.
       2) Small mail works fine, but large emails hang.
       3) ssh works fine, but scp hangs after initial handshaking.
      Workaround: activate this option and add a rule to your firewall configuration like:

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

      --set-mss value
             Explicitly sets MSS option to specified value. If the MSS of the packet is already lower than value, it will not  be  increased  (from  Linux
             2.6.25 onwards) to avoid more problems with hosts relying on a proper MSS.

      --clamp-mss-to-pmtu
             Automatically  clamp MSS value to (path_MTU - 40 for IPv4; -60 for IPv6).  This may not function as desired where asymmetric routes with dif‐
             fering path MTU exist — the kernel uses the path MTU which it would use to send  packets  from  itself  to  the  source  and  destination  IP
             addresses. Prior to Linux 2.6.25, only the path MTU to the destination IP address was considered by this option; subsequent kernels also con‐
             sider the path MTU to the source IP address.

      These options are mutually exclusive.


Vegeu també

Enllaços externs