12 points par GN⁺ 2025-08-02 | 1 commentaires | Partager sur WhatsApp
  • Le premier patch intégrant officiellement le protocole QUIC au noyau Linux a été soumis
  • L’objectif est d’améliorer plusieurs limites de TCP (latence, head-of-line blocking, ossification du protocole due aux équipements intermédiaires, etc.)
  • QUIC, basé sur UDP, prend en charge le multistream et le chiffrement de bout en bout, et son intégration au noyau pourrait élargir son usage sur davantage de plateformes et de matériels
  • Les performances de l’implémentation initiale dans le noyau ont été mesurées comme inférieures à celles de TCP existant et de kernel TLS, mais des gains sont attendus avec le hardware offloading et les optimisations à venir
  • Le support est actuellement activement discuté dans Samba, SMB/NFS basés sur le noyau, curl et d’autres projets, mais l’intégration dans la branche principale devrait encore prendre du temps

Contexte de l’émergence de QUIC et limites de TCP

  • QUIC a été conçu pour résoudre divers problèmes de TCP sur l’Internet actuel
  • L’expérience web se dégrade à cause de la latence induite par le 3-way handshake de TCP, de l’absence de bon support du multistream et du phénomène de head-of-line blocking en cas de perte de paquets
  • Les métadonnées de TCP sont transmises sans chiffrement, ce qui crée un risque de fuite d’informations, et les middleboxes de l’Internet filtrent le trafic à partir des informations de connexion, ce qui a conduit à l’ossification du protocole
  • Les tentatives d’amélioration de TCP (par exemple Multipath TCP) ne fonctionnent correctement que si elles se font passer pour du TCP classique

Caractéristiques de QUIC et avantages techniques

  • QUIC fonctionne au-dessus de UDP et peut établir une connexion rapidement, sans 3-way handshake séparé lors du processus de connexion
  • Son architecture de transmission multistream évite qu’une perte de paquets n’affecte l’ensemble des flux
  • Les données de transport liées à QUIC sont toujours chiffrées de bout en bout (sur la base de TLS), empêchant les équipements intermédiaires d’accéder aux messages internes
  • Dans tout environnement réseau où les paquets UDP peuvent circuler, QUIC peut lui aussi fonctionner normalement

Aperçu du patch d’intégration de QUIC dans le noyau Linux

  • Le patch soumis introduit un nouveau type de protocole, IPPROTO_QUIC, permettant d’utiliser l’appel système socket() existant
  • Comme avec TCP, on peut utiliser les appels bind(), connect(), listen() et accept(), mais le traitement ultérieur présente des différences
  • La gestion de session TLS ainsi que les processus d’authentification et de chiffrement sont pris en charge dans l’espace utilisateur, et l’handshake TLS doit être terminé à chaque extrémité après l’établissement de la connexion avant de pouvoir échanger des données
  • Après la connexion initiale, le résultat de la négociation TLS peut être mis en cache, ce qui accélère fortement les reconnexions entre deux systèmes

Défis de performances et perspectives

  • L’implémentation de QUIC dans le noyau qui a été soumise reste pour l’instant en retrait, en termes de performances, par rapport à kernel TLS et TCP
    • Un débit inférieur d’un facteur pouvant aller jusqu’à 3 par rapport à l’in-kernel TLS, et jusqu’à 4 fois inférieur à TCP même quand le chiffrement est désactivé
  • Parmi les causes avancées figurent l’absence de prise en charge du segmentation offloading, des copies de données supplémentaires dans le chemin d’émission et le processus de chiffrement des en-têtes
  • On s’attend à une amélioration des performances à mesure que le support du hardware offloading sera ajouté et que l’implémentation in-kernel sera optimisée

Adoption actuelle et perspectives

  • Les discussions autour du support in-kernel de QUIC sont actives dans de nombreux projets, notamment les serveurs/clients Samba, les systèmes de fichiers SMB et NFS du noyau, ainsi que curl
  • Le patch représente environ 9 000 lignes et ne contient pour l’instant que du code de support bas niveau. L’implémentation complète est annoncée dans des patchs supplémentaires
  • Les discussions de revue de code et d’intégration viennent tout juste de commencer, et son usage réel demandera encore du temps
    • Sachant que l’intégration du protocole Homa dans le noyau a récemment nécessité 11 soumissions sur 9 mois, l’entrée de QUIC dans la branche principale n’est pas attendue avant 2026 au plus tôt

1 commentaires

 
GN⁺ 2025-08-02
Commentaire Hacker News
  • J’ai récemment ajouté ssl_preread_server_name à une configuration NGINX pour proxy_pass les requêtes de certains domaines vers une autre instance NGINX
    La première instance ne fait que transmettre le flux TLS brut (avec proxy_protocol), et la seconde se charge de la terminaison TLS réelle
    Cette approche est efficace pour mettre en place un basculement : si le chemin principal du serveur tombe, on met à jour l’enregistrement DNS A vers le NGINX de la machine de secours, et cette instance route ensuite les requêtes de certains domaines vers le backend d’origine via un chemin séparé
    C’est pratique car il n’est pas nécessaire de dupliquer toute la configuration TLS
    En revanche, cette méthode n’est pas applicable à HTTP/3
    HTTP/3 repose sur QUIC, fonctionne sur UDP, et chiffre le SNI pendant le handshake, donc impossible de faire un routage par domaine avec ssl_preread_server_name
    Je me demande s’il existe une alternative pour prendre en charge le routage basé sur le SNI avec HTTP/3, ou s’il faut rester sur HTTP/1.1 ou HTTP/2 over TLS si l’on a besoin de cette fonctionnalité
    • La plupart des clients qui prennent en charge QUIC prennent aussi en charge les enregistrements DNS HTTPS, donc il est possible d’ajouter un enregistrement de priorité plus basse pour le basculement et de laisser le client gérer
      En pratique, le comportement varie selon l’implémentation du client (voir l’état du support des enregistrements HTTPS dans Chromium, lien vers l’issue), mais si une connexion QUIC échoue, le client bascule de manière transparente vers HTTP/1.1/2, tout en respectant aussi l’en-tête Alt-Svc
      Pour un basculement planifié, on peut aussi cesser d’envoyer l’en-tête Alt-Svc et attendre qu’un timeout se produise vers l’instance alternative
      Si le routage QUIC est vraiment nécessaire, heureusement les informations SNI sont toujours présentes dans le premier paquet, donc un routage par inspection de paquets est possible
      Le udpgrm de Cloudflare peut servir de référence, et cela fonctionne tant qu’il n’y a pas d’ECH (Encrypted Client Hello)
      En présence d’ECH, le routeur doit disposer de la clé de déchiffrement pour pouvoir prendre une décision de routage, et il est aussi possible de concevoir un basculement en cascade au niveau du protocole
      On peut voir une implémentation concrète dans cet exemple udpgrm
    • Terminer TLS directement à l’edge (par exemple NGINX) n’est plus vraiment un point de risque majeur aujourd’hui dans un environnement letsencrypt
      Si un attaquant accède à ce serveur, il lui est de toute façon facile d’émettre de nouveaux certificats SSL, donc au lieu de compliquer les choses avec un système de basculement sophistiqué, il est probablement plus rationnel de terminer TLS directement
      Personnellement, je n’ai jamais réussi à reproduire moi-même les gains de performance ou de fiabilité de QUIC
      Je fais des tests depuis des années, mais je finis généralement par le désactiver pour des raisons de performance
      Le basculement basé sur le DNS aussi met en pratique plusieurs minutes à se propager, et pour des clients simples comme les navigateurs, le basculement se produit mal
      Du coup, j’utilise directement un gestionnaire onerror pour charger un second chemin
      Par exemple, j’utilise ce type de code pour le suivi publicitaire, et j’expose aussi fetch de la même façon via un wrapper
      Cette méthode est de loin la plus efficace parmi toutes celles que j’ai essayées
    • Dans un environnement de basculement, je ne me préoccuperais pas du basculement QUIC
      Même si le navigateur échoue à établir une connexion QUIC (y compris si elle est annoncée dans le DNS), il revient automatiquement à HTTP/1 ou HTTP/2 over TLS, donc on peut conserver exactement la même stratégie de basculement
    • Cela relève du type de problème « ce n’est pas un bug »
      L’une des caractéristiques de conception de HTTP/3 est précisément de ne pas exposer les informations de l’endpoint jusqu’à la couche TLS
      Personnellement, je vois cela comme un avantage
      HAProxy peut faire du proxy TLS brut, mais pas du routage basé sur le nom d’hôte
      Cloudflare tunnel dispose d’une fonctionnalité particulière qui permet un routage par nom d’hôte sans terminaison TLS, mais pour l’utiliser il faut aussi relier le DNS à Cloudflare
      Voir la BD xkcd associée
    • Question intéressante
      Je me demande si la même limite existe aussi dans un environnement TCP+TLS lorsqu’Encrypted Client Hello est utilisé
      Je pense que la réponse serait à peu près la même
  • Je me souviens depuis longtemps de ce billet sur les inconvénients de QUIC
    J’ai l’impression que cette discussion va justement dans le sens d’une résolution progressive de ce type de problèmes
    À l’avenir, un support matériel au niveau des cartes réseau pourrait aussi devenir possible
    • QUIC n’est pas très adapté au trafic machine à machine
      En revanche, comme la majorité du trafic Internet circule aujourd’hui entre mobiles et serveurs, c’est sur ce segment que QUIC et HTTP/3 montrent vraiment leur intérêt
      Pour les autres usages, on peut très bien continuer à utiliser TCP
  • Je suis curieux de voir à quoi ressemblera l’API socket pour les flux multiples
    Elle donnera sans doute l’impression de plusieurs connexions comme aujourd’hui, tout en étant mise en cache en interne
    Personnellement, j’aimerais bien recevoir explicitement un objet connexion et ouvrir les flux séparément, mais pour l’instant l’approche actuelle me va aussi
    D’après cette discussion, si ce n’est pas une extension, alors le serveur peut lui aussi créer de nouveaux flux après l’établissement de la connexion
    Côté client, comme il s’agit en réalité de flux, il est difficile de les abstraire comme des « connexions » distinctes, et il semble qu’une abstraction API entièrement nouvelle soit nécessaire au fond
    J’imagine probablement une structure où un nouveau descripteur de fichier est reçu via recvmsg pour chaque nouveau flux
    • La fonctionnalité multi-flux est déjà prise en charge par l’API socket SCTP, donc l’interface SCTP peut servir de référence
  • Indépendamment de l’implémentation noyau, j’aimerais bien voir un support de QUIC dans OpenSSH
    J’aimerais avoir la robustesse de Mosh face aux problèmes réseau, tout en conservant toutes les fonctionnalités d’OpenSSH (SFTP, SOCKS, port forwarding, gestion d’état, roaming, etc.)
    Je me demande si OpenSSH pourrait exploiter un support au niveau du noyau
    Voir Mosh
    • SSH devrait remplacer entièrement sa couche de chiffrement et de multiplexage par QUIC, donc cela représenterait un chantier de grande ampleur
      Il vaudrait sans doute mieux créer un protocole de connexion séparé basé sur QUIC
      Plusieurs approches sont en cours au stade du prototype
    • OpenSSH est un projet OpenBSD, donc il est possible qu’il ne se soucie pas beaucoup d’une API Linux
  • On dit que le goulot d’étranglement de TCP vient du handshake, mais il me semblait que la réutilisation de connexion ou le multiplexage réglaient déjà cela
    Pourtant, on dit que l’implémentation noyau actuelle de QUIC est 3 à 4 fois plus lente que Linux, tout en ajoutant que l’écart de performances devrait bientôt se réduire
    Si la vitesse est censée être l’avantage de QUIC, pourquoi l’utiliser s’il est en pratique plus lent ?
    L’auteur de la PR dit aussi qu’une partie de la dégradation des performances vient de la conception même du protocole ; y a-t-il donc encore quelque chose à corriger séparément dans TCP ?
    • L’article mentionne justement de nombreuses raisons pour lesquelles QUIC est lent
      En gros, cela se résume à « ce n’est pas encore optimisé »
      Par exemple, absence de segmentation offload, copies de données supplémentaires sur le chemin de transmission, surcoût lié au chiffrement des en-têtes, etc., et tout cela a de fortes chances d’être corrigé
      Ici, les benchmarks ont été réalisés dans un environnement très idéal
      En réalité, dans un environnement mobile, la variabilité du réseau est forte, ce qui met en évidence les limites structurelles de TCP
      En pratique, on implémente déjà souvent au-dessus de TCP des fonctionnalités proches de QUIC, comme avec HTTP/2
      Au fond, QUIC est une pile réseau complète qui opère à partir de la couche 5 du modèle OSI, tandis que TCP est plutôt un moteur de couche 3, donc la comparaison structurelle est difficile
      Surtout, l’un des avantages de QUIC est l’établissement et le rétablissement plus rapides des connexions, avec continuité de session même lors de changements d’IP
      Sa structure en flux multiplexés et non bloquants simplifie radicalement la conception des protocoles de plus haut niveau
      Une fois cette structure intégrée au noyau, la marge d’optimisation des performances devient énorme
      À l’avenir, au lieu d’empiler des solutions multicouches sur les limites de TCP, il faudra probablement utiliser bien plus souvent au quotidien des bases avancées comme QUIC
    • Le goulot d’étranglement de TCP ne se limite pas au handshake
      Lorsqu’il y a perte de paquets, tout ce qui suit est retardé jusqu’à récupération complète de la transmission (HOL blocking), ce qui constitue une limite structurelle importante
    • On ne peut pas réutiliser une « connexion inexistante », donc beaucoup de discussions se concentrent sur la réduction de la latence
      Ce n’est pas seulement une question de débit, mais bien d’amélioration de la latence
    • L’un des avantages de QUIC est le suivi basé sur un connection ID fourni par le serveur
      Voir ce document technique
  • Je suis un peu perdu entre le message consistant à dire qu’on améliore les performances en déplaçant la pile réseau en espace utilisateur, et cette discussion qui propose au contraire de la déplacer côté noyau
    • La plupart des piles QUIC fonctionnent sur UDP dans le noyau
      Le principal goulot d’étranglement vient des changements de contexte entre noyau et espace utilisateur
      Le user-space networking (par exemple l’accès direct à la NIC) élimine les entrées dans le noyau
      À l’inverse, fournir des fonctionnalités dans l’espace noyau (par exemple sendfile, in-kernel TLS, NIC offloading, DMA direct du disque vers la NIC) réduit lui aussi les changements de contexte globaux et les copies de données
      Les piles QUIC actuelles ne profitent réellement d’aucun des deux avantages
      L’entrée/sortie des paquets repose sur des syscalls, et il reste impossible d’éviter les copies de données
      Avec de l’I/O batchée comme io_uring, on réduit les changements de contexte, mais pas les copies elles-mêmes
    • Exactement
      Il y a soit l’approche kernel bypass + DMA, soit l’approche de type sendfile/ktls qui exclut l’espace utilisateur, et l’implémentation noyau de QUIC ne bénéficie d’aucun des deux avantages
    • Au final, il faut toujours remettre les données dans le buffer de la NIC
      Si l’on peut écrire directement dans la NIC via DMA ou si l’on passe par un syscall noyau, la différence de performances est importante
      Le user-space networking n’est vraiment convaincant que lorsqu’on dispose de ce type de transition de privilège et de structure DMA
    • Le fait que l’espace utilisateur accède directement aux données réseau, probablement sans syscall, n’a pas beaucoup d’intérêt pour les logiciels grand public
      Cela n’est vraiment exploité que par de très grandes entreprises (MOFAANG, etc.)
      En théorie, on espère que io_uring généralisera ce type d’avantages, mais ce n’est pas encore mûr pour un usage réel
    • Les changements de contexte sont trop lents lorsqu’il s’agit d’accès matériel
      C’est pour cela que TCP/IP reste dans le noyau des principaux OS
  • « Pourquoi met-on de plus en plus de fonctionnalités dans le noyau ? »
    J’avais l’impression que le rôle du noyau était la gestion de la mémoire, du matériel et des tâches ; n’est-il pas plus logique de traiter les protocoles au-dessus d’IP en userland ?
    • Gérer le réseau, le routage, les VPN, etc. dans l’espace noyau améliore les performances dans certains cas d’usage
      À l’inverse, séparer ces piles en espace utilisateur peut aussi améliorer les performances dans certains autres cas
    • Une intégration au noyau apporte les avantages du hardening, du support LTS, ainsi que des optimisations au niveau du noyau et du réseau
    • La raison principale tient aux optimisations autour des transferts DMA et du NIC offloading
    • Si l’on place tous les protocoles au-dessus d’IP en espace utilisateur, l’usage multi-processus devient impossible
      Comme TCP/UDP arbitrent dans le noyau le routage des sockets sur la base des ports, plusieurs programmes peuvent utiliser TCP/UDP simultanément
      QUIC fonctionne au-dessus d’UDP, donc l’argument de cette discussion reste malgré tout pertinent
      Cela souligne surtout qu’on ne peut pas faire fonctionner en espace utilisateur uniquement des protocoles situés directement au-dessus d’IP
  • Je pense que QUIC représente un changement majeur pour beaucoup de monde
    J’espère que l’Internet sera un peu plus rapide à l’avenir
    Dans des environnements comme la 5G, on ne ressentira peut-être pas vraiment la différence, mais cela reste une avancée utile
    Je trouve intéressant qu’il existe une structure de handshake distincte au niveau du lien
    Ce n’est pas tout à fait ce que j’imaginais, moi qui pensais que QUIC intégrait TLS en natif
  • La principale raison pour laquelle le Web est devenu plus lent, c’est surtout que les sites sont devenus beaucoup trop lourds
    Cela dit, je pense que cette technologie pourrait quand même réduire davantage la latence dans les jeux
    • Le paradoxe de Jevons s’applique aussi ici
      Quand les ressources de calcul et l’efficacité réseau augmentent, la demande augmente elle aussi
      Pour les jeux ou le calcul scientifique, ce n’est pas grave si cela permet de meilleurs résultats
      Mais sur le Web, cela a souvent des effets pervers, avec davantage de publicité, de traçage et de JavaScript
  • L’article indique que QUIC établit les connexions comme TCP avec bind(), connect(), listen(), accept(), mais que la structure change ensuite en utilisant les syscalls sendmsg() et recvmsg()
    J’aurais aussi aimé une explication sur le choix de cette approche, et sur la raison pour laquelle on n’a pas créé des syscalls séparés spécifiquement adaptés à QUIC