¿Cómo es que la MTU es 65535 en UDP pero Ethernet no permite un tamaño de trama de más de 1500 bytes?


11

Estoy usando un ethernet rápido de 100 Mbps, cuyo tamaño de trama es inferior a 1500 bytes (1472 bytes para la carga útil según mi libro de texto). En eso, pude enviar y recibir un paquete UDP con un tamaño de mensaje de 65507 bytes, lo que significa que el tamaño del paquete era 65507 + 20 (Encabezado IP) + 8 (Encabezado UDP) = 65535.

Si el tamaño de la carga útil de la trama en sí es máximo de 1472 bytes (según mi libro de texto), ¿cómo puede el tamaño del paquete de IP ser mayor que el que aquí es 65535?

Usé el código del remitente como

char buffer[100000];
for (int i = 1; i < 100000; i++)
{
    int len = send (socket_id, buffer, i);
    printf("%d\n", len);
}

Código del receptor como

while (len = recv (socket_id, buffer, 100000))
{
     printf("%d\n". len);
}

Observé eso send returns -1en i > 65507e recvimprime o recibe un paquete de maximum of length 65507.

Respuestas:


11

Los datagramas UDP tienen poco que ver con el tamaño de MTU; puede hacerlos tan grandes como desee hasta que el máximo de 64K sea el mencionado anteriormente. Incluso puede enviar uno de ellos en un paquete completo siempre que utilice marcos jumbo con un tamaño mayor que el gran datagrama.

Sin embargo, los marcos gigantes deben ser compatibles con todo el equipo que el marco pasará y esto es un problema. Para fines prácticos, las tramas Ethernet son el tamaño de transporte más común, la MTU para estos es de alrededor de 1500 bytes, diré 1500 en adelante, pero no siempre es así. Cuando crea un datagrama UDP más grande que la MTU subyacente (que, como se indica, es a menudo ethernet), se dividirá silenciosamente en un número de marcos de 1500 bytes. Si activa este tráfico, verá una cantidad de paquetes rotos en el límite de MTU que tendrá la bandera de más fragmentos establecida junto con un número de fragmento. El primer paquete tendrá un número de fragmento de 0 y se establecerán más fragmentos y el último tendrá un número de fragmento distinto de cero y no se establecerán más fragmentos.

Entonces, ¿por qué importa? El detalle de implementación realmente importa. La fragmentación puede perjudicar el rendimiento en la red, ya no es un gran problema, sino uno a tener en cuenta. Si utilizó un gran tamaño de datagrama, en caso de que se pierda algún fragmento, será necesario reenviar todo el datagrama. Igualmente a grandes volúmenes y hoy en día estos son volúmenes perfectamente alcanzables, entonces es posible una asociación errónea de los fotogramas en el reensamblaje. También puede haber problemas para conseguir que los paquetes UDP fragmentados atraviesen configuraciones de firewall empresarial donde los equilibradores de carga distribuyen los paquetes, si un fragmento está en un firewall y el otro en otro diferente, el tráfico se caerá como incompleto.

Por lo tanto, no cree datagramas UDP más grandes que la fragmentación del tamaño de MTU a menos que tenga que hacerlo y si tiene que especificar que la infraestructura que se está comunicando está cerca (el mismo cierre de subred) en cuyo punto las tramas gigantes probablemente serían una buena opción.


Buena información sobre la 'bandera de más fragmentos'. ¿Es eso una bandera en el encabezado UDP o en el encabezado IP?
Juan Jesús

Nota: Algunos sistemas operativos NO transmitirán UDP si los datos se fragmentarán. By default, Linux UDP does path MTU (Maximum Transmission Unit) discovery. This means the kernel will keep track of the MTU to a specific target IP address and return EMSGSIZE when a UDP packet write exceeds it.
Documento de

2

La capa IP fragmentará su paquete en el extremo emisor y luego lo volverá a ensamblar en el extremo receptor antes de pasarlo a UDP. Desde la capa UDP, no se puede decir realmente que el paquete ha sido fragmentado. Si utiliza una herramienta de captura de paquetes como Wireshark , debería poder ver que su computadora recibe paquetes IP limitados a la MTU.


1

Resulta que permitir que la pila TCP / IP fragmente los paquetes según sea necesario es una sobrecarga mucho menor que el envío de paquetes individuales.


1
¿Quiere decir que TCP / IP se está fragmentando y volviendo a montar? En caso afirmativo, ¿por qué la gente dice todo el tiempo que su código debe encargarse del reensamblaje en el extremo del receptor? No observé fragmentación hasta ahora, pero había visto muchos foros que decían esto e incluso la gente lo aceptaba.

Para aquellos de nosotros que tenemos problemas con el modelo OSI, ¿podría agregar un poco más de detalle a su respuesta por favor?
Robert Harvey

Estaba siendo un poco cauteloso porque no puedo decir si esto es tarea o no. Es una compensación: dado que UDP no garantiza la entrega, si se descarta un fragmento de paquete, se pierde todo el paquete. Si desea un transporte confiable sobre UDP, debe manejar todo esto usted mismo; pero si está haciendo (digamos) protocolos de transmisión (o NFS sobre UDP, que tomó la ruta similar a la transmisión), es menor la sobrecarga para simplemente descartar esos paquetes o retransmitir el paquete más grande después de un retraso prolongado si es necesario. Debe equilibrar sus necesidades con las características del protocolo y la sobrecarga del protocolo.
geekosaur

1

UDP no sabe nada sobre MTU. Los paquetes UDP pueden tener cualquier tamaño de 8 a 65535 bytes. Las capas de protocolo debajo de UDP pueden enviar un paquete de un tamaño específico o rechazarán enviar ese paquete con un error si es demasiado grande.

La capa debajo de UDP suele ser IP, ya sea IPv4 o IPv6. Y el paquete IP puede tener cualquier tamaño desde 20 (IPv4) / 40 (IPv6) a 65535 bytes, es el mismo máximo que UDP. Sin embargo, IP admite un mecanismo llamado fragmentación . Si un paquete IP tiene un tamaño mayor que el que puede transportar la capa de abajo, IP puede dividir un paquete único en múltiples paquetes llamados fragmentos. De hecho, cada fragmento es un paquete de IP propio (tiene un encabezado de IP propio) y también se envía por sí solo al destino; es entonces la tarea del destino recopilar todos los fragmentos y reconstruir el paquete completo a partir de ellos antes de pasar los datos recibidos en la siguiente capa superior (por ejemplo, UDP).

El protocolo Ethernet solo puede transportar tramas con una carga útil entre 46 y 1500 bytes (hay excepciones, pero eso está fuera del alcance de esta respuesta). Si los datos de la carga útil son inferiores a 46 bytes, se rellenan para que sean 46 bytes. Si los datos de la carga útil superan los 1500 bytes, la interfaz se negará a aceptarlos. Si eso sucede, ahora depende de la capa IP decidir si fragmenta el paquete, de modo que ningún fragmento sea mayor de 1500 bytes o informe un error a la siguiente capa superior si la fragmentación se ha deshabilitado o prohibido para esta conexión en particular.

La fragmentación generalmente se debe evitar, ya que

  • Esto desperdicia recursos en el lado del remitente.
  • desperdicia recursos en el lado del receptor.
  • aumenta la sobrecarga del protocolo para la misma cantidad de datos de carga útil.
  • Si se pierde un solo fragmento, se pierde todo el paquete.
  • Si un solo fragmento está dañado, todo el paquete está dañado.
  • En caso de reenvío, todos los fragmentos deben reenviarse.

Es por eso que TCP adopta de manera inteligente su tamaño de trama para que los paquetes nunca requieran IP para fragmentarlos. Esto se puede hacer prohibiendo que IP fragmente los paquetes y si IP informa que un paquete es demasiado grande para ser enviado, TCP reduce el tamaño de la trama e intenta nuevamente, hasta que ya no se informa ningún error.

Sin embargo, para UDP, esta sería la tarea de la aplicación en sí misma, ya que UDP es un protocolo "tonto", no tiene lógica de administración propia, lo que lo hace muy flexible, rápido y simple.

El único tamaño UDP en el que puede confiar para que sea siempre transportable es 576 menos 8 bytes de encabezado UDP y menos 20 (v4) / 40 (v6) bytes de encabezado IP, ya que el estándar IP requiere que cada host IP pueda recibir paquetes IP con un tamaño total de 576 bytes. La implementación de su protocolo no sería estándar si no puede aceptar paquetes de al menos ese tamaño. Sin embargo, tenga en cuenta que el estándar no dice 576 sin fragmentación, por lo que incluso un paquete IP de 576 bytes puede fragmentarse entre dos hosts.

El único tamaño de paquete en el que puede confiar para que sea transportable sin fragmentación es 24 bytes para IPv4 y 56 bytes IPv6, ya que los encabezados IP más pequeños para un fragmento son 20/48 bytes (v4 / v6) y un fragmento debe tener al menos 4/8 bytes (v4 / v6) datos de carga útil. Por lo tanto, un sistema de transporte por debajo de la capa IP que no puede transportar al menos paquetes de estos tamaños, no puede utilizarse para transportar tráfico IP.

Y antes de que alguien comente que un encabezado IPv6 solo tiene 40 bytes: eso es correcto pero, a diferencia de un encabezado IPv4, un encabezado IPv6 estándar no tiene campos de encabezado para la fragmentación. Si un paquete tiene que fragmentarse, se debe agregar un encabezado de extensión de fragmentación debajo del encabezado base IPv6 y este encabezado de extensión tiene una longitud de 8 bytes. Además, a diferencia de IPv4, las compensaciones de fragmentación en IPv6 se cuentan en unidades de 8 bytes y no de 4 bytes, por lo que un fragmento solo puede transportar una carga útil que es un múltiplo de 8 bytes en el caso de IPv6.


0

Para responder a su pregunta, "Si el tamaño de la carga útil del marco en sí mismo es máximo de 1472 bytes (según mi libro de texto), ¿cómo puede el tamaño del paquete de IP ser mayor que el que aquí es 65535?"

Se debe a una función de descarga llamada UFO (Descarga de fragmentación UDP). Por favor, consulte este enlace.

Puede verificar y alternar las funciones de descarga a través de ethtool -k ethX y ethtool -K ethX respectivamente.


0

Si está monitoreando tramas salientes, es posible que su adaptador de red admita la descarga de segmentación y esté habilitado. Con la descarga de segmentación habilitada, la propia tarjeta de red maneja la segmentación del paquete / trama en el tamaño apropiado, en lugar de la pila de red. Esto libera la CPU en la computadora para realizar otras tareas, mejorando el rendimiento. En Linux, "ethtool -k [dispositivo]" mostrará las banderas de descarga.

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.