Add a stream relay (TURN) to the proxy for browsers that cannot connect directly
Vanadium forbids direct UDP for WebRTC, and mobile and company networks often block direct connections; the only route then is a relay reached over TCP. - server/turn.ts: STUN and TURN on one port, over UDP and TCP, with short-lived credentials from /api/turn, quotas and a peer filter - The browser build fetches credentials and offers the relay automatically - Stats for nerds says when a stream is relayed and how the relay is reached - Tests: a TURN client over UDP and TCP, and a browser limited to the relay over TCP in the web E2E Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -64,7 +64,17 @@
|
||||
const pair = (transport?.selectedCandidatePairId && report.get(transport.selectedCandidatePairId)) || all.find(s => s.type === 'candidate-pair' && s.nominated && s.state === 'succeeded');
|
||||
if (pair) {
|
||||
const local = report.get(pair.localCandidateId), remote = report.get(pair.remoteCandidateId);
|
||||
rows.push(['Connection', `${KIND[local?.candidateType] ?? local?.candidateType ?? 'n/a'}, ${String(local?.protocol ?? '').toUpperCase()}`]);
|
||||
// What this side had to offer. A route discovered during the checks (prflx) is still a
|
||||
// relayed one when relays were all we had.
|
||||
const mine = all.filter(s => s.type === 'local-candidate' && s.candidateType !== 'prflx');
|
||||
const relays = mine.filter(s => s.candidateType === 'relay');
|
||||
const relayed = local?.candidateType === 'relay' || (local?.candidateType === 'prflx' && relays.length > 0 && relays.length === mine.length);
|
||||
const relayVia = (local?.relayProtocol ?? relays[0]?.relayProtocol) as string | undefined;
|
||||
// A relayed route is UDP beyond the relay; what matters is how we reach the relay
|
||||
rows.push(['Connection', relayed ? `${KIND.relay}${relayVia ? `, reached over ${relayVia.toUpperCase()}` : ''}`
|
||||
: `${KIND[local?.candidateType] ?? local?.candidateType ?? 'n/a'}, ${String(local?.protocol ?? '').toUpperCase()}`]);
|
||||
const count = (type: string) => mine.filter(s => s.candidateType === type).length;
|
||||
rows.push(['Routes offered', `${count('host')} direct, ${count('srflx')} through STUN, ${relays.length} relayed`]);
|
||||
if (remote?.candidateType) rows.push(['Other side', KIND[remote.candidateType] ?? remote.candidateType]);
|
||||
rows.push(['Round trip', ms(pair.currentRoundTripTime)]);
|
||||
if (pair.availableOutgoingBitrate) rows.push(['Estimated capacity', `${Math.round(pair.availableOutgoingBitrate / 1000)} kbit/s`]);
|
||||
|
||||
Reference in New Issue
Block a user