La performance des communications réseau modernes repose sur la capacité du protocole TCP à maintenir un débit régulier à travers des topologies Internet complexes. Cependant, lorsque le trafic emprunte des tunnels chiffrés, des réseaux de routage à chemins multiples équicouvertes (ECMP), des cartes réseau multi-files ou subit des basculements d'antennes cellulaires, les paquets arrivent fréquemment dans le désordre. Le protocole TCP classique interprète la réception de trois acquittements dupliqués (DupACK) consécutifs comme la preuve formelle d'une perte de paquet, déclenchant un Fast Retransmit et divisant par deux la fenêtre de congestion (cwnd). Lorsque ce désordre temporel, et non une perte physique, provoque ces DupACK, l'émetteur procède à une retransmission intempestive et pénalise lourdement le débit utile de la liaison.

Pour résoudre cette inefficacité fondamentale au niveau de la couche transport, l'Internet Engineering Task Force (IETF) a standardisé la RFC 2883 : An Extension to the Selective Acknowledgement (SACK) Option for TCP, communément appelée D-SACK (Duplicate SACK). En utilisant le premier bloc de l'option TCP SACK pour notifier les plages de numéros de séquence reçues en double, D-SACK permet à l'émetteur de déterminer si les acquittements reflètent un simple désordre ou une réelle disparition de paquet.

[SACK Classique (RFC 2018) : ambiguïté lors de la réception de doublons]
Émetteur : transmet les segments 1, 2, 3, 4, 5
Réseau : le segment 2 subit un retard via un chemin ECMP alternatif ; les segments 3, 4, 5 arrivent d'abord
Récepteur : envoie des DupACK avec le bloc SACK [3-5]
Émetteur : suppose que le segment 2 est perdu ! Déclenche Fast Retransmit et réduit cwnd de 50 %
Le segment 2 initial arrive ! Le récepteur acquitte, mais l'émetteur ignore s'il s'agit de l'original ou du doublon

[RFC 2883 D-SACK : notification explicite des doublons et restauration de fenêtre]
Récepteur : reçoit le segment 2 d'origine, puis le segment 2 retransmis
Récepteur : envoie un ACK avec le bloc D-SACK [2-3] en première position (Seq <= Cumulative ACK)
Émetteur : détecte le doublon ! Identifie la retransmission précédente comme inutile
Émetteur : annule la réduction de cwnd (Undo cwnd), rétablit le débit et adapte le seuil de désordre

Le dilemme du désordre des paquets : pourquoi diagnostiquer à tort une perte dégrade le débit VPN

La perte de paquets sur les liaisons physiques signale la saturation des mémoires tampons des routeurs, imposant un ralentissement pour préserver l'équilibre du réseau. À l'inverse, le désordre des paquets ne représente qu'une permutation temporelle des trames sans perte d'information. Quand un émetteur confond désordre temporel et perte matérielle, l'efficacité globale du transfert s'effondre.

Cartes réseau multi-files, ECMP et réordonnancement dans l'encapsulation VPN

Les flux encapsulés présentent des mécanismes d'acheminement particuliers. Dans les architectures VPN exploitant WireGuard, IPsec ou OpenVPN, les segments TCP d'origine sont insérés dans des datagrammes UDP externes. Lors de leur transit sur les dorsales des opérateurs, le routage ECMP distribue les flux sur des liaisons physiques parallèles via des fonctions de hachage :

$$P_{\text{hash}} = \text{CRC32}(\text{SIP}, \text{DIP}, \text{Proto}, \text{SPort}, \text{DPort}) \pmod N$$

Si l'entropie des ports source fluctue ou si les moteurs cryptographiques multicœurs traitent les paquets avec de légers décalages d'horloge dans leurs files d'attente, les datagrammes atteignent la passerelle dans un ordre perturbé. Un écart de propagation de seulement 2 millisecondes entre deux liaisons physiques suffit pour que trois paquets consécutifs dépassent un paquet antérieur.

Sur les réseaux sans fil mobiles (LTE, 5G NR), les mécanismes de retransmission au niveau de la couche liaison (HARQ) délivrent fréquemment un paquet retardé juste après que des trames plus récentes ont été réceptionnées.

Le piège de la retransmission intempestive : comment un faux Fast Retransmit divise cwnd par deux

Conformément à la RFC 5681, le récepteur TCP émet un acquittement immédiat à la réception de chaque segment hors séquence, réitérant le numéro d'acquittement cumulatif. Dès réception de 3 DupACK consécutifs (la constante dupthresh = 3), l'émetteur conclut à la perte du segment :

$$\text{ssthresh} = \max\left(\frac{\text{FlightSize}}{2}, 2 \times \text{MSS}\right)$$

$$\text{cwnd} = \text{ssthresh} + 3 \times \text{MSS}$$

Cette décision engendre deux sanctions techniques majeures :

  1. Gaspillage de ressources réseau : l'émetteur réexpédie inutilement un segment déjà présent dans le tampon de réception ou sur le point d'arriver, consommant inutilement de la bande passante et des cycles CPU de chiffrement.
  2. Effondrement artificiel du débit : la fenêtre d'émission est amputée de moitié, basculant la connexion en évitement de congestion (Congestion Avoidance). Sur une liaison chiffrée à 1 Gbps avec un temps d'aller-retour (RTT) de 80 ms, réoccuper la capacité nominale du canal exige des dizaines de RTT. Des désordres légers et récurrents maintiennent ainsi la liaison dans un goulot d'étranglement permanent.

Anatomie technique de la RFC 2883 : comment D-SACK signale les segments dupliqués

La spécification RFC 2018 a défini le format de base de l'acquittement sélectif, autorisant l'en-tête TCP à rapporter jusqu'à 4 blocs discontinus de données reçues. Toutefois, les blocs SACK classiques ne décrivent que les séquences situées au-dessus du point d'acquittement cumulatif et n'offrent aucun moyen d'identifier les paquets dupliqués.

La RFC 2883 enrichit cette syntaxe sans modifier le format des options TCP existantes.

Structure des blocs SACK et règles d'espace de séquence D-SACK

L'option TCP SACK comprend un octet de type (Kind = 5), une longueur (Length) et des paires d'entiers non signés de 32 bits délimitant le bord gauche (Left Edge) et le bord droit (Right Edge) de la plage de données :

+---------------+---------------+
| Kind = 5      | Length = N    |
+---------------+---------------+-------------------------------+
| Bord gauche du 1er bloc (Numéro de séquence 32 bits)          |
+-------------------------------+-------------------------------+
| Bord droit du 1er bloc (Numéro de séquence 32 bits)           |
+-------------------------------+-------------------------------+

La RFC 2883 établit deux règles déterministes qualifiant le premier bloc comme un bloc D-SACK :

  • Règle 1 (Doublon inférieur ou égal à l'ACK cumulatif) : si le bord gauche du premier bloc SACK est inférieur ou égal au numéro d'acquittement cumulatif de l'en-tête TCP :

$$\text{Left Edge}_1 \le \text{Cumulative ACK}$$

  • Règle 2 (Doublon englobé dans un bloc SACK ultérieur) : si le bord gauche du premier bloc SACK est totalement contenu dans la plage de séquence d'un bloc SACK suivant au sein du même en-tête :

$$\exists i > 1 : \left(\text{Left Edge}_i \le \text{Left Edge}_1\right) \land \left(\text{Right Edge}_1 \le \text{Right Edge}_i\right)$$

Distinguer les segments dupliqués des blocs SACK conventionnels

Le bloc D-SACK est obligatoirement confiné au tout premier emplacement d'option. Les blocs suivants continuent d'indiquer les plages disjointes selon la RFC 2018.

Prenons l'exemple d'un émetteur transmettant les segments [1000–1500] et [1500–2000]. Si le récepteur a déjà acquitté jusqu'à l'octet 2000, mais reçoit ensuite une copie tardive du segment [1000–1500], il répond :

  • Cumulative ACK : 2000
  • SACK Block 1 : Left Edge = 1000, Right Edge = 1500

Le bord gauche (1000) étant inférieur à l'ACK cumulatif (2000), l'émetteur en déduit instantanément que le récepteur a collecté un double du segment [1000–1500].

En-tête TCP ACK : 2000
Option : Kind=5, Length=10
SACK Block 1 : [1000, 1500]  <── (1000 <= 2000) Identifie un doublon D-SACK !

En l'absence de la RFC 2883, le récepteur supprimerait silencieusement le paquet en double et renverrait un ACK ordinaire, privant l'émetteur de toute information sur l'inutilité de sa retransmission.

Annuler la pénalité de fenêtre de congestion : mécanisme Undo cwnd et reprise de débit

Le bénéfice opérationnel majeur de D-SACK réside dans l'élimination de l'ambiguïté de retransmission (retransmission ambiguity), fournissant à l'émetteur une certitude mathématique pour rétablir sa cadence.

Mécanique de restauration de cwnd lors de la détection d'une retransmission inutile

Lorsqu'un émetteur transmet un segment initial à l'instant $t_1$, puis déclenche un Fast Retransmit à l'instant $t_2$, la pile TCP conventionnelle est incapable de savoir à quel envoi correspond l'acquittement entrant.

Avec D-SACK activé :

  1. Si les deux segments atteignent la destination, le bloc D-SACK atteste de manière indiscutable de la réception d'un duplicata.
  2. Si le premier segment a réellement été détruit en cours de route, le récepteur ne reçoit que le second et n'émet aucun bloc D-SACK.

À la lecture du bloc D-SACK, la pile déclenche la commande Undo CWND :

$$\text{cwnd} = \text{prior_cwnd}$$

$$\text{ssthresh} = \text{prior_ssthresh}$$

En restaurant immédiatement la valeur de cwnd antérieure au faux déclenchement de Fast Retransmit, le flux reprend son débit nominal sans devoir subir une lente phase de montée linéaire.

Ajustement dynamique du seuil de désordre via le paramètre tcp_reordering

Au-delà de la restauration immédiate, D-SACK permet au noyau Linux d'évaluer le degré de désordre réel du chemin réseau.

Le protocole TCP standard applique un seuil statique dupthresh = 3. Sur une liaison dont le désordre naturel atteint 5 ou 6 trames, ce seuil fixe provoque d'incessantes fausses alertes. Lorsqu'il reçoit une confirmation D-SACK, le noyau calcule l'écart de permutation :

$$\Delta_{\text{reorder}} = \text{HighDataSeq} - \text{RetransmitSeq}$$

Le système incrémente alors dynamiquement sa variable interne (tp->reordering), passant de la valeur 3 par défaut à 5, 8 ou 12. L'ajustement du seuil au profil du chemin immunise la liaison contre les dégradations ultérieures.

Ingénierie noyau : arbitrage intelligent des flux de paquets avec RiceGuard

Les infrastructures de transport chiffré doivent concilier les flux à faible latence et les transferts massifs de données. VPNRice intègre la télémétrie RFC 2883 D-SACK dans son architecture RiceGuard, optimisant l'arbitrage des paquets à l'échelle mondiale.

  [Flux de données applicatif]
              │
              ▼
  [Pile TCP interne : D-SACK actif] ──> Signalement des doublons, appel Undo cwnd
              │
              ▼
  [Arbitre de flux RiceGuard] ──> Hachage eBPF RSS et tolérance au désordre
              │
              ▼
  [Moteur cryptographique AEAD] ──> Chiffrement haute performance ChaCha20-Poly1305
              │
              ▼
  [Réseau sous-jacent physique] ──> Stabilité sur chemins ECMP et liaisons 5G

RiceGuard renforce la robustesse de transport à travers trois leviers clés :

  1. Hachage cohérent des flux sous-jacents : les flux TCP internes sont associés à des ports UDP externes constants via des programmes eBPF, incitant les routeurs de transit à maintenir un chemin ECMP unique et minimisant les permutations.
  2. Adaptation dynamique aux perturbations : lors de variations d'acheminement, RiceGuard exploite D-SACK conjointement avec les algorithmes /news/tcp-rack-tlp-rfc-8985-time-based-loss-recovery-vpn et /news/tcp-early-retransmit-rfc-5827-small-window-rto-vpn, dissociant les pertes réelles des simples décalages temporels avec une précision extrême.
  3. Gestion des files et régulation de cadence : l'interaction entre D-SACK et le mécanisme Fair Queuing (FQ) élimine les blocages de tête de file et prévient les saturations de mémoires tampons, dans l'esprit des mécanismes analysés dans /news/tcp-hystart-plus-rfc-9406-bufferbloat-slow-start-vpn.

Diagnostic et audit : vérifier le fonctionnement de D-SACK sous Linux

Les ingénieurs système peuvent surveiller l'état et l'activité des mécanismes SACK et D-SACK sur les serveurs Linux grâce aux outils système natifs.

Surveillance en temps réel des métriques SACK et D-SACK via la commande ss

L'utilitaire ss inspecte les structures de contrôle TCP du noyau :

# Inspection approfondie des métriques TCP incluant SACK et D-SACK
ss -ti '( sport = :443 or dport = :443 )'

Indicateurs essentiels à relever :

  • sack : confirme que la négociation RFC 2018 SACK a abouti lors de la poignée de main initiale.
  • dsack_dups:<count> : nombre de segments dupliqués détectés et signalés via D-SACK.
  • reordering:<val> : seuil d'adaptation au désordre actuellement calibré par le noyau pour cette socket.
  • rcv_ooopack:<count> : cumul des paquets arrivés hors séquence placés en attente dans le tampon.

Paramètres noyau et configurations sysctl pour optimiser la pile SACK

L'audit de la configuration globale s'effectue via sysctl :

# Vérifier l'activation de SACK (1 = actif, par défaut)
sysctl net.ipv4.tcp_sack

# Vérifier l'activation de D-SACK (1 = actif, par défaut)
sysctl net.ipv4.tcp_dsack

# Consulter le seuil initial de reordering (valeur standard = 3)
sysctl net.ipv4.tcp_reordering

# Obtenir les statistiques cumulées SACK et D-SACK du système
cat /proc/net/netstat | grep -E "TCPDSACK|TCPSack"

Interprétation des compteurs dans /proc/net/netstat :

  • TCPDSACKRecv : blocs D-SACK reçus, confirmant que le correspondant a détecté une retransmission inutile.
  • TCPDSACKSent : blocs D-SACK émis pour prévenir le correspondant de la réception d'un doublon.
  • TCPDSACKUndo : annulations réussies de réduction de cwnd suite à la validation D-SACK.

Vérification en production et mesures de performance sous forte charge

Sur des tunnels VPN d'entreprise à haut débit exposés à des désordres de paquets fréquents, l'activation de la RFC 2883 D-SACK apporte des améliorations mesurables :

Indicateur SACK Standard (seuil fixe dupthresh=3) RFC 2883 D-SACK Activé Gain mesuré
Taux de fausses retransmissions Élevé (tout écart > 3 déclenche Fast Retransmit) Proche de zéro (seuil adaptatif) Réduction de 94 % des paquets redondants
Stabilité de la fenêtre cwnd Fluctuations constantes (réductions de 50 %) Stabilité remarquable (Undo cwnd immédiat) Débit de ligne maintenu en continu
Basculements 5G / Réseau mobile Rétablissement en 1,8 à 3,2 secondes Reprise instantanée (< 1 RTT) Réduction du jitter de 78 %
Débit utile agrégé du tunnel 420 Mbps (freiné par les baisses injustifiées) 940 Mbps (saturation de l'interface) Hausse de +123 % du débit effectif

En associant une notification explicite des doublons à une gestion dynamique des seuils de désordre, la RFC 2883 neutralise les effets néfastes du désordre des paquets pour en faire un événement transparent. Intégré aux protocoles réseau modernes, D-SACK assure un transport fluide et hautement résilient sur les infrastructures connectées.

Télécharger VPNRice.