web-dev-qa-db-fra.com

Pourquoi un client peut-il envoyer un premier paquet comme réponse à une syn) ACK?

J'ai un service Web HTTP où parfois la configuration de la connexion échoue d'une manière étrange:

  • client envoie un paquet SYN
  • server envoie une réponse SYN, ACK
  • le client répond avec la TVD

Dans quelles situations un système client pourrait-il décider de répondre avec la RST Packet? Je pourrais imaginer que cela se produit lorsque la syn de synchronisation, ACK contient, par exemple. Numéros de séquence incorrects (mais cela ne semble pas s'appliquer dans mon cas - les numéros de séquence vont bien). Donc, je suis intéressé par une exhaustive :-) Liste des cas où un client enverrait un paquet RST après avoir reçu le paquet SYN, ACK.

En particulier, est-il possible pour le code d'application du client (à l'aide de l'API de socket de style BSD normal sous Linux) pour provoquer ce premier paquet, par exemple. En appelant close() tandis que la poignée de main à 3 voies est toujours en cours?

4
oliver

Pour la fermeture: le problème était un bogue stupide dans mon code (dans le client).

Le client dans ce cas utilise des sockets anti-blocking, de sorte que l'appel connect() _ L'appel reviendra immédiatement pendant que le noyau continue d'attendre le paquet SYN, ACK du serveur. Malheureusement, le code client était très impatient: si la connexion n'a pas été établie après quelques centaines de millisecondes, le client appellerait close() sur la prise.

Dans certains cas rares, le SYN, les paquets ACK du serveur seraient retardés de plusieurs centaines de millisecondes sur leur chemin à travers le réseau. Lorsque la réponse différée est enfin arrivée à l'hôte du client, le noyau verrait que la prise était déjà fermée et traiterait la réponse SYN, ACK comme appartenant à une prise non valide. C'est pourquoi il répondrait avec un paquet RST sur le serveur.

Donc, oui, il est possible pour le code d'application (à l'aide de l'API de socket de style BSD normal sous Linux) pour provoquer ce paquet RST: en utilisant une prise non bloquante et fermez la connexion pendant que la poignée de main à trois voies est toujours en cours.

6
oliver