Affichage des articles dont le libellé est option. Afficher tous les articles
Affichage des articles dont le libellé est option. Afficher tous les articles

mardi 29 mars 2016

Acquittements sélectifs (SACK)

Contexte


Dans la présentation du protocole TCP, nous avons vu que les acquittements sont cumulatifs.
Par conséquent, la pile TCP ne peut acquitter qu'une suite continue d'octets. Le problème se pose si un segment est perdu et que les suivants arrivent à destination.

De plus, la pile TCP ne peut pas transmettre à l'application les données reçues avec des « trous », de par le modèle de flux d'octet.

Perte du premier segment dans un burst TCP


Que faire des segments 20 à 23 pour le récepteur ? De même, quelle stratégie de retransmission à appliquer pour l'émetteur des données ?
Car d'après la RFC 793, aucun des segments n'aura été reçu du point de vue de l'émetteur. En effet, le récepteur des données devra acquitter en premier le segment 19 (ci­-dessus) qui a été perdu.
Le risque est que l'émetteur retransmette les segments 19 à 23.

Le mécanisme d'acquittement sélectif (« Selective Acknowledgement » ou SACK) permet de répondre à cette problématique.
Le destinataire des données peut indiquer à l'émetteur quels sont les segments reçus, et ainsi permettre à ce dernier de ne retransmettre que les segments manquants.

Fonctionnement


La RFC 2018 définit 2 options.

La première permet d'indiquer au destinataire que l'émetteur implémente cette fonctionnalité. Le type est 0x04 et de longueur 2 (octets).

Elle ne peut être envoyée que lors de l'établissement de la connexion (Lorsque le drapeau SYN est activé).



La deuxième option informe l'émetteur de l'existence de blocs de données non contigus dans les segments reçus.

L'option liste tous les blocs reçus valides (contenus dans la fenêtre de réception) et isolés dans le flux d'octets. Pour N éléments dans la liste, la longueur de cette option est N*8+2.



Chaque bloc est constitué de 2 entiers non signés de 32 bits :

• celui de gauche indique le premier numéro de séquence de ce bloc.

• celui de droite indique le prochain numéro de séquence après ce bloc.

Chaque bloc constitue un ensemble d'octets reçus, contigus et isolés dans la fenêtre de réception. Les octets juste autour de ce bloc n'ont pas été reçus.

Dans la mesure où l'en­-tête TCP ne peut pas avoir une longueur supérieure à 60 octets, il ne peut y avoir que 4 éléments dans la liste, au maximum. Dans la pratique, avec l'utilisation des timestamps, ce nombre est plutôt de 3 au maximum.

Il est à noter que le champ d'acquittement dans l'en­tête ne change pas de signification, il pointe toujours vers le premier octet attendu dans la fenêtre de réception. Dans l'exemple ci-­dessus, le champ ACK pointe toujours vers le segment 19.

N.B. : cette option est uniquement informative, elle n'engage pas le récepteur à garder ces blocs de données.
Ce dernier peut notifier l'émetteur au moyen de l'option SACK et quand même supprimer ces blocs de ses files d'attente (par manque de mémoire), même si cela n'est pas recommandé.
Toutefois, à part le dernier segment reçu isolé, le récepteur des données ne doit pas signaler de blocs de données supprimés.

Règles d'envoi de l'option SACK


• Le destinataire de cette option doit avoir indiqué son acceptation lors de l'établissement de la connexion.

• Chaque segment d'acquittement (avec le drapeau ACK activé) peut contenir l'option SACK. Par contre, le premier bloc de la liste doit contenir les numéros de séquence du dernier segment reçu.

• Le destinataire des données devrait lister autant de blocs de données qu'il est nécessaire. Néanmoins, cette liste peut être tronquée par les limites de la taille maximale de l'en­tête.

• La liste des blocs devrait être remplie dans l'ordre inverse d'ancienneté (le plus récent d'abord). Ce qui assure à chaque bloc d'être transmis au moins 3 fois (4 sans timestamps) si nécessaire.


L'idée principale est d'indiquer à l'émetteur des données l'état le plus récent de la fenêtre de réception du destinataire.
De plus, ces segments d'acquittement SACK peuvent être perdus eux aussi. Le fait de transmettre chaque bloc au moins 3 fois diminue le risque qu'un bloc ne soit pas signalé à l'émetteur des données.


Exemple d'envoi de plusieurs blocs SACK
Exemple d'envoi de plusieurs blocs SACK
Dans l'exemple ci-dessus, le récepteur des données (10.8.0.22) indique à l'émetteur qu'il se retrouve avec un bloc isolé de données (paquet n° 131) puis avec un deuxième (paquet n° 132).
A noter que le premier bloc (n° 132) fait référence au dernier segment reçu (paquet n° 130).


Stratégie de retransmission


L'émetteur des données est supposé tenir à jour une liste des segments à retransmettre (les segments qui n'ont toujours pas été acquittés).

En cas de réception de l'option SACK, les segments concernés sont mis à part. Par exemple, avec l'utilisation d'un drapeau SACK qui indique la bonne réception par le destinataire.

Ce mécanisme permet de déterminer les segments à retransmettre, sans attendre l'expiration du temps d'attente (« retransmit timeout »).

Toutefois, en cas d'expiration de ce temps d'attente, tous les segments de cette liste, marqués ou non, sont considérés comme perdus et doivent être retransmis.

N'oublions pas que cette option SACK est informative. Le récepteur des données peut, pour des raisons diverses, ne pas avoir gardé en mémoire les segments déclarés dans l'option SACK.

Avec ou sans cette fonctionnalité SACK, LA seule façon d'enlever un segment de cette liste de retransmission, est que le récepteur des données ait acquitté ce segment grâce au champ d'acquittement dans l'en­tête TCP.


Toutes les copies écrans sont issues du logiciel d'analyse réseau de Comoe Networks.

mardi 15 mars 2016

Les options TCP


Les options ont plusieurs objectifs :

• Lors de l'établissement de la connexion, elles permettent de définir les capacités de la pile TCP implémentée (Selective Acknowledgement, Window Scale, ...) ainsi que les conditions de transmission (Maximum Segment Size, ...).

• Elles permettent aussi de fournir des moyens supplémentaires de correction d'erreurs (Selective Acknowledgement par exemple).

• Enfin, elles peuvent fournir des moyens supplémentaires pour améliorer la sécurité ou estimer la latence (Timestamps par exemple).

Les options sont de longueur variable et sont intégrées dans le checksum TCP. Elles se trouvent entre l'en-tête fixe et les éventuelles données.

La RFC 793 définit 3 options qui doivent être obligatoirement implémentées par toute pile TCP. Toutes les options sont répertoriées par l'IANA.

L'URL actuelle est ici. Elle peut changer, donc le mieux est d'utiliser l'outil de recherche de l'IANA avec les mots clés 'tcp parameter' (ou dans votre moteur de recherche favori).

Format des options


Il existe 2 formats pour les options :

• 1 seul octet pour l'option, qui correspond au code associé.

• un format TLV (Type/Longueur/Valeur) de longueur variable :

Type (1 octet) -Longueur (1 octet) -Données (variable)

La longueur inclut également les 2 octets pour le champ Type et le champ Longueur.

Les options standards à un seul octet


L'option « Fin d'option (End of Option List) » dont le code est 0x00. Elle n'est nécessaire que si la fin des options ne coïncide pas avec la longueur de l'en-tête. Elle se trouve uniquement à la fin de toutes les options.

L'option « Pas d'opération (No­ Operation) »  dont le code 0x01. Cette option est principalement utilisée pour aligner la longueur de l'en­tête sur des mots de 32 bits.
En effet, la longueur de l'en-­tête est donnée en mots de 32 bits.

L'option Maximum Segment Size (MSS)


Pour rappel, la taille maximale d'un datagramme (MTU) IPv4 DEVANT être accepté est de 576 octets (RFC 791).

Par conséquent, un hôte ne doit pas envoyer un segment avec une taille supérieure à 576 octets, à moins d'avoir la certitude que le destinataire acceptera de tels segments.

Dans le cas d'une fragmentation, la taille totale du datagramme réassemblé peut dépasser cette limite, mais chaque fragment doit respecter cette limite.

D'où l'intérêt de l'option MSS :

L'option « Taille maximale du segment » (Maximum Segment Size ou MSS) définit la longueur maximale des données dans un segment TCP acceptée par l'émetteur de cette option (RFC 793, 879 et 6691).

Cette option ne peut être envoyée qu'avec le drapeau SYN activé, par conséquent, uniquement lors de l'établissement de la connexion.

Son code est 0x02 et sa longueur fixe est de 4 octets (la valeur est codée sur 16 bits).

Il y a eu beaucoup de débat sur cette valeur (RFC 879, 6691, 1122) et, en particulier, sur comment la définir. Faut il prendre en compte les options qui peuvent ne pas être présentes ou non ?

Au départ, rien n'est spécifié (RFC 793). Puis, devant les incertitudes soulevées, la RFC 879 nous dit ceci :

THE TCP MAXIMUM SEGMENT SIZE IS THE IP MAXIMUM DATAGRAM SIZE MINUS FORTY

Donc, on enlève 40 octets à la MTU, sans être réellement sûr de savoir à quoi correspond ce chiffre.
Dans un souci de clarifier une bonne fois pour toute, la RFC 6691 nous donne la formule pour le calcul de cette valeur :

MSS = MTU – taille en­tête IP (sans options) – taille en­tête TCP (sans option).

Par contre, l'émetteur doit prendre en compte la taille des options pour calculer la taille du segment à envoyer.


Options TCP présentes lors de l'ouverture d'une connexion
Exemple d'options présentes lors de l'ouverture d'une connexion


Voilà pour les options définies par la RFC 793, nous verrons les autres options dans des articles dédiés.

mardi 16 février 2016

Connexions TCP


TCP est un protocole orienté connexion. Contrairement à UDP par exemple, il est nécessaire d'établir une connexion avant de pouvoir échanger des données.

Cette phase a pour but d'initialiser différents paramètres comme le numéro de séquence initial (ISN), la taille maximale de segment (MSS), ou le support de certaines implémentations (SACK, Window scaling, ...).

Le drapeau SYN est utilisé lors de cette phase appelée "Three Way Handshake".

De même, une fois le transfert de données terminé, il est nécessaire de fermer la connexion entre les 2 hôtes. Le drapeau FIN est utilisé à cette fin lors de cette phase appelée "Four Way Handshake".

Comme indiqué dans l'article d'introduction sur TCP, une connexion TCP entre 2 hôtes est définie de manière unique par le couple de "socket" (terme popularisé par l'université de Berkeley).

Établissement de la connexion


Regardons de plus près l'établissement d'une connexion TCP :

Etablissement d'une connexion TCP - Comoe Networks

  1. Le client initie la communication en envoyant un segment dont le drapeau SYN est activé (couramment appelé segment SYN). Il transmet par la même occasion son ISN, qui sera le numéro de séquence de référence pour le transfert de données dans le sens client vers serveur. De même, il indique ses conditions et ses capacités dans les options.
  2. Le serveur envoie alors son segment SYN, dans lequel il confirme avoir bien reçu l'ISN du client ainsi que ses capacités. Il envoie également son ISN ainsi que ses capacités.
  3. Le client confirme avoir bien reçu le segment SYN du serveur. Le transfert de données peut commencer.
Dans la mesure où l'établissement de la connexion doit être aussi fiable que le transfert de données, le drapeau SYN compte pour un octet dans les numéros de séquence.

On peut voir ici la capture de l'établissement d'une connexion avec le logiciel d'analyse réseau de Comoe Networks.
Etablissement d'une connexion TCP - analyse réseau Comoe Networks
Établissement d'une connexion TCP

Terminaison de la connexion


N'importe quel hôte peut fermer la connexion, ce n'est pas forcément le client. Cela dépend plutôt de l'application de la couche supérieure qui utilise le service TCP.
Il est même possible d'avoir une clôture simultanée, même si dans la pratique, c'est plutôt rare.

Terminaison d'une connexion TCP - Comoe Networks
Terminaison classique d'une connexion TCP
  1. L'hôte qui souhaite indiquer la fin de l'envoi de données (dans une situation normale), le signale en envoyant un segment avec le drapeau FIN (couramment appelé segment FIN).
  2. Son correspondant envoie un segment ACK pour confirmer la réception du segment FIN.
  3. Son correspondant envoie lui aussi un segment FIN pour signaler qu'il n'a plus de données à envoyer.
  4. L'hôte envoie un segment ACK à son correspondant pour confirmer la réception de son segment FIN.
De la même façon, pour confirmer la bonne réception du segment FIN, ce dernier compte pour un octet dans les numéros de séquence.

Note : les étapes 1 et 2 n’entraînent pas obligatoirement les étapes 3 et 4 dans la foulée. Le segment FIN indique juste que son émetteur n'a plus de données à envoyer. Le destinataire de ce segment peut lui avoir encore des données à transmettre.

De la même façon, on peut suivre le déroulement de la fermeture d'une connexion TCP ci-dessous :

Fermeture d'une connexion TCP - Comoe Networks
Fermeture d'une connexion TCP


Pour l'hôte qui a initié la terminaison de la connexion, comment savoir que le correspondant a bien recu le segment de l'étape 4 ci-dessus ?

Dans la pratique, c'est impossible. C'est pourquoi il est instauré un temps d'attente durant lequel, la socket sur cet  hôte ne peut être fermée et reste dans l'état CLOSE_WAIT (sur Linux).
On peut le voir ci-dessous pour la connexion TCP/IPv6

root@LAB-NODE2:~# netstat -nt
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address           Foreign Address             State     
tcp     0           136       192.168.43.1:22        192.168.43.254:42642    ESTABLISHED
tcp6   1           0           ::1:50516                    ::1:631                            CLOSE_WAIT


Nous verrons plus en détail cet aspect lorsque nous regarderons les différents états d'une connexion TCP.

Merci.

Toutes les copies écrans sont issues du logiciel d'analyse réseau de Comoe Networks.