Resumen

  • TCP conservaba un flujo ordenado, no los límites de una CALL o una REPLY; ONC RPC encerró cada mensaje en un registro formado por uno o más fragmentos.
  • Cada fragmento llevaba delante cuatro bytes en orden big-endian: 31 bits indicaban su longitud y el bit superior decía que el registro acababa después de esos datos.
  • El final permitía encuadrar, no certificar: XDR, XID, autenticación, autorización, resultado y efecto duradero seguían bajo controles distintos.

El receptor no podía fiarse del tamaño de la lectura

Una biblioteca solicita cuatro bytes y obtiene uno. No es una cabecera inválida, sino una cabecera incompleta. Debe conservarlo hasta reunir los otros tres. En la lectura siguiente quizá lleguen esos bytes, todo el cuerpo, dos registros adicionales y media cabecera más.

Este comportamiento es normal porque TCP no transmite las llamadas de la API como unidades. RFC 793 definió el servicio ordenado de octetos y negó que PUSH fuese un marcador de registros. RFC 9293 mantiene la noción de flujo fiable y ordenado. Los segmentos pueden cambiar; la secuencia debe permanecer.

RPC necesitaba conocer algo que TCP no prometía: dónde terminaba la representación de una petición o respuesta para que comenzara la siguiente. Por eso la respuesta debía estar encima del transporte.

Un entero guardó una cuenta y una decisión

RFC 1050 publicó record marking en abril de 1988. Un mensaje RPC ocupaba un registro RM, compuesto por uno o más fragmentos. RFC 1057, de junio del mismo año, conservó el diseño.

El marcador es una palabra sin signo de cuatro bytes, ordenada del byte más significativo al menos. Los 31 bits inferiores señalan cuántos bytes de datos contiene ese fragmento, desde cero hasta 2^31 - 1. El bit más alto vale uno si es el fragmento final del registro y cero si quedan más.

El orden de las operaciones evita un error sutil. Ver el bit final no autoriza a cerrar aún el registro: antes hay que consumir la longitud indicada. Completar un fragmento con bit cero tampoco autoriza a entregarlo como mensaje; lo siguiente será otro marcador del mismo registro.

La máquina de estados sobrevivía a cualquier partición TCP

El parser reúne cuatro bytes, separa bandera y longitud, y lee exactamente el cuerpo anunciado. Conserva los datos o los procesa bajo un presupuesto acumulado. Después consulta la bandera guardada.

Con cero vuelve a esperar otro marcador. Con uno declara completo un mensaje RPC y trata los bytes sobrantes como comienzo del registro siguiente. El mismo algoritmo funciona si un marcador cruza varios paquetes o si una lectura contiene muchos registros.

El intervalo de longitudes incluye un fragmento de cero bytes. Aunque no aporte cuerpo, la bandera sigue teniendo sentido. En cambio, el cierre de la conexión a mitad del cuerpo deja un fragmento truncado. No convierte lo recibido en un mensaje corto ni prueba que el procedimiento remoto no actuó.

El fragmento RM no viajaba solo

Un fragmento de record marking no es un fragmento IP ni un segmento TCP. Tampoco coincide necesariamente con una escritura del programa o con un valor XDR. Puede atravesar numerosos paquetes; varios fragmentos o registros pueden compartir un único paquete o buffer.

El bit final tampoco equivale a TCP FIN, PSH, fin de archivo o éxito. CALL y REPLY son mensajes diferentes y, sobre TCP, cada uno recibe su propio registro. Un record puede cerrar correctamente y contener una versión de programa desconocida, credenciales rechazadas o argumentos imposibles.

PUSH y RM resolvían preguntas distintas. PUSH pedía no retener bytes disponibles esperando más datos. RM decía cuántos bytes pertenecían a la unidad actual y si, después de ellos, el mensaje estaba completo. La urgencia no fabricaba sintaxis.

La envoltura quedó fuera de XDR

ONC RPC describe el interior mediante External Data Representation. RFC 4506 fija enteros, longitudes, relleno y tipos para que máquinas distintas interpreten la misma estructura.

Sin embargo, los RFC de RPC advierten que el marcador no está en forma XDR estándar. Comparte el orden de bytes de un entero, pero actúa antes del mensaje encerrado. El parser de flujo debe descubrir el contenedor antes de pedir a XDR que entienda el contenido.

Gracias a la separación, una longitud inaceptable puede rechazarse antes de interpretar el procedimiento. También puede existir un registro impecablemente encuadrado cuyo XDR sea inválido. Encontrar el final no valida lo encontrado.

El espacio numérico no era capacidad concedida

Los 31 bits limitan un fragmento, no el registro completo ni la memoria que el receptor debe reservar. Como hay varios fragmentos por registro, el formato no publica un máximo acumulado único. Una asignación ciega transforma una medida enviada por un desconocido en control remoto del heap.

El receptor necesita límites locales de bytes acumulados, cantidad de fragmentos, memoria simultánea y tiempo. Puede transmitir internamente o rechazar según el programa, pero debe registrar tanto la declaración recibida como el presupuesto aplicado. Estos límites son política operativa, no una reescritura de la norma.

La posibilidad de recuperación también tiene frontera. Los documentos dicen que delimitar ayuda a detectar y quizá recuperar errores, pero no definen la búsqueda del siguiente patrón plausible. Un cuerpo puede contener cualquier palabra de cuatro bytes. Tras perder el encuadre, cerrar la conexión puede evitar atribuir datos a la llamada equivocada.

La regla permaneció hasta que otro transporte la sustituyó

RFC 1831 mantuvo la forma en 1995. RFC 5531 la reemplazó en 2009 sin cambios sobre el cable. Su estabilidad procedía de una misión pequeña: reponer la frontera que el byte stream no conservaba.

RFC 8166 dibuja el límite posterior. RPC-over-RDMA lleva un transport stream y un payload stream y sustituye cualquier otro encuadre RPC, incluso TCP record marking cuando el RDMA subyacente utiliza TCP. Un cambio dinámico solo puede ocurrir entre mensajes RPC distintos y coordinado con el transporte.

Record marking no era, por tanto, una propiedad de la operación remota. Era un adaptador para transportar mensajes sobre un flujo concreto.

Fuentes y límites

El expediente cerrado incluye RFC 793, RFC 1050, RFC 1057, RFC 1831, RFC 4506, RFC 5531, RFC 8166 y RFC 9293. Demuestra formato, continuidad y límites de capa. No mide despliegue actual, no certifica productos y no demuestra identidad, permiso, contenido o resultado en una conexión real.

Los cuatro bytes resolvieron una disputa local con precisión. Dos pares podían dividir el flujo de maneras opuestas y aun así coincidir en el final del mensaje. La bandera nunca prometió que el efecto exterior hubiera acabado también.