Encapsuler un flux de transport fiable au sein d'un autre flux de transport fiable peut sembler une démarche naturelle au premier abord. De nombreux administrateurs et utilisateurs configurent couramment des tunnels VPN via le port TCP 443 pour franchir des pare-feu stricts ou des proxys d'entreprise qui bloquent les datagrammes UDP bruts. Cependant, emboîter TCP dans TCP introduit un mode de défaillance critique des systèmes distribués, connu sous le nom de meltdown TCP-over-TCP (l'effondrement par empilement TCP).

Dans les conditions réelles des réseaux, sujettes aux fluctuations de gigue (jitter) et aux pertes de paquets, les deux boucles de rétroaction de TCP entrent en conflit direct. Loin de fiabiliser la liaison, l'indépendance de leurs temporisateurs de retransmission provoque un engorgement massif des files d'attente, un recul exponentiel des débits et un effondrement brutal de la bande passante utile. L'étude de ce mécanisme démontre pourquoi les architectures VPN modernes — comme WireGuard et RiceGuard de VPNRice — recourent impérativement à des datagrammes UDP au niveau de la couche réseau (Layer 3).

Le problème des deux boucles de contrôle indépendantes

Le protocole TCP a été conçu selon le principe de bout en bout (end-to-end principle). La couche de transport suppose que le support physique sous-jacent n'est pas fiable (les paquets IP peuvent être altérés, perdus ou désordonnés) et garantit la livraison ordonnée des données à l'aide de numéros de séquence, d'acquittements (ACK), de fenêtres glissantes et d'algorithmes de régulation de congestion (tels que CUBIC ou BBR).

Lorsqu'un tunnel VPN emploie TCP comme protocole de transport, il superpose sur le même lien physique deux boucles de contrôle autonomes et non coordonnées :

+-------------------------------------------------------------------------+
|                  Conflit des deux boucles de contrôle TCP               |
+-------------------------------------------------------------------------+
| Couche applicative : requêtes HTTPS, sessions SSH, flux multimédia      |
|   |                                                                     |
|   v                                                                     |
| [ Boucle TCP interne (Inner Loop) ]                                     |
|   - Numéros de séquence, estimation du RTT applicatif, timer RTO        |
|   - Fenêtre de congestion (cwnd) régulée par les transferts applicatifs |
|   |                                                                     |
|   v (Encapsulée comme charge utile dans l'interface du VPN)             |
| [ Boucle TCP externe (Outer Loop) ]                                     |
|   - Opère sur le support physique (Wi-Fi, 4G/5G, fibre)                 |
|   - Numéros de séquence propres, RTT physique et timer RTO externe      |
|   - Réordonne, met en mémoire tampon et réémet les paquets perdus       |
+-------------------------------------------------------------------------+

Lorsqu'un paquet physique unique vient à être perdu sur la liaison, les deux boucles adoptent des comportements antagonistes :

  1. La couche externe tente la récupération : Dès qu'elle détecte la perte (via des ACK dupliqués ou l'expiration de son RTO), la connexion externe suspend la transmission des données ultérieures vers l'interface virtuelle et réémet une demande de retransmission sur le réseau physique.
  2. Injection d'une latence artificielle : Tant que le paquet manquant n'est pas parvenu à la couche externe, l'interface du tunnel ne peut délivrer les octets suivants à l'application en raison de l'obligation de livraison ordonnée. Le temps d'aller-retour (RTT) perçu par le TCP interne bondit instantanément de quelques millisecondes à plusieurs secondes.
  3. Déclenchement du temporisateur interne : Le temporisateur de retransmission (RTO - Retransmission Timeout) du TCP interne, calculé lors d'une période de faible latence, expire avant que le TCP externe n'ait pu achever sa réparation sur le réseau physique.
  4. Injection de doublons inutiles : Croyant que ses données ont disparu sur Internet, l'application réémet elle-même un exemplaire identique de son paquet.
  5. Saturation en cascade des files d'attente : Le TCP externe accepte ce paquet dupliqué comme une nouvelle charge utile ordinaire et l'accumule en fin de file d'attente, derrière les paquets déjà en souffrance.

Anatomie d'un meltdown : l'avalanche de retransmissions

L'effondrement progresse d'une simple perte de paquet vers la paralysie complète de la session selon un enchaînement mathématique prévisible.

+-------------------------------------------------------------------------+
|                     Chronologie de l'avalanche de retransmissions       |
+-------------------------------------------------------------------------+
| Lien physique : perte accidentelle du paquet #10                        |
|                                                                         |
| TCP externe :                                                           |
|   - Détecte la perte -> Gèle le flux -> Passe en Fast Retransmit        |
|   - La mémoire tampon bloque les paquets #11, #12, #13 en attente du #10|
|                                                                         |
| TCP interne (session applicative) :                                     |
|   - Attend l'acquittement (ACK) de son paquet #4                        |
|   - Le timer RTO interne expire (ex. au bout de 200 ms)                 |
|   - La fenêtre de congestion s'effondre : cwnd = 1 MSS                  |
|   - Réémet le paquet #4 -> Injecté dans la file du TCP externe          |
|                                                                         |
| Le TCP externe reçoit la réparation du paquet #10 :                     |
|   - Délivre le paquet original #4 à l'application                       |
|   - Se trouve désormais contraint d'expédier le paquet #4 dupliqué      |
|                                                                         |
| Résultat : Bufferbloat, doublement du RTO, débit utile écroulé          |
+-------------------------------------------------------------------------+

La dérive mathématique du temporisateur RTO

Selon la norme RFC 6298, le RTO est ajusté en continu d'après le temps d'aller-retour lissé (SRTT) et sa variance (RTTVAR) :

$$\text{RTO} \leftarrow \text{SRTT} + \max(G, 4 \cdot \text{RTTVAR})$$

En situation de perte sur la couche externe, le délai total subi par la couche interne s'écrit :

$$\text{RTT}{\text{interne, effectif}} = \text{RTT}{\text{externe}} + \text{Délai de retransmission externe}$$

Ce délai de retransmission externe dépassant fréquemment le $\text{SRTT}$ de base de l'application, le RTO interne s'active prématurément. À chaque tentative infructueuse, TCP applique un recul binaire exponentiel (Exponential Backoff) :

$$\text{RTO}{\text{suivant}} = 2 \cdot \text{RTO}{\text{actuel}}$$

Les deux couches s'enferment simultanément dans des temporisations croissantes. La fenêtre de transmission interne tombe à 1 segment maximal (1 MSS), tandis que le tampon de sortie externe se remplit de répliques superflues qui saturent la bande passante physique.

Le blocage en tête de ligne (Head-of-Line Blocking)

En conditions courantes, de multiples applications se partagent le même tunnel VPN :

  • Les résolutions de noms DNS
  • Les appels audio et visioconférences WebRTC
  • Les sessions de terminal SSH et le trafic web interactif

Lorsqu'un tunnel repose sur TCP, la perte d'un segment d'un simple téléchargement d'arrière-plan bloque sans exception l'ensemble des flux simultanés. Le noyau du système d'exploitation ne peut remettre les octets reçus aux autres programmes tant que le segment externe manquant n'a pas été reconstitué. Le son se hache, le terminal se fige et les requêtes web échouent par dépassement de délai.

Confrontation : tunnel TCP contre tunnel UDP Layer 3

Les protocoles modernes adoptent l'encapsulation en datagrammes UDP au niveau de la couche réseau, séparant hermétiquement le transport brut de la logique de fiabilité.

+-------------------------------------------------------------------------+
|                  Comparatif des tunnels TCP et UDP Layer 3              |
+-------------------------------------------------------------------------+
| Critère                | Tunnel TCP            | Tunnel UDP (WireGuard) |
|------------------------|-----------------------|------------------------|
| Modèle de transport    | Flux d'octets fiable  | Datagrammes autonomes  |
| Gestion de congestion  | Deux boucles rivales  | Boucle unique finale   |
| Réaction aux pertes    | Retransmission externe| Abandon et acheminement|
| Blocage de ligne (HoL) | Paralysie globale     | Isolé par application  |
| Résistance au jitter   | Vulnérabilité majeure | Immunité totale        |
| Roaming mobile         | Rupture de socket     | Sans état (0 ms)       |
| Flux en temps réel     | Dégradation audio/vidéo| Maintien de faible latence|
+-------------------------------------------------------------------------+

La supériorité de l'UDP : préserver l'autonomie des paquets

Avec l'encapsulation en datagrammes UDP (appliquée dans WireGuard, IPsec ESP et RiceGuard) :

  • Aucune retransmission dans le tunnel : L'interface virtuelle n'analyse pas l'ordre des trames, ne gère pas d'acquittements et ne réémet aucun datagramme égaré.
  • Maîtrise exclusive par l'application : Si une application requiert une garantie de livraison (comme HTTPS), sa propre pile TCP gère les pertes de manière unifiée de bout en bout. Le réseau ne comporte qu'une seule boucle de contrôle.
  • Préservation des flux temps réel : Les requêtes DNS, les paquets vocaux et le protocole HTTP/3 QUIC transitent immédiatement sans subir les retards liés à d'autres connexions.

Constat sur le terrain par analyse de trames tcpdump

L'observation d'un trafic TCP dans TCP sous 2 % de perte de paquets simulée via tcpdump illustre parfaitement le mécanisme d'écroulement :

# Analyse de trames : collision des retransmissions en cascade
14:10:01.102341 IP client.45210 > vpn.443: Flags [P.], seq 1024:2472, ack 1
14:10:01.102410 IP client.45210 > vpn.443: Flags [P.], seq 2472:3920, ack 1
14:10:01.182105 IP vpn.443 > client.45210: Flags [.], ack 1024, win 65535, options [sack 1 {2472:3920}]
14:10:01.182190 IP client.45210 > vpn.443: Flags [P.], seq 1024:2472, ack 1  <-- Retransmission externe
14:10:01.382410 IP client.45210 > vpn.443: Flags [P.], seq 3920:5368, ack 1  <-- RTO interne échu (Doublon)
14:10:01.782890 IP client.45210 > vpn.443: Flags [P.], seq 5368:6816, ack 1  <-- Temporisation à 400 ms

Les données révèlent :

  1. L'option SACK signale la perte du segment 1024:2472 sur la liaison physique.
  2. La couche externe lance la réémission à 14:10:01.182.
  3. Pendant ce temps, le timer de 200 ms de l'application interne s'épuise à 14:10:01.382, envoyant un doublon inutile.
  4. L'envolée des timers vers 400 ms puis 800 ms paralyse l'ensemble des échanges.

Franchir les réseaux restreints sans subir de meltdown

Lorsque les datagrammes UDP sortants sont systématiquement filtrés par un réseau d'entreprise, le recours à un port TCP devient temporairement incontournable. Des arbitrages techniques permettent d'en atténuer les effets néfastes :

  • Désactivation de l'algorithme de Nagle (TCP_NODELAY) : Empêche le socket externe de retenir les petits paquets, éliminant les micro-pauses indésirables.
  • Calibrage strict des mémoires tampons de socket : Réduire la taille des tampons d'écriture empêche le tunnel d'engranger trop de doublons et transmet immédiatement la pression à l'application d'origine.
  • Sondage et retour dynamique vers UDP : L'application VPN teste en permanence la réouverture du passage UDP en tâche de fond pour réorienter la session vers le mode sans état dès que possible.

L'ingénierie Layer 3 de VPNRice

Le moteur réseau RiceGuard de VPNRice est architecturé autour de la dissociation des datagrammes au niveau de la couche 3, éliminant tout risque de meltdown :

  1. Routage UDP natif par défaut : L'ensemble du trafic IP est encapsulé dans des datagrammes indépendants, conférant aux applications une maîtrise intégrale de leur rythme de transmission.
  2. Éradication des blocages de file d'attente : Les résolutions DNS, la voix et la navigation web circulent sur des flux étanches qui ne subissent aucun ralentissement croisé.
  3. Continuité de service en mobilité : Le routage cryptographique permet à l'appareil de basculer du Wi-Fi à la 5G sans réinitialisation de socket ni coupure des sessions actives.

Télécharger VPNRice.