Composants client et serveur QUIC pour Delphi et C++ Builder | Blog eSeGeCe

Composants client et serveur QUIC pour Delphi et C++ Builder

· Composants
Composants client et serveur QUIC sgcQUIC

sgcQUIC apporte le protocole de transport QUIC (RFC 9000) à Delphi, C++ Builder et .NET. Il fournit deux nouveaux composants, TsgcQUICClient et TsgcQUICServer, tous deux bâtis sur le moteur QUIC natif d'OpenSSL 3.5, si bien que le transport et la négociation TLS 1.3 s'exécutent en un seul échange.

QUIC est le protocole sous-jacent à HTTP/3, mais il est utile par lui-même. Il fonctionne sur UDP, multiplexe de nombreux flux indépendants sur une seule connexion, reprend avec le 0-RTT et survit à un changement de réseau grâce à la migration de connexion. Cet article couvre la couche QUIC brute. Le prochain article couvre les composants HTTP/3 qui reposent par-dessus.

Pourquoi QUIC

Une connexion TLS-sur-TCP classique nécessite une négociation TCP, puis une négociation TLS avant que le premier octet de données applicatives ne circule. QUIC réunit les deux en un seul échange, si bien qu'une nouvelle connexion est prête en un seul aller-retour, et qu'une connexion reprise peut envoyer des données avec le 0-RTT.

Parce que chaque flux QUIC est livré indépendamment, un paquet perdu sur un flux ne bloque pas les autres. Cela élimine le blocage en tête de file que l'on obtient lorsqu'on multiplexe sur un seul socket TCP. Une connexion QUIC est identifiée par un identifiant de connexion plutôt que par le couple IP et port, si bien qu'elle peut migrer du Wi-Fi vers les données mobiles sans être coupée.

Le client QUIC

Définissez Host et Port, assignez les événements, puis mettez Active à True. La négociation s'achève en un seul échange, et WriteData envoie des octets sur un flux QUIC.

uses
  sgcQUIC_Client;

var
  oClient: TsgcQUICClient;
begin
  oClient := TsgcQUICClient.Create(nil);
  oClient.Host := 'www.example.com';
  oClient.Port := 443;
  oClient.OnQUICConnect    := OnQUICConnect;
  oClient.OnQUICStreamData := OnQUICStreamData;
  oClient.OnQUICDisconnect := OnQUICDisconnect;

  oClient.Active := True;          // TLS 1.3 handshake in a single flight
  oClient.WriteData('ping');       // send bytes on a QUIC stream
end;

Les octets entrants arrivent dans l'événement OnQUICStreamData, qui indique l'identifiant du flux et la charge utile :

procedure TForm1.OnQUICStreamData(Sender: TObject; aStreamId: Int64;
  aUnidirectional: Boolean; const aData: TBytes);
begin
  Memo1.Lines.Add('stream ' + IntToStr(aStreamId) + ': ' +
    TEncoding.UTF8.GetString(aData));
end;

Le serveur QUIC

Le serveur écoute sur un port UDP et a besoin d'un certificat et d'une clé privée au format PEM. QUIC fonctionne toujours sur TLS 1.3, le certificat est donc obligatoire. Les octets du client arrivent dans OnQUICData, et vous répondez avec WriteData, en passant la connexion à laquelle vous voulez répondre.

uses
  sgcQUIC_Server;

var
  oServer: TsgcQUICServer;
begin
  oServer := TsgcQUICServer.Create(nil);
  oServer.Port := 443;
  oServer.QUICOptions.SSLOptions.CertFile := 'cert.pem';
  oServer.QUICOptions.SSLOptions.KeyFile  := 'key.pem';
  oServer.OnQUICConnect := OnQUICConnect;
  oServer.OnQUICData    := OnQUICData;
  oServer.Active := True;
end;

procedure TForm1.OnQUICData(Sender: TObject;
  aConnection: TsgcQUICServerConnection; const aData: TBytes);
begin
  // echo the message back to the client that sent it
  oServer.WriteData(aConnection, aData);
end;

Flux multiplexés

Une seule connexion QUIC peut transporter plusieurs flux à la fois. Appelez EnableMultiStream avant de vous connecter, puis ouvrez autant de flux que nécessaire. Un flux bidirectionnel transporte une requête et sa réponse ; un flux unidirectionnel pousse des données dans un seul sens.

oClient.EnableMultiStream;
oClient.OpenStream;                 // a new bidirectional stream
oClient.OpenStream(True);           // a unidirectional stream

Le mode multi-flux utilise le moteur QUIC intégré d'OpenSSL 3.5. Chaque flux dispose de son propre contrôle de flux, si bien qu'un flux lent ou bloqué ne bloque jamais les autres.

0-RTT et migration de connexion

Après une première négociation réussie, le client peut conserver le ticket de session et se reconnecter avec le 0-RTT, en envoyant des données applicatives dès le tout premier paquet. La migration de connexion maintient une session active à travers un changement de réseau, ce qui compte pour les clients mobiles qui passent du Wi-Fi au cellulaire. Les deux sont gérés par le moteur QUIC sous-jacent.

Disponibilité

sgcQUIC est un package séparé, sous licence en tant que module complémentaire de sgcWebSockets Enterprise. Chaque licence inclut le code source Pascal complet et un an de mises à jour. Les composants s'installent sur la palette SGC QUIC et prennent en charge Delphi et C++ Builder 7 à 13, ainsi qu'un portage .NET avec les mêmes noms de classes Tsgc.

Les composants client et serveur HTTP/3 sont traités dans le prochain article. Vous pouvez télécharger la version d'essai et consulter la référence complète des composants sur la page produit sgcQUIC.

Des questions ou des retours ? Contactez-nous, vous recevrez une réponse des personnes qui ont écrit le code.