Componenti Client e Server QUIC per Delphi e C++ Builder | Blog eSeGeCe

Componenti Client e Server QUIC per Delphi e C++ Builder

· Componenti
Componenti client e server QUIC sgcQUIC

sgcQUIC porta il protocollo di trasporto QUIC (RFC 9000) su Delphi, C++ Builder e .NET. Include due nuovi componenti, TsgcQUICClient e TsgcQUICServer, entrambi costruiti sul motore QUIC nativo di OpenSSL 3.5, così il trasporto e l'handshake TLS 1.3 vengono eseguiti come un unico flight.

QUIC è il protocollo che sta sotto HTTP/3, ma è utile anche di per sé. Funziona su UDP, multiplexa molti stream indipendenti su una sola connessione, riprende con 0-RTT e sopravvive a un cambio di rete grazie alla migrazione della connessione. Questo articolo tratta il livello QUIC grezzo. Il prossimo articolo tratta i componenti HTTP/3 che vi si appoggiano sopra.

Perché QUIC

Una classica connessione TLS-su-TCP ha bisogno di un handshake TCP e poi di un handshake TLS prima che il primo byte di dati applicativi viaggi. QUIC combina entrambi in un unico scambio, così una nuova connessione è pronta in un solo round trip, e una ripresa può inviare dati con 0-RTT.

Poiché ogni stream QUIC viene consegnato per conto proprio, un pacchetto perso su uno stream non blocca gli altri. Questo elimina l'head-of-line blocking che si ha quando si multiplexa su un singolo socket TCP. Una connessione QUIC è identificata da un connection ID invece che dalla coppia IP e porta, così può migrare da Wi-Fi a rete mobile senza cadere.

Il Client QUIC

Imposta Host e Port, assegna gli eventi, poi imposta Active a True. L'handshake si completa in un unico flight, e WriteData invia byte su uno stream 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;

I byte in ingresso arrivano nell'evento OnQUICStreamData, che riporta l'id dello stream e il payload:

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

Il Server QUIC

Il server è in ascolto su una porta UDP e ha bisogno di un certificato e di una chiave privata in formato PEM. QUIC funziona sempre su TLS 1.3, quindi il certificato è obbligatorio. I byte del client arrivano in OnQUICData, e rispondi con WriteData, passando la connessione a cui vuoi rispondere.

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;

Stream Multiplexati

Una singola connessione QUIC può trasportare molti stream contemporaneamente. Chiama EnableMultiStream prima di connetterti, poi apri tutti gli stream di cui hai bisogno. Uno stream bidirezionale trasporta una richiesta e la sua risposta; uno stream unidirezionale spinge i dati in una sola direzione.

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

La modalità multi-stream usa il motore QUIC integrato di OpenSSL 3.5. Ogni stream ha un controllo di flusso proprio, così uno stream lento o bloccato non blocca mai il resto.

0-RTT e Migrazione della Connessione

Dopo un primo handshake andato a buon fine, il client può conservare il session ticket e riconnettersi con 0-RTT, inviando dati applicativi già nel primissimo pacchetto. La migrazione della connessione mantiene viva una sessione attraverso un cambio di rete, cosa che conta per i client mobili che si spostano tra Wi-Fi e rete cellulare. Entrambi sono gestiti dal motore QUIC sottostante.

Disponibilità

sgcQUIC è un package separato, con licenza come add-on di sgcWebSockets Enterprise. Ogni licenza include il codice sorgente Pascal completo e un anno di aggiornamenti. I componenti si installano sulla palette SGC QUIC e supportano Delphi e C++ Builder dalla 7 alla 13, più un port .NET con gli stessi nomi di classe Tsgc.

I componenti client e server HTTP/3 sono trattati ne il prossimo articolo. Puoi scaricare la trial e leggere il riferimento completo dei componenti sulla pagina prodotto di sgcQUIC.

Domande o feedback? Contattaci, riceverai una risposta dalle persone che hanno scritto il codice.