Resumen

  • RFC 768 dio dos significados distintos al cero del campo checksum de UDP: un resultado calculado cero se transmitía como 0xFFFF, mientras que 0x0000 indicaba que no se había generado checksum.
  • Los requisitos para hosts de 1989 mantuvieron la posibilidad de omitirlo, pero dejaron el cálculo activado por defecto. IPv6 lo hizo obligatorio y, en 2013, una actualización permitió un caso de túnel muy acotado.

Dos ceros en un solo campo

En agosto de 1980, RFC 768, escrito por Jon Postel, definió el User Datagram Protocol para que las aplicaciones intercambiaran datagramas con el mínimo de mecanismos. UDP no prometía entrega ordenada, protección contra duplicados ni fiabilidad. Su cabecera ocupaba solo ocho octetos: puerto de origen, puerto de destino, longitud y checksum, seguidos por los datos.

El último campo parece sencillo hasta que la aritmética le plantea un caso especial. UDP usa el checksum de complemento a uno de 16 bits, también empleado por TCP. El cálculo abarca la cabecera UDP y los datos, además de una pseudocabecera con las direcciones IP de origen y destino, el número de protocolo y la longitud UDP. Postel explicó que la pseudocabecera ayudaba a proteger contra datagramas mal encaminados.

En complemento a uno, el cero tiene dos representaciones: todos los bits en cero y todos los bits en uno. RFC 768 asignó funciones distintas a esas dos formas en la red. Si el cálculo daba cero, el emisor debía transmitir todos los bits en uno. En cambio, un campo transmitido con todos los bits en cero indicaba que no se había generado checksum. El formato llevaba así tanto un resultado como una pequeña señal de estado, sin añadir un bit de bandera.

Ese es el punto histórico preciso de este artículo. Un checksum UDP cero no era un checksum calculado cuyo resultado fuese cero. Codificaba una ausencia. Confundir ambos estados podía hacer que una implementación descartara un datagrama válido o tratara la falta de detección de errores como si fuera una verificación satisfactoria.

Que fuera opcional no lo hacía predeterminado

La especificación original permitía omitir el checksum, por ejemplo para depuración o cuando a un protocolo de nivel superior no le importaba. Nueve años después, RFC 1122, sobre los requisitos de los hosts de Internet, aclaró la regla operativa. Un host debía implementar la generación y validación del checksum; una aplicación podía controlar su generación, pero debía estar activada por defecto. Los receptores podían elegir si entregaban datagramas sin checksum a las aplicaciones.

RFC 1122 también señaló un error de implementación habitual: un resultado calculado cero debe transmitirse como 65535, mientras que el campo totalmente a cero significa “ausente”. El documento informó de que algunas aplicaciones usadas solo en redes de área local habían desactivado el checksum por eficiencia y de que se habían notificado numerosos errores no detectados. No proporcionó cifras, incidentes identificados ni denominador. Es evidencia de una preocupación de los autores de estándares, no una medición de su prevalencia.

El checksum nunca fue una firma. Su pseudocabecera podía detectar ciertos errores de entrega y el cálculo podía detectar parte de la corrupción accidental. No autenticaba al emisor, no impedía una modificación deliberada ni demostraba que los datos de la aplicación fueran correctos. “Checksum presente” y “paquete confiable” eran afirmaciones distintas.

IPv6 estrechó el límite

La especificación IPv6 de 1998, RFC 2460, hizo obligatorio el checksum UDP. Si el resultado calculado era cero, también debía escribirse como 0xFFFF; el receptor debía descartar un datagrama UDP IPv6 cuyo campo checksum fuese cero. Así, el marcador opcional de ausencia dejó de ser aceptable en el tráfico UDP IPv6 ordinario.

La regla se encontró después con un caso de rendimiento específico. En 2013, RFC 6935 y RFC 6936 actualizaron el comportamiento de IPv6 para ciertos túneles UDP. Esos túneles podían transportar paquetes que ya tenían controles de integridad propios, y calcular un checksum externo podía tener un coste. La excepción dependía de condiciones de aplicabilidad, del comportamiento de ambos extremos y de la compatibilidad de los equipos intermedios; no convirtió el checksum cero en una opción general para IPv6.

La secuencia de estándares muestra que el patrón de bits no cambió, pero sí el contexto permitido. En IPv4, cero podía indicar ausencia, con el cálculo activado por defecto según los requisitos de los hosts. En IPv6, esa ausencia se rechazó al principio y luego se permitió de forma limitada para un papel concreto de encapsulación externa. El valor por sí solo nunca decía al receptor si la omisión era aceptable. Importaban la versión IP y el contexto de uso.

Fuentes