# 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 : ```text 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.