TCP MSS mínimo en Linux


9

El TCP MSS en Linux debe tener al menos 88 (incluir / net / tcp.h):

/* Minimal accepted MSS. It is (60+60+8) - (20+20). */
#define TCP_MIN_MSS             88U

Mi pregunta es: ¿dónde se les ocurrió "60 + 60 + 8" y por qué? Entiendo que 20 + 20 proviene del encabezado IP + encabezado TCP.

EDITAR: después de mirar más de cerca los encabezados, la fórmula me busca así:

(MAX_IP_HDR + MAX_TCP_HDR + MIN_IP_FRAG) - (MIN_IP_HDR + MIN_TCP_HDR)

La pregunta sigue en pie: ¿por qué ? ¿Por qué el kernel de Linux utiliza esta fórmula, prohibiendo (un flujo forzado de) segmentos TCP de, digamos, 20 bytes? Piensa iperf aquí.

EDIT2: Aquí está mi caso de uso. Al forzar un MSS bajo en el socket / conexión, todos los paquetes enviados por la pila tendrán un tamaño pequeño. Quiero establecer un MSS bajo cuando trabajo con iperf para paquetes / segunda prueba. ¡No puedo obtener paquetes IP de menos de 128 bytes (tramas Ethernet de 142 bytes) en el cable debido a este límite inferior para el MSS! Me gustaría acercarme al tamaño de trama de Ethernet de 64 bytes según RFC 2544. Teóricamente esto debería ser posible: 18 + 20 + 20 <64.


¿Cómo prohíbe esto los segmentos TCP de 20 bytes?
David Schwartz

MSS significa Tamaño máximo de segmento, es el límite superior (no inferior) para el tamaño de segmento en una conexión particular. TCP_MIN_MSS especifica el límite inferior para este límite. Por lo tanto, no prohíbe de ninguna manera los segmentos con menos de 88 bytes, solo establece que el MSS para cualquier conexión debe ser> = 88 bytes.
gelraen

¡Por supuesto! Perdón por no ser lo suficientemente claro. Por favor vea la última edición.
Mircea Gherzan

¿Por qué dejaste expirar la recompensa? La respuesta de David aclara las cosas al menos para mi satisfacción. La diferencia entre su respuesta y la mía es que estamos hablando de mínimos diferentes. Para lo que vale, hay un tercer mínimo, que es 41, o 20 + 20 + 1 byte de datos TCP. Por lo tanto, el tamaño mínimo del paquete depende de la razón por la que lo solicita. Espero que 68 sea la respuesta correcta en los casos en que el núcleo usa TCP_MIN_MSS.
Warren Young

Todavía no estoy satisfecho con la respuesta. Todavía no veo la razón por la cual el kernel no me permite imponer un pequeño MSS a una aplicación. Me encantaría tener (un flujo constante de carga de TCP) paquetes IP de 41 bytes, pero no puedo, debido a TCP_MIN_MSS. ¿Por qué no puede ser 1? ¿Qué RFC se rompería? ¿Qué problema teórico / práctico causaría? ¿Estás seguro de que está "fuera de las especificaciones"? ¿"Mínimos diferentes"? Aquí solo hay un mínimo de interés: el MSS más pequeño permitido por el núcleo.
Mircea Gherzan

Respuestas:


5

Se requiere una implementación para admitir los encabezados TCP e IP de tamaño máximo, que son 60 bytes cada uno.

Una implementación debe admitir datagramas de 576 bytes, que incluso con encabezados máximos significa más de 8 bytes de datos en el datagrama. Para enviar datagramas con más de 8 bytes de datos, la fragmentación de IP debe colocar al menos 8 bytes de datos en al menos uno de los paquetes que representan los fragmentos del datagrama. Por lo tanto, una implementación debe admitir al menos 8 bytes de datos en un paquete.

En conjunto, una implementación debe admitir paquetes de 60 + 60 + 8 bytes.

Cuando enviamos paquetes que forman parte de una secuencia TCP, tienen un encabezado IP de 20 bytes (más opciones) y un encabezado TCP de 20 bytes (más opciones). Eso deja un mínimo de (60 + 60 + 8) - (20 + 20) bytes restantes para datos y opciones. Por lo tanto, este es el máximo que podemos asumir con seguridad el TCP MSS de una implementación.


1
Sin embargo, el MSS no incluye el encabezado (es solo la carga útil), y 60aparece dos veces
Michael Mrozek

Una implementación debe ser compatible con un paquete con un encabezado de tamaño máximo, pero no enviamos un encabezado de tamaño máximo. Por lo tanto, la diferencia entre el máximo y lo que realmente enviamos está disponible para datos y debe agregarse al MSS.
David Schwartz el

OK, entonces has explicado los 8 bytes. No sé qué quieres decir con encabezado "TCP / IP". Sé de un encabezado IP y uno TCP. Y, como señaló Michael, 60 aparece dos veces. Y el RFC solo discute el "MSS efectivo" y no uno mínimo.
Mircea Gherzan

60 aparece dos veces, una para el encabezado IP y otra para el encabezado TCP.
David Schwartz

68 es solo sobre fragmentación. "60 + 60 + 8" podría fragmentarse, entonces, ¿por qué preocuparse por la fragmentación? Incluso "68 + 20" podría fragmentarse. ¿Y por qué "debe" la otra parte "aceptar" "60 + 60 + 8"? "Aceptar" como en "sin fragmentación"? En pocas palabras: ¿por qué no puedo enviar "20 + 20" + 10 bytes de datos?
Mircea Gherzan

3

No sé de dónde viene ese número, pero puedo decirte que está fuera de la especificación. La MTU mínima admitida para redes IP es de 576 bytes, que son 512 bytes de datos más hasta 64 bytes para encabezados IP + TCP y opciones de TCP. Ese valor fue elegido para dar una sobrecarga decentemente baja en el caso típico.

Mi lectura de bits de código del núcleo sugiere que el valor que está mostrando no es arbitrario. Había una práctica más antigua para usar la constante sin procesar 64 en lugar de TCP_MIN_MSS. Por lo tanto, supongo que hay una extraña red de IP sobre Foo con la que se encontraron los desarrolladores del kernel que les hizo decidir que podrían aumentar el valor de lo que ves.

Sin embargo, no puedo decir cuál es ese tipo de red no estándar.


576 es la MTU para datagramas . En este caso, lo que importa son los límites de los paquetes, no los límites de los datagramas porque los paquetes TCP establecen el bit DF.
David Schwartz

MTU mínimo definido para datagramas IP, y los paquetes TCP también son datagramas IP.
gelraen

Correcto, pero esta limitación TCP es para paquetes, no datagramas, porque los datagramas TCP nunca (normalmente) se fragmentan. El único sentido en el que importa la regla del datagrama de 576 bytes es que significa que la implementación debe ser capaz de soportar al menos 8 bytes de datos en un paquete (de ahí el 8 en la fórmula). De lo contrario, sería imposible fragmentar un datagrama de 576 bytes.
David Schwartz
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.