Entonces, he leído mucha información sobre datos auxiliares de flujo de Unix, pero una cosa que falta en toda la documentación es ¿qué se supone que sucederá cuando hay una lectura parcial?
Supongamos que estoy recibiendo los siguientes mensajes en un búfer de 24 bytes
msg1 [20 byes] (no ancillary data)
msg2 [7 bytes] (2 file descriptors)
msg3 [7 bytes] (1 file descriptor)
msg4 [10 bytes] (no ancillary data)
msg5 [7 bytes] (5 file descriptors)
La primera llamada a recvmsg, obtengo todo msg1 (¿y parte de msg2? ¿El sistema operativo lo hará alguna vez?) Si obtengo parte de msg2, ¿obtengo los datos auxiliares de inmediato y necesito guardarlos para la próxima lectura? cuando sé lo que el mensaje realmente me decía que hiciera con los datos? Si libero los 20 bytes de msg1 y luego llamo a recvmsg nuevamente, ¿entregará alguna vez msg3 y msg4 al mismo tiempo? ¿Los datos auxiliares de msg3 y msg4 se concatenan en la estructura del mensaje de control?
Si bien podría escribir programas de prueba para descubrir esto experimentalmente, estoy buscando documentación sobre cómo se comportan los datos auxiliares en un contexto de transmisión. Parece extraño que no pueda encontrar nada oficial en él.
Voy a agregar mis hallazgos experimentales aquí, que obtuve de este programa de prueba:
https://github.com/nrdvana/daemonproxy/blob/master/src/ancillary_test.c
Linux 3.2.59, 3.17.6
Parece que Linux agregará porciones de mensajes con soporte auxiliar al final de otros mensajes siempre y cuando no sea necesario entregar una carga útil auxiliar anterior durante esta llamada a recvmsg. Una vez que se entregan los datos auxiliares de un mensaje, devolverá una lectura breve en lugar de comenzar el siguiente mensaje de datos auxiliares. Entonces, en el ejemplo anterior, las lecturas que obtengo son:
recv1: [24 bytes] (msg1 + partial msg2 with msg2's 2 file descriptors)
recv2: [10 bytes] (remainder of msg2 + msg3 with msg3's 1 file descriptor)
recv3: [17 bytes] (msg4 + msg5 with msg5's 5 file descriptors)
recv4: [0 bytes]
BSD 4.4, 10.0
BSD proporciona más alineación que Linux y ofrece una lectura breve inmediatamente antes del inicio de un mensaje con datos auxiliares. Pero, felizmente agregará un mensaje no auxiliar al final de un mensaje auxiliar. Entonces, para BSD, parece que si su búfer es más grande que el mensaje de soporte auxiliar, obtendrá un comportamiento casi similar al de un paquete. Las lecturas que obtengo son:
recv1: [20 bytes] (msg1)
recv2: [7 bytes] (msg2, with msg2's 2 file descriptors)
recv3: [17 bytes] (msg3, and msg4, with msg3's 1 file descriptor)
recv4: [7 bytes] (msg5 with 5 file descriptors)
recv5: [0 bytes]
QUE HACER:
Todavía me gustaría saber cómo sucede en Linux, iOS, Solaris, etc., y cómo se podría esperar que suceda en el futuro.