sipsorcery icon indicating copy to clipboard operation
sipsorcery copied to clipboard

WebRTC TURN over TCP needs adjust

Open scvthorsten opened this issue 9 months ago • 7 comments
trafficstars

Clients firewalls are outright configured to block UDP or not route UDP. This presents a problem to establish WebRTC sessions to our SipSorcery .NET backend, even when we provide a TURN server to proxy the traffic between peers. In this implementation, the browser is peer to the backend stack, the corresponding peer (on a static IP address)

While the client can establish a TCP connection to COTURN (our TURN server), it seems SipSorcery does not offer TCP options. It is not clear if this line L287 is a bug since "udp" is hard coded under the tcp condition:

https://github.com/sipsorcery-org/sipsorcery/blob/23441de26e75e83d117b0e94abfd8ab15cd0e159/src/net/ICE/RTCIceCandidate.cs#L287

scvthorsten avatar Jan 25 '25 15:01 scvthorsten

There is a TCP ICE channel albeit with a very confusing base class. I have personally never used or tested that implementation.

In the original implementation no TCP option was implemented for RTP as I was somewhat skeptical that it would work well enough to be useful. As soon as there's packet loss or congestion TCP is going to be a big handicap for real-time media. I do get the point about corporate firewalls blocking UDP and I guess with WebRTC now taking over from VoIP an occassionally glitchy stream is better than no stream.

sipsorcery avatar Jan 25 '25 19:01 sipsorcery

WebRTC is indeed taking a learing role in the conversational AI implementations, since its ability to carry data and voice provides a cross-browser channel whilst avoiding WebSockets, often outright blocked in corporate networks.

We see tcp in the robust solutions like Google Meet, when udp failsover: Image

Engineers best to decide on their implementation. Quality difference in 1:1 streams should be minimally different (passing over same routes).

We shall do trails of PR https://github.com/sipsorcery-org/sipsorcery/pull/1295 in our preprod.

Really love your work. Will contribute additional PRs, wherever we can help too.

tozzi21 avatar Jan 26 '25 04:01 tozzi21

@sipsorcery I saw that the PR https://github.com/sipsorcery-org/sipsorcery/pull/1295 is now merged, to align RTC candidate to use TCP. Can we release an updated Nuget with the changes?

bryanlimktscv avatar Jan 27 '25 04:01 bryanlimktscv

@bryanlimktscv (or anyone else) would you be able to confirm whether that PR allows ICE over TCP to now work?

sipsorcery avatar Jan 27 '25 04:01 sipsorcery

It is not clear if this fix solves it, because the interim solution has been JavaScript client to use tcp to TURN server, while backend .net stack uses UDP. this solved the client accessing through their firewall.

on revision, its not clear if it should return tcp and must be checked against RFC spec, as we often see tcp connects receive udp proposal: Image

scvthorsten avatar Feb 06 '25 03:02 scvthorsten

using TURN server: Coturn-4.6.3 'Gorst'

If forced to use TCP Allocation by using REQUESTED-TRANSPORT: TCP, it fails relay and connectivity. There might be something we're missing, haven't looked at the RFC again.

tcpdump on the TURN server Image

I tried the webrtc samples in Firefox and Chromium (Edge). While the connection with the TURN server is TCP, it still uses UDP encapsulated inside the TURN-TCP (?)

At this point, I don't know if WebRTC behavior is on the same level or not.

JSONs from Firefox
  • Both forces relay-only

  • RTCPeer A is configured with ?transport=tcp

  • RTCPeer B is without

  • RTCPeer A

{
    "sdp": "v=0
o=mozilla...THIS_IS_SDPARTA-99.0 7142885487407455343 0 IN IP4 0.0.0.0
s=-
t=0 0
a=fingerprint:sha-256 DA:EC:9D:9A:A5:33:F4:D2:CE:BD:73:AA:51:1E:6C:78:A9:34:72:E1:2E:15:0D:6A:4E:88:F6:41:F8:F9:73:D7
a=group:BUNDLE 0
a=ice-options:trickle
a=msid-semantic:WMS *
m=application 9 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 0.0.0.0
a=sendrecv
a=ice-pwd:02a076d6870cb9741652b6245eccb1b3
a=ice-ufrag:2c898136
a=mid:0
a=setup:actpass
a=sctp-port:5000
a=max-message-size:1073741823
",
    "type": "offer"
}
  • RTCPeer B
Got remote answer 
{
    "sdp": "v=0
o=mozilla...THIS_IS_SDPARTA-99.0 4923176688973568470 0 IN IP4 0.0.0.0
s=-
t=0 0
a=fingerprint:sha-256 0A:1D:61:E3:73:2A:D0:F2:66:2C:99:6E:04:47:9D:38:5F:4E:B0:FF:5C:5C:FE:A8:72:3F:29:F0:A0:59:57:28
a=group:BUNDLE 0
a=ice-options:trickle
a=msid-semantic:WMS *
m=application 9 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 0.0.0.0
a=sendrecv
a=ice-pwd:a6be97f6e91d00732782cc14bc20df64
a=ice-ufrag:87b98be5
a=mid:0
a=setup:active
a=sctp-port:5000
a=max-message-size:1073741823
",
    "type": "answer"
}
  • RTCPeer A
RTCIceCandidate
{
    "address": "10.10.10.1",
    "candidate": "candidate:0 1 UDP 8331263 10.10.10.1 55715 typ relay raddr 10.10.10.1 rport 55715",
    "component": "rtp",
    "foundation": "0",
    "port": 55715,
    "priority": 8331263,
    "protocol": "udp",
    "sdpMid": "0",
    "sdpMLineIndex": 0,
    "type": "relay"
}
  • RTCPeer B
RTCIceCandidate
{
    "address": "10.10.10.1",
    "candidate": "candidate:0 1 UDP 8331263 10.10.10.1 52511 typ relay raddr 10.10.10.1 rport 52511",
    "component": "rtp",
    "foundation": "0",
    "port": 52511,
    "priority": 8331263,
    "protocol": "udp",
    "sdpMid": "0",
    "sdpMLineIndex": 0,
    "type": "relay"
}

ha-ves avatar Feb 07 '25 12:02 ha-ves

i setup a coturn instance on my network, added no-udp to the config file and forced TCP with the ice server configuration and set iceTransportPolicy to relay and i've been unable to break it, seems to be working fine.

ispysoftware avatar Feb 13 '25 08:02 ispysoftware