Files
games/crates/common/game-realtime-webtransport-lib/README.md
2026-09-21 22:55:21 +02:00

4.1 KiB

game-realtime-webtransport-lib

Backend WebTransport/QUIC candidat pour le realtime de games.sasedev.

Responsabilité

La crate possède le transport WebTransport concret sans introduire de sémantique gameplay, room, joueur, tick ou snapshot. Son chemin natif repose sur web-transport-quinn et conserve les erreurs publiques dans game-realtime-transport-lib.

La frontière native disponible couvre désormais :

  • configuration client HTTPS avec pin SHA-256 exact ;
  • identité serveur X.509 DER + clé privée PKCS#8 DER injectables ;
  • génération locale d'une identité self-signed ECDSA P-256 à validité courte pour localhost, IPv4 loopback et IPv6 loopback ;
  • bind UDP/QUIC sur adresse explicite ou port éphémère ;
  • établissement HTTP/3 WebTransport client/server natif ;
  • sélection d'un unique stream bidirectionnel fiable comme chemin realtime principal ;
  • framing privé u32 big-endian + payload binaire ;
  • borne POC de 1 MiB vérifiée avant allocation côté réception et avant écriture côté émission ;
  • adaptation RealtimeConnection / RealtimeSender / RealtimeReceiver ;
  • fermeture propre du chemin logique par FIN du stream primaire ;
  • tracing sous games::realtime::webtransport.

TLS de développement

WebTransportServerIdentity::generate_loopback() crée une identité en mémoire. La clé privée n'est ni écrite ni versionnée. Le certificat est valide sept jours, avec une petite marge de clock skew, et son SHA-256 est exposé à travers WebTransportCertificateHash afin que le client puisse utiliser le pinning fourni par web-transport-quinn.

Une identité préexistante peut être injectée en DER avec WebTransportServerIdentity::from_pkcs8_der(...). La compatibilité certificat/clé est alors vérifiée par le builder TLS au bind du serveur.

Aucune option de désactivation globale de la vérification TLS n'est exposée.

Stream fiable principal

Une session WebTransport établie n'est pas encore le contrat realtime lui-même. Le client appelle WebTransportSession::open_primary_connection() ; le serveur appelle WebTransportSession::accept_primary_connection().

Le chemin logique devient ensuite :

one WebTransport session
    -> one primary bidirectional reliable stream
        -> u32 big-endian payload length
        -> payload bytes

open_primary_connection() écrit déjà l'en-tête de stream WebTransport requis par HTTP/3 avant de retourner. Le pair peut donc terminer accept_primary_connection() avant l'envoi de la première frame applicative ; aucun préambule propre à games.sasedev n'est nécessaire.

RealtimeConnection::split() conserve la session WebTransport dans les deux moitiés afin que la session ne soit pas fermée au moment où l'objet connexion est consommé.

Limite de frame POC

La borne actuelle du framing fiable est volontairement interne à cette tranche : 1 MiB par message. Elle empêche une longueur u32 hostile de provoquer une allocation arbitraire et rejette aussi l'émission hors limite avec TransportErrorKind::MessageTooLarge.

Cette valeur n'est pas encore une configuration produit. La tranche de robustesse suivante doit décider si la limite devient configurable avec les deadlines, la backpressure, les resets, l'abort/cancellation et le mapping d'erreurs détaillé.

Frontières actuelles

La crate ne possède toujours pas :

  • d'API datagram transport-neutral ;
  • de deadlines applicatives WebTransport ;
  • de politique de backpressure explicite ;
  • de reset/abort/cancellation produit ;
  • de mapping fin de toutes les erreurs Quinn/WebTransport ;
  • de chemin navigateur/WASM ;
  • de smoke executable public WebTransport ;
  • de benchmark WebSocket/WebTransport.

Ces responsabilités restent réservées aux tranches suivantes du plan 0.3.5.

Le chemin natif s'exécute sous un runtime Tokio fourni par le consommateur ; la crate ne crée ni runtime ni thread privé. Le chemin navigateur/WASM est distinct : aucun cfg WASM ni dépendance navigateur n'est requis par le backend natif actuel.