Skip to main content

La capture de backlog TCP est un effet qui empêche une application serveur sur le module Stratus qui écoute sur le port X de réussir à créer une connexion avec tout client essayant de se connecter au port X. Les connexions à d'autres ports, même à partir des mêmes clients, fonctionnent bien. La solution typique consiste à arrêter et à redémarrer l'application serveur. Ce billet expliquera pourquoi la capture de l'arriéré se produit et d'autres solutions moins drastiques.

Le backlog TCP est la file d'attente des connexions en attente, c'est-à-dire des demandes de connexion qui ont été reçues mais qui n'ont pas encore été acceptées. Dans les applications compilées sur des versions antérieures à OpenVOS 17.1 et dans les applications compilées sur OpenVOS 17.1 mais sans les bibliothèques POSIX, les demandes de connexion ne reçoivent pas d'accusé de réception tant qu'elles ne sont pas acceptées par l'application. Le client renverra le paquet de demande de connexion entre 3 et 10 fois à des intervalles croissants. Les détails exacts dépendront du système d'exploitation du client et de sa configuration. À un moment donné, l'application serveur accepte la demande de connexion et la pile STCP envoie un accusé de réception. Tant que cet accusé de réception est reçu avant que le client n'ait abandonné, la connexion sera terminée et la communication pourra commencer.

Le scénario de rattrapage de l'arriéré requiert plusieurs conditions

  1. Il y a une défaillance temporaire du réseau entre le serveur et le client (mais pas entre le client et le serveur). Cela permet au serveur de recevoir les demandes de connexion du client, mais empêche le client de recevoir les accusés de réception de connexion du serveur.
    ou

    L'application du serveur retarde l'appel de la fonction d'acceptation pour une raison quelconque.

  2. Le client continue à envoyer des demandes de connexion ; c'est à ce moment que la demande en cours expire et que le client en envoie une nouvelle. La valeur du délai d'attente du client doit être inférieure à celle du serveur.
  3. Un pare-feu dynamique ou un autre dispositif situé entre le client et le serveur temporise les demandes de connexion du client et rejette les accusés de réception de connexion du serveur sans renvoyer de réponse au serveur. Ce délai doit être plus court que celui du serveur.

Malheureusement, cette combinaison de conditions n'est pas aussi improbable qu'il n'y paraît à première vue.

Elle commence généralement par une panne de réseau qui empêche les paquets du serveur d'atteindre le client mais qui permet aux paquets du client d'atteindre le serveur. Lorsque le paquet de demande de connexion du client atteint le serveur, il est placé dans la file d'attente. Lorsque l'application du serveur appelle le code d'acceptation, le code extrait la demande de connexion de la file d'attente et envoie un accusé de réception de la connexion. Comme le serveur n'obtient pas d'accusé de réception pour son paquet, parce que le réseau est interrompu, il retransmet l'accusé de réception de la connexion. La pile TCP du client retransmet également la demande de connexion parce qu'elle n'a pas reçu d'accusé de réception. Au bout d'un certain temps, la pile TCP du client s'arrête et l'application cliente envoie une nouvelle demande. Le serveur continue de répondre à la première demande. Au bout d'une minute et demie environ (par défaut), le serveur s'arrête et retire la demande suivante de la file d'attente. Entre-temps, le client a renvoyé la deuxième demande et pourrait se trouver sur la troisième. Ces demandes se trouvent également dans la file d'attente de l'arriéré. Il est possible qu'un autre client puisse obtenir qu'une demande de connexion soit placée dans la file d'attente, mais pour qu'elle aboutisse, le client a besoin d'un délai d'attente supérieur au délai d'attente du serveur multiplié par la position de la demande de connexion dans la file d'attente. Une fois que la panne du réseau est corrigée, le pare-feu avec état perpétue la panne en abandonnant silencieusement les accusés de réception de connexion pour lesquels il n'a plus d'état, car il ne conserve l'état que pendant un temps plus court que le délai d'attente du serveur.

Comment le reconnaissez-vous ?

Tout d'abord, l'arriéré est plein ou du moins se remplit. Cette commande vous permet d'afficher la file d'attente pour une connexion.

analyze_system -request_line (chaîne de caractères correspondant au backlog - ou syncnt (octet 3Bx) dump_st +
cbq -full -lport 7654 -faddr 0x) -quit 
OpenVOS version 17.0.2au, analyze_system version 17.0.2au 
Le processus actuel est le 154, ptep 91CC7100, Noah_Davids.CAC 
syncnt 6 
arriéré 5 
prêt 11:41:19

La valeur lport est le numéro de port local, 7654 dans ce cas. La valeur 0 de l'adresse étrangère (faddr) limite la sortie à la seule prise LISTENING. Si la valeur de backlog plus 1 est égale à la valeur de syncnt, le backlog est complet. Si la valeur de syncnt est supérieure à 0 et que l'on monte, la file d'attente de l'arriéré est pleine. La taille de la file d'attente est fixée par l'application lorsqu'elle appelle la fonction d'écoute.

Ensuite, vous devez examiner une trace de protocole réseau. La trace montrera que la dernière demande de connexion ne fait pas l'objet d'un accusé de réception alors qu'il existe des accusés de réception pour une demande de connexion précédente et que ces accusés de réception ne reçoivent aucune réponse.

C'est ce que montre la trace de la figure 1. Chaque connexion est étiquetée avec un index de flux et également codée par couleur. La première demande de connexion du client se trouve dans la trame 1 au temps 0. L'accusé de réception est envoyé dans la trame 2 et ensuite retransmis dans la trame 3. La trame 4 est le client qui retransmet la demande de connexion. Comme le STCP envoie déjà des acquittements de connexion, la trame 4 ne déclenche qu'un acquittement TCP dans la trame 5. Les trames 6 et 7 sont des acquittements de connexion retransmis. La trame 8 est une demande de connexion retransmise par le client. La trame 9 est l'acquittement TCP déclenché par la demande de connexion retransmise et la trame 10 est un autre acquittement de connexion retransmise. La trame 11 est une autre demande de connexion du client mais pour une nouvelle seconde connexion. Notez qu'il n'y a pas de réponse et que la trame 12 montre une demande de connexion retransmise. La trame 13 montre un acquittement de connexion mais c'est toujours pour la première connexion. La trame 14 est une retransmission de la deuxième demande de connexion. La trame 14 est une autre retransmission de la deuxième demande de connexion. La trame 15 montre une nouvelle troisième demande de connexion du client et les trames 16 et 17 sont des retransmissions. La trame 18 est une autre retransmission de l'accusé de réception de la première connexion. La trame 19 est une autre demande de connexion avec les trames 20 et 21 les retransmissions et la trame 22 est la quatrième nouvelle demande de connexion. Enfin, dans la trame 23, le STCP abandonne la première demande de connexion et envoie une réinitialisation suivie dans la trame 24 d'un accusé de réception de la connexion à la deuxième demande de connexion avec une retransmission dans la trame 25. À ce stade, je pense que vous comprenez l'idée.

Le STCP a pris le temps de passer de la trame 0 à la trame 23, soit un total de 106,9 secondes. Bien que le client n'envoie pas de réinitialisation lorsque le délai est écoulé, le temps entre le début de la deuxième et de la troisième demande de connexion (trame 11 à trame 15) est de 29,152 secondes et entre la troisième et la quatrième (trames 15 et 19) est de 25,8 secondes, ce qui est beaucoup plus rapide que le STCP.

Que pouvez-vous faire pour éviter cela ?

La meilleure solution est de passer à OpenVOS 17.1 et de recompiler l'application avec les bibliothèques POSIX. Cela permettra d'éviter que le problème ne se reproduise, puisque le STCP enverra immédiatement un accusé de réception de la connexion, sans attendre que l'application appelle l'acceptation. Cela peut toutefois modifier d'autres comportements de votre application et il convient de tester soigneusement votre application. Si la mise à jour et la recompilation ne sont pas possibles, vous pouvez

  1. Reconfigurez le périphérique réseau en état de marche qui supprime les accusés de réception de connexion pour qu'il réponde par une réinitialisation. Lorsque le STCP reçoit la réinitialisation, il passe à la demande de connexion suivante dans la file d'attente. Il en résulte que les demandes de connexion interrompues par l'appareil en état seront rapidement supprimées de la file d'attente. Tout autre accusé de réception de connexion sera traité par le client, qui enverra sa propre réinitialisation ou accusera réception de la demande.
  2. Empêchez le client de faire des demandes de connexion jusqu'à ce que la file d'attente du serveur soit vidée.
  3. Fermez la prise d'écoute de l'application serveur et rouvrez-la. En général, l'application n'est pas conçue pour cela, vous devez donc arrêter et redémarrer l'application serveur.
  4. Configurez la valeur de syn_rcvd_abort pour qu'elle soit plus courte que la valeur du délai d'attente du client. La valeur est modifiée avec la requête analyze_system set_stcp_param
    analyze_system -request_line 'set_stcp_param syn_rcvd_abort 15' -quit
    OpenVOS version 17.0.2au, analyze_system version 17.0.2au 
    Le processus actuel est le 151, étape 91530AC0, Noah_Davids.CAC 
    Modification du délai d'attente tcp SYN_RCVD (syn_rcvd_abort) de off à 15 
    prêt 11:07:44

    Dans l'exemple ci-dessus, le délai d'attente est fixé à 15 secondes. Les valeurs valides sont comprises entre 1 et 180, la valeur 0 signifiant qu'il faut utiliser la valeur par défaut (environ 100 secondes).

    Cela permettra d'éviter qu'un seul client ne crée une accumulation importante dans la file d'attente. La longueur de la valeur dépendra du nombre de clients pouvant accéder au serveur en même temps. Le problème avec cette approche est que cela affecte tous les clients et tous les ports du serveur, vous ne pouvez pas avoir une valeur pour un ensemble de ports et une autre pour un autre ensemble de ports. En outre, une valeur trop faible pourrait faire échouer certaines connexions passant par des liens à forte latence alors qu'elles pourraient réussir si le délai était plus long. Choisir une valeur optimale est plus un art qu'une science

2020 Stratus Technologies.