Le client termine son envoi, le proxy voit EOF et la réponse disparaît. Fermer immédiatement les deux sockets du proxy peut produire exactement cette séquence. Dans un relais TCP, une fin ordonnée dans une direction ne signifie pas que l'autre direction est terminée.

Prenons un client qui envoie une requête, ferme son côté émission et attend la réponse :

client -- request, then FIN --> proxy --> service
client <-------- reply ------- proxy <-- service

Le proxy a deux connexions TCP et deux flux d'octets qui avancent indépendamment. Il doit transmettre l'indication de fin d'entrée après avoir transmis les octets qui la précèdent.

Videz la file avant de transmettre EOF

Pour une réception de taille non nulle sur un flux TCP, un retour de zéro indique une fin ordonnée de ce flux entrant. Marquez cette direction de lecture comme terminée. Cessez d'attendre davantage d'entrée de sa part, mais conservez les octets déjà mis en file pour le socket opposé.

Une fois la file client-vers-service vidée, appelez shutdown(service_socket, SHUT_WR) sur un socket POSIX. Cela met fin à toute transmission ultérieure vers le service tout en laissant la direction service-vers-client disponible. Lorsque le service termine sa réponse, appliquez l'opération symétrique après avoir vidé la file de réponse.

La fermeture des descripteurs intervient au moment où les deux directions et leurs tampons en attente sont terminés, ou lorsqu'une erreur ou une annulation impose l'arrêt. Gardez un délai borné pour un pair qui n'achève jamais sa moitié restante.

La disponibilité est une invitation à lire

Un socket lisible peut contenir des données ou un état EOF. Appelez recv et interprétez le résultat. Les comptes positifs sont des octets à transmettre ; zéro est la fin directionnelle. Sur un socket non bloquant, EAGAIN ou EWOULDBLOCK signifie qu'il n'y a pas d'autre entrée pour le moment, tandis que EINTR peut nécessiter une nouvelle tentative. Aucun des deux n'est le même événement que EOF.

Ne cherchez pas d'indicateur FIN dans le tampon d'octets renvoyé. TCP fournit à cette API un flux d'octets ordonné ; les frontières de paquets et le segment FIN ne sont pas une charge utile applicative ordinaire.

C'est le cycle de vie d'un tunnel d'octets brut. Un proxy HTTP qui analyse les messages doit toujours respecter le cadrage HTTP, et un proxy qui termine TLS possède aussi un protocole d'arrêt TLS. Gardez ces décisions de protocole au-dessus du relais TCP directionnel.

Articles similaires