ICE (native client): relay-only connections time out against a real TURN server; host-socket checks starve the relay pairs
I maintainer di solito rispondono entro 2 giorni
Valutazione
- Difficoltà
- 2/5
- Tempo stimato
- 1-3 ore
- Idoneità per principianti
- 79/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Attiva
- Stack tecnologico
- cpp
- Ambito
- backend-api-design, networking
Direzione di ricerca
Inizia in src/steamnetworkingsockets/clientlib/steamnetworkingsockets_ice_client.cpp, in Think_TestPeerConnectivity(), e segui come i tipi di candidati consentiti determinano i candidati locali. Riproduci il problema con la configurazione relay-only descritta e confronta il comportamento della connessione con e senza la condizione proposta per i candidati host. Il lavoro è completato quando peer relay-only su macchine diverse si connettono tramite TURN senza che i controlli degli host-socket ritardino le coppie relay.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Version: master at d534c19 (1.6.x), native ICE client (steamnetworkingsockets_ice_client.cpp, ENABLE_ICE=ON, USE_STEAMWEBRTC=OFF), custom signaling.
Setup: k_ESteamNetworkingConfig_P2P_Transport_ICE_Enable = k_nSteamNetworkingConfig_P2P_Transport_ICE_Enable_Relay, no STUN servers, one TURN server (coturn 4.6.3, use-auth-secret) with P2P_TURN_ServerList/UserList/PassList set. Both peers relay-only, on different machines, both allocate on the same TURN server.
What happens: allocations and CreatePermission succeed on both sides, the relay candidates are exchanged, and then the connection fails after the initial timeout with 5008: Timed out attempting to negotiate rendezvous ("Guessed ICE failure to be 5009: NAT traversal failed"). Verbose logging shows only ICE: STUN request 0x1 to <peer relay addr> timed out for every remote candidate. A packet capture on the TURN server shows no Send indications at all after CreatePermission: only binding requests sent directly from each peer's own socket to the other peer's relayed address, which the TURN server (correctly) drops, as it has no permission for the sender's address.
Why (as far as I can tell):
Think_TestPeerConnectivity()always adds the interface's host socket as a local candidate (// Host candidate -- always present.), even whenm_nPermittedCandidateTypespermits only relay candidates. So every remote relay candidate gets a host-socket pair, besides the relay pair. In relay-only mode those host pairs can't succeed: they send straight to a relayed address.- Pairs are unfrozen one per remote foundation at a time (
vecFoundationsUsed, keyed onm_remoteCandidate.m_sFoundationonly), and host pairs sort first. So the relay pair for a remote candidate waits until every host pair for it (one per local interface) has timed out, which takes longer than the connection's initial timeout. (RFC 8445 6.1.2.6 makes a pair's foundation from both the local and the remote candidate's foundations, so host and relay pairs to the same remote candidate wouldn't share one.)
Why it's easy to miss: with both peers (or a peer and the TURN server) on one machine, the relayed address is a local address, so a "direct" host-socket check can be sent from that address and passes the TURN server's permission check as if it were relayed. Everything works until the peers are on different machines.
Repro on one machine: run coturn with its relays on an address that's also local (e.g. ip addr add 5.5.5.5/32 dev lo, --relay-ip=5.5.5.5), and drop packets that arrive on lo for the relay ports from anything but the relay ports (nft ... iifname "lo" ip daddr 5.5.5.5 udp dport 49160-49659 udp sport != 49160-49659 drop), as a real network would. Two relay-only peers then never connect; with the patch below they connect at once.
Patch (what we ship): don't add the host local candidate when only relay candidates are permitted.
--- a/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_ice_client.cpp
+++ b/src/steamnetworkingsockets/clientlib/steamnetworkingsockets_ice_client.cpp
@@ -2385,8 +2385,12 @@ void CSteamNetworkingICESession::Think_TestPeerConnectivity()
ICELocalCandidate localCandidates[2];
int nLocalCandidates = 0;
- // Host candidate -- always present.
- localCandidates[nLocalCandidates++] = { pIntf.get(), {} };
+ // Host candidate -- unless only relay candidates are permitted. Then checks from the
+ // host socket would go straight to the peer's relay candidates, whose TURN server drops
+ // them (no permission for this address), and they'd hold up the relay pairs to the same
+ // remote candidates (one pair per foundation at a time) until the connection times out.
+ if ( m_nPermittedCandidateTypes & ~k_EICECandidate_Any_Relay )
+ localCandidates[nLocalCandidates++] = { pIntf.get(), {} };
The foundation point (2) probably deserves a fix of its own: in "all" mode it still delays the relay fallback behind every host pair to the same remote candidate.
Happy to open a PR with the patch if that's useful.
- Lingua principale
- C++
- Stelle
- 10k
- Fork
- 767
- Metriche di merge delle PR
- Nessuna PR unita negli ultimi 30g
Preparare l'ambiente
Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di ValveSoftware/GameNetworkingSockets
-
Difficoltà 4/5 Più di una settimana Idoneità per principianti 12/100
ValveSoftware/GameNetworkingSockets#465 ·
I maintainer di solito rispondono entro 2 giorni
-
Difficoltà 4/5 3-5 giorni Idoneità per principianti 18/100
ValveSoftware/GameNetworkingSockets#464 ·
I maintainer di solito rispondono entro 2 giorni
-
Assertion Failed: pSock->m_callback.m_fnCallback (socketthread.cpp:2609) after re-initializing the library with GameNetworkingSockets_Kill + GameNetworkingSockets_InitForse già presa @siddiqueirshad l’ha presa 10 giorni fa. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 45/100
ValveSoftware/GameNetworkingSockets#458 ·
I maintainer di solito rispondono entro 2 giorni
-
ISteamNetworkingSockets: Trying to use over 8 network lanes/channels failsForse già presa @jpggvilaca l’ha presa 14 giorni fa. Aperta
Difficoltà 4/5 1-2 giorni Idoneità per principianti 55/100
ValveSoftware/GameNetworkingSockets#455 ·
I maintainer di solito rispondono entro 2 giorni
-
ConfigureConnectionLanes: reconfiguring lanes can leave one lane in a stale priority classForse già presa @sebxt l’ha presa 18 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 35/100
ValveSoftware/GameNetworkingSockets#453 ·
I maintainer di solito rispondono entro 2 giorni
Tutte le issue di ValveSoftware/GameNetworkingSockets
Issue simili
-
bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
Sunrisepeak/mcpp-language-server#80 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
xiaoyifang/goldendict-ng#3148 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 91/100
triton-inference-server/server#9069 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 66/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
I maintainer di solito rispondono entro 4 giorni