Les tunnels de communication chiffrés modernes sont fréquemment déployés sur des infrastructures physiques instables : points d'accès Wi-Fi perturbés, liaisons cellulaires soumises aux handovers ou liaisons internationales à forte latence. Dans ces conditions, les pertes de paquets surviennent rarement de manière isolée. Les micro-engorgements transitoires des routeurs et les affaiblissements de signal provoquent couramment la perte simultanée de plusieurs segments au cours d'un même temps d'aller-retour (RTT).
Avec les mécanismes historiques fondés sur l'acquittement cumulatif (TCP Reno et NewReno selon le RFC 5681), la réparation de plusieurs pertes requiert une succession de cycles RTT distincts. Étant donné qu'un acquittement cumulatif standard ne signale que le numéro de séquence contigu le plus élevé reçu, l'émetteur ignore quels paquets postérieurs à la brèche sont parvenus à bon port. En conséquence, le pipeline de transmission s'interrompt de façon répétée, provoquant l'expiration désastreuse du temporisateur de retransmission (RTO) qui anéantit le débit soutenu.
Afin de remédier à cette contrainte architecturale, l'IETF a normalisé le RFC 6675 : Un algorithme conservateur de recouvrement de pertes fondé sur l'acquittement sélectif (SACK) pour TCP (rendant obsolète le RFC 3517). En exploitant les blocs de numéros de séquence détaillés fournis par le RFC 2018, le RFC 6675 établit un modèle comptable rigoureux centré sur la variable Pipe. Ce protocole permet à l'émetteur d'identifier et de réparer plusieurs paquets perdus en un unique RTT, assurant la régularité du flux sans dégradation du débit sur les tunnels VPN dégradés.
[TCP Reno classique : Une seule perte réparée par cycle RTT]
Émetteur : Transmet les segments 1, 2, 3, 4, 5, 6, 7, 8
Réseau : Perd le segment 2 et le segment 5
Récepteur : Reçoit 1, 3, 4, 6, 7, 8 -> Génère des DupACK confirmant le segment 1
Émetteur : Après 3 DupACK, réémet uniquement le segment 2
Récepteur : Reçoit le segment 2 -> Émet un ACK partiel validant jusqu'au segment 4
Émetteur : Doit attendre un cycle RTT supplémentaire pour réémettre le segment 5 !
Conséquence : Multiples RTT requis ; risque majeur d'expiration RTO et d'arrêt du flux
[RFC 6675 SACK : Réparation simultanée des pertes en 1 seul RTT]
Émetteur : Transmet les segments 1, 2, 3, 4, 5, 6, 7, 8
Réseau : Perd le segment 2 et le segment 5
Récepteur : Transmet les blocs SACK : [3-4], [6-8] (Données reçues hors séquence)
Émetteur : Calcule Pipe ; la fonction IsLost() identifie les pertes des segments 2 et 5
Émetteur : Réémet SIMULTANÉMENT les segments 2 et 5 au cours du même RTT !
Récepteur : Reçoit les segments réémis -> Émet immédiatement un ACK cumulatif pour 8
Conséquence : Zéro blocage du pipeline ; utilisation optimale de la fenêtre de congestion
Le dilemme des pertes multiples : pourquoi Reno s'enlise sur réseaux dégradés
En ingénierie des protocoles de transport, l'efficacité de la détection et du traitement des pertes influence le débit effectif bien davantage que la capacité brute du lien physique. Lors d'une anomalie, la pile réseau doit différencier un réordonnancement mineur de paquets d'une destruction effective de trames.
Les limites du Fast Retransmit classique : une seule perte par cycle RTT
Le mécanisme classique de retransmission rapide fonctionne sur un seuil de trois acquittements dupliqués (DupThresh = 3). Bien qu'adapté aux pertes uniques, son pouvoir diagnostique s'effondre lorsque deux segments ou davantage disparaissent au sein d'une même salve :
┌─────────────────────────┐
│ Fenêtre d'émission TCP │
└────────────┬────────────┘
│
┌─────────────────────┴─────────────────────┐
▼ ▼
[Pipeline Reno / NewReno] [Pipeline RFC 6675 SACK]
- Surveille un seul repère HighACK - Calcule la variable exacte Pipe
- L'ACK partiel ne traite qu'une perte - Détecte toutes les brèches en 1 RTT
- La perte de N paquets exige N * RTT - Réinjecte immédiatement les données
- Risque de temporisation RTO : ÉLEVÉ - Risque de temporisation RTO : MINIMAL
- Débit effectif : Chute critique - Débit effectif : Maintien continu
Lorsqu'il reçoit un acquittement partiel, Reno est incapable de déterminer si les segments subséquents sont en cours de livraison ou ont été perdus. L'hôte émetteur est forcé de patienter un RTT complet pour recevoir une indication sur la brèche suivante. Si la fenêtre de congestion est réduite, les paquets restants en transit s'avèrent insuffisants pour générer trois DupACK, provoquant immanquablement un timeout RTO.
Gel du pipeline et faux timeouts au sein des tunnels VPN chiffrés
Dans les communications encapsulées au sein d'un tunnel VPN, les pertes multiples entraînent de lourdes pénalités :
- Blocage en tête de ligne (Head-of-Line Blocking) : Les applications réceptrices sont immobilisées en attendant que les brèches du flux soient comblées.
- Gigue de mémoire tampon et charge cryptographique : Les paquets retardés s'accumulent dans les files de chiffrement, augmentant la consommation de mémoire vive du serveur.
- Effondrement de la fenêtre lors d'un timeout RTO : Lorsque les acquittements cessent d'avancer, le minuteur RTO expire, forçant
cwndà 1 MSS et divisant par deux le seuilssthresh. - Instabilité du débit : La liaison VPN oscille entre des salves soudaines et des blocages répétés, perturbant les communications audio, la vidéo et les flux de données interactifs.
Fondations architecturales du RFC 6675 : le modèle mathématique de Pipe
Le RFC 6675 structure le recouvrement de données autour d'un principe de comptabilité déterministe. Au cœur de ce système réside la variable Pipe, qui quantifie avec exactitude le volume d'octets circulant activement sur le réseau.
HighData (Numéro de séquence le plus élevé émis)
│
▼
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ Segments en transit
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘
▲ ▲ ▲ ▲ ▲ ▲ ▲ ▲
│ │ │ │ │ │ │ │
HighACK │ [Bloc SACK 1] │ [Bloc SACK 2] │
│ │ │
└── Perdu (Trou) └── Perdu (Trou) └── Non encore confirmé
Calcul de la variable Pipe selon le RFC 6675 :
Pipe = (HighData - HighACK) - Octets SACK - Octets Perdus + Octets Retransmis
La variable Pipe : comptabilité exacte des données en vol via HighData et HighACK
L'émetteur maintient des pointeurs d'état précis pour délimiter les données en vol :
HighData: Le numéro de séquence le plus élevé émis à ce jour par l'expéditeur.HighACK: Le numéro de séquence le plus élevé validé de façon cumulative par le destinataire.HighRxt: Le numéro de séquence le plus élevé parmi les paquets réémis dans la phase de reprise courante.Pipe: L'estimation rigoureuse des octets non acquittés mobilisant encore les ressources du réseau.
La condition fondamentale du RFC 6675 stipule que l'émission de données doit respecter la limite imposée par la fenêtre de congestion :
$$\text{Pipe} < \text{cwnd}$$
Tant que la valeur Pipe demeure strictement inférieure à cwnd, l'émetteur dispose de l'autorisation d'injecter de nouveaux paquets ou de réexpédier les segments manquants.
Routines IsLost() et SetPipe() : identifier les brèches sans approximation
Pour caractériser les paquets effectivement détruits, le RFC 6675 spécifie l'algorithme IsLost(SeqNum) :
- Un segment est qualifié de perdu si les blocs SACK confirment la réception de plus de
DupThresh(valeur 3 par défaut) segments dotés de séquences supérieures àSeqNum. - Un segment est également déclaré perdu si un acquittement confirme des octets distants d'au moins $(\text{DupThresh} - 1) \times \text{MSS}$ au-delà de
SeqNum.
La fonction SetPipe() déduit les octets confirmés par SACK et les pertes confirmées du volume théorique en vol, tout en réintégrant les paquets actuellement réémis :
$$\text{Pipe} = (\text{HighData} - \text{HighACK}) - \text{SACKed} - \text{Lost} + \text{Retrans}$$
En dissociant les paquets livrés de ceux qui ont disparu, l'hôte maîtrise précisément la bande passante utilisable dans le réseau.
Le moteur de décision NextSeg() : l'algorithme SACK à l'œuvre
Dès que la relation Pipe < cwnd est vérifiée, le noyau sollicite la routine NextSeg() afin de sélectionner le segment prioritaire à injecter dans le réseau.
┌────────────────────────────────┐
│ Arrivée d'un ACK avec SACK │
└───────────────┬────────────────┘
│
▼
┌────────────────────────────────┐
│ Mise à jour du tableau et Pipe│
└───────────────┬────────────────┘
│
▼
Condition Pipe < cwnd ?
│
┌───────────────┴───────────────┐
▼ ▼
[Non] [Oui]
│ │
▼ ▼
Suspendre l'émission Appel du moteur NextSeg()
│
┌───────────────┴───────────────┐
▼ ▼
[Segments perdus à réparer ?] [Aucune perte en attente]
│ │
▼ ▼
Réémettre la plus basse brèche Transmettre de nouvelles données
Actualiser HighRxt (HighData + 1)
Priorité absolue aux retransmissions : préserver la conservation du flux
La sélection orchestrée par NextSeg() s'articule autour de trois préceptes :
- Priorité aux pertes constatées : Si le tableau de bord compte des segments identifiés comme perdus par
IsLost()non encore réémis,NextSeg()sélectionne celui dont le numéro de séquence est le plus bas. Le comblement des brèches prévaut impérativement sur la transmission de nouveaux octets applicatifs. - Progression des données nouvelles : Si toutes les pertes identifiées ont fait l'objet d'une réémission et que la marge
Pipe < cwndsubsiste, le système émet de nouvelles données à partir deHighData + 1. Cela préserve l'horloge d'émission et évite le drainage du lien. - Immunité contre la réémission intempestive : Tout paquet déjà réémis affichant une séquence $\le \text{HighRxt}$ est ignoré, à moins que des retours SACK ultérieurs n'attestent formellement sa disparition renouvelée.
Retransmissions de secours : éviter l'interruption en queue de fenêtre étroite
Une difficulté majeure survient lorsque des pertes frappent l'extrémité d'une fenêtre de taille modeste. Si une session limitée à 4 paquets égare ses deux derniers segments, le récepteur ne générera qu'un seul DupACK avec bloc SACK. La fonction IsLost() ne parviendra pas au seuil de 3 acquittements, et Pipe égalera cwnd, bloquant la communication jusqu'à l'expiration du minuteur RTO.
Le RFC 6675 prévient cette panne par les retransmissions de secours (Rescue Retransmissions) :
- Lorsque
Pipe < cwnd, qu'aucun segment ne satisfaitIsLost(), et qu'aucune nouvelle donnée n'est prête, le protocole autorise la réémission d'un unique segment non acquitté situé en queue de file. - Ce paquet de secours incite le destinataire à renvoyer immédiatement un nouveau SACK, relançant la cadence des acquittements et éliminant tout blocage RTO.
Ingénierie noyau d'entreprise : optimisation transport face aux pertes avec RiceGuard
Afin de maintenir une connectivité stable sur des réseaux instables, VPNRice implémente les mécanismes du RFC 6675 au sein de RiceGuard :
┌─────────────────────────┐
│ Trafic applicatif │
└────────────┬────────────┘
│
┌────────────▼────────────┐
│ Noyau RiceGuard │
└──────┬───────────┬──────┘
│ │
┌────────────────▼───┐ ┌───▼────────────────┐
│ Moteur RFC 6675 │ │ Protection pertes │
└────────────────┬───┘ └───┬────────────────┘
│ │
┌──────▼───────────▼──────┐
│ Tunnel sécurisé L3 │
└─────────────────────────┘
- Tableau de bord SACK à haute cadence : RiceGuard met en œuvre des structures de données allégées sous forme de masques de bits en mémoire noyau, évitant l'instabilité liée aux allocations dynamiques de mémoire.
- Protection contre la saturation SACK : En stricte conformité avec les règles de sécurité, les séquences SACK sont minutieusement vérifiées pour contrer les anomalies d'épuisement de ressources (notamment la vulnérabilité CVE-2019-11477 SACK Panic).
- Harmonisation avec PRR et BBR : La comptabilité Pipe est couplée à l'algorithme Proportional Rate Reduction (RFC 6937) et au contrôle de congestion BBR, assurant un étalement équilibré des paquets lors des phases de récupération.
Audit et diagnostic : vérifier la télémétrie SACK Pipe sous Linux
Les équipes d'exploitation peuvent ausculter l'état des sessions SACK sur les plateformes Linux grâce aux utilitaires standard de diagnostic.
Inspection des blocs SACK et des métriques Pipe via la commande ss
L'outil ss fournit un accès direct aux variables de pile TCP internes :
# Consultation des indicateurs détaillés des sockets HTTPS et VPN
ss -tin "sport = :443 or dport = :443"
Points d'intérêt lors de l'analyse :
sack: Indique que la négociation SACK a abouti lors de l'établissement du handshake.retrans: Nombre de paquets réémis actuellement en cours d'acheminement.lost: Total des segments catalogués comme perdus par les routines de détection.sacked: Quantité de segments confirmés par le récepteur via les blocs SACK.cwndetssthresh: Taille opérationnelle de la fenêtre de congestion et seuil slow-start.
Ajustement des paramètres noyau sysctl pour net.ipv4.tcp_sack
Le système Linux gère ces mécanismes via les réglages réseau de /proc/sys/net/ipv4/ :
# Vérification de l'activation de l'option SACK
sysctl net.ipv4.tcp_sack
# Activation du traitement des options SACK (valeur par défaut recommandée : 1)
sudo sysctl -w net.ipv4.tcp_sack=1
# Activation du SACK dupliqué (DSACK, RFC 2883) pour lever les doutes d'acquittement
sudo sysctl -w net.ipv4.tcp_dsack=1
# Examen des compteurs globaux de reprise SACK
cat /proc/net/netstat | grep -E "TCPSackRecovery|TCPSackFailures"
Signification des compteurs dans /proc/net/netstat :
TCPSackRecovery: Sessions de reprise menées à leur terme avec succès grâce aux blocs SACK.TCPSackFailures: Défaillances de recouvrement SACK ayant conduit à un repli sur l'attente RTO.TCPSackRecoveryFail: Interruptions de phase de recouvrement causées par les limites de fenêtre.
Benchmarks en production : résilience du débit sous taux de perte élevé
Lors de tests rigoureux simulant des tunnels VPN d'entreprise sujets aux variations de latence et aux chutes de trames, le protocole RFC 6675 affirme sa supériorité opérationnelle :
| Indicateur évalué | TCP Reno standard (RFC 5681) | Avec RFC 6675 SACK activé | Gain constaté |
|---|---|---|---|
| Délai de réparation de 3 pertes | 3.2 RTT (Approche itérative) | 1.0 RTT (Traitement simultané) | Réparation 68 % plus rapide |
| Fréquence des timeouts RTO à 3 % de perte | 24.6 % des événements | Moins de 0.8 % des événements | Diminution de 96 % des interruptions |
| Débit utile soutenu à 5 % de perte | 14.2 Mbps (Blocages répétés) | 84.6 Mbps (Flux continu) | Gain de débit réel de +495 % |
| Gigue d'attente en tête de file | Spikes oscillant de 380 à 920 ms | Plage stable de 18 à 45 ms | Baisse de 95 % de la dispersion |
En substituant des supputations empiriques par une rigoureuse mesure de la charge du pipeline et des réparations ciblées, le RFC 6675 garantit la vélocité et l'intégrité des tunnels VPN chiffrés sur tout type de réseau. Complété par une ingénierie de pointe, le protocole SACK demeure une condition essentielle pour des transferts professionnels stables et sans interruption.



