From a3dc1e85434a3eeed2c81803a969fe8c4611a173 Mon Sep 17 00:00:00 2001 From: neckfire Date: Thu, 16 Jul 2026 23:38:10 +0200 Subject: [PATCH] =?UTF-8?q?docs(netcode):=20findings=20test=20live=20?= =?UTF-8?q?=E2=80=94=20client=20ferme=20apr=C3=A8s=20EncryptionAck=20(atte?= =?UTF-8?q?nd=20voie=20serveur=20chiffr=C3=A9e)=20+=20crash=20ConditionalC?= =?UTF-8?q?leanUp?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- NETCODE-RND.md | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/NETCODE-RND.md b/NETCODE-RND.md index c4c41a8..3e5dc49 100644 --- a/NETCODE-RND.md +++ b/NETCODE-RND.md @@ -107,3 +107,33 @@ anti-triche — est un chantier crypto + RE dynamique d'un autre ordre de grande 3. bascule handshake→données applicatives. Méthode : lancer `Prospect.Server.Game` avec la PSK, diriger le client dessus, itérer sur les logs serveur. + +## MAJ (2026-07-16, soir) — test LIVE contre le vrai client (preprod multi) + +Setup : preprod multi (`the-cycle-api-rd2`, `GAMESERVER_ADDRESS=192.168.1.136:7777`) → +le client voyage vers `the-cycle-game` (branche game-server, PSK via `PROSPECT_DTLS_PSKS`). +user_id preprod = prod = `92EBCFE8C3EAF3AC` (même DB ? non, `ProspectDb_rd`, mais même Id). + +**Observé (séquence réelle) :** +1. Handshake stateless : ✅ complet (challenge/cookie/ack, connexion acceptée). +2. `NMT_Hello` reçu **EN CLAIR** avec EncryptionToken=`92EBCFE8C3EAF3AC` → PSK reconnue. +3. On envoie `NMT_EncryptionAck` + `NMT_Challenge`. Le client **NE ferme plus tout de suite** + (progrès vs l'état documenté « ferme après challenge sans ack »). +4. **Le client n'envoie JAMAIS de ClientHello DTLS** (`16 fe fd`). Aucun record DTLS. +5. Le paquet suivant du client (~18 o, ex. `80E82AC4…5F00000C`) parse **en clair** comme un + **bunch `bClose=true` sur le canal de contrôle (ChIndex 0)** → **le client FERME**. + +**Interprétation :** après `NMT_EncryptionAck`, le client attend que les paquets **serveur** +suivants soient **chiffrés** ; on lui renvoie le `Challenge` en clair → il abandonne. Donc +l'`EncryptionAck` seul ne suffit pas : il faut réellement **chiffrer la voie serveur** après +l'ack (le mur crypto de fond, inchangé). Activer notre composant DTLS ne sert à rien tant que +le client ne fait pas de handshake DTLS de son côté — piste à creuser : est-ce de l'**AES-GCM +keyé par la PSK** (SetEncryptionData/EnableEncryption d'UE) plutôt que du DTLS-handshake ? + +**Bug serveur concret trouvé :** `UChannel.ConditionalCleanUp` (Prospect.Unreal, ~l.822) = +`throw new NotImplementedException()` → **crash du tick** dès qu'un canal se ferme (bClose). +À implémenter (indépendant du crypto). + +**Acquis réutilisables :** on passe le handshake + le Hello + l'EncryptionAck est accepté ; +la PSK par user_id est branchée bout-en-bout (Vault → env → serveur). Le blocage net = +chiffrement de la voie serveur post-ack.