versatica / mediasoup

Cutting Edge WebRTC Video Conferencing
https://mediasoup.org
ISC License
6.31k stars 1.13k forks source link

Support ICE Consent Freshness (RFC7675) #1127

Closed penguinol closed 9 months ago

penguinol commented 1 year ago

Feature Request

https://datatracker.ietf.org/doc/html/rfc7675

In both WHEP and WHIP, RFC7675 is used to check the abnormal shutdown clients, so we can remove them on server. In short, RFC7675 add a timer to check whether the ice server received binding request in last 30s, if not, terminal it.

penguinol commented 1 year ago

It seems RFC7675 is not suitable for ICE-Lite. But we need a way to detected unexpected closed clients.

Here is some similar issues in pion. https://github.com/pion/ice/issues/288 https://github.com/pion/webrtc/issues/2045

ibc commented 1 year ago

We don't have a way to detect unexpected closed plain RTP clients. Such a thing doesn't even exist in RTP protocol. Why should we care about WebRTC (ICE) unexpected closures? This can be easily done at application level by implementing a keep alive mechanism in which the server sends "ping" messages over DataChannel to a client and the client must reply with "pong".

We should not invent things that do not exist in the RTC specs.

ibc commented 1 year ago

The only idea coming to my mind would be this:

penguinol commented 1 year ago

Because WHEP and WHIP are using HTTP as protocol, and has not define keep-alive message. The all use RFC7675 to do this.

https://datatracker.ietf.org/doc/draft-murillo-whep/

Once a session is set up, ICE consent freshness [RFC7675] SHALL be used to detect abrupt disconnection and DTLS teardown for session termination by either side.

https://datatracker.ietf.org/doc/draft-ietf-wish-whip/

Once a session is setup, ICE consent freshness [RFC7675] SHALL be used to detect non graceful disconnection and DTLS teardown for session termination by either side.

ibc commented 1 year ago

Because WHEP and WHIP are using HTTP as protocol, and has not define keep-alive message. The all use RFC7675 to do this.

Yes, but mediasoup is ICE Lite so it cannot send ICE Binding requests to clients, and even if we sent them we couldn't reliably expect ICE answers from those clients since, as per spec, they are not mandated to reply to ICE requests received from ICE Lite endpoints (mediasoup).

ibc commented 9 months ago

@penguinol you want to see this :)

https://github.com/versatica/mediasoup/pull/1332

ggarber commented 9 months ago

@ibc What is the benefit of implementing sending ICE Binding requests MS->clients instead of relying on missing ICE Binding requests clients->MS to detect when the connection is disconnected?
It looks like a more common approach and more efficient but maybe I'm missing something. (I have commented it with other people and shared the same comment/concern).

ibc commented 9 months ago

What is the benefit of implementing sending ICE Binding requests MS->clients instead of relying on missing ICE Binding requests clients->MS to detect when the connection is disconnected?

Client->MS periodic ICE consent mechanism is not mandatory or there could be ICE clients that do not implement it. We cannot assume that all clients implement it.

ggarber commented 9 months ago

All endpoints MUST send keepalives for each data session. These keepalives serve the purpose of keeping NAT bindings alive for the data session. The keepalives SHOULD be sent using a format that is supported by its peer. ICE endpoints allow for STUN-based keepalives for UDP streams, and as such, STUN keepalives MUST be used when an ICE agent is a full ICE implementation and is communicating with a peer that supports ICE (lite or full).

https://datatracker.ietf.org/doc/html/rfc8445#section-11

ibc commented 9 months ago

What is exactly wrong with being explicit and sending requests by ourselves? Or is it just that since there is an alternative legitimate approach then we have to undo the ongoing work?

ibc commented 9 months ago

The funny thing is that you are right and we could just run a timeout and report disconnection if no consent request was received in the last 30 seconds. HOWEVER the ongoing PR of this task has made a underlying bug to show up (maybe the server side timeout approach you suggest would also make it show up) so I want to fix that first. It's explained in the PR.

ibc commented 9 months ago

@ggarber I hate you. I'll refactor the PR to follow your proposal.

fippo commented 9 months ago

The argument I've seen for doing a STUN ping from server to client anyway is 💩 enterprise firewalls which let outgoing traffic through but block all incoming traffic.

ibc commented 9 months ago

The argument I've seen for doing a STUN ping from server to client anyway is 💩 enterprise firewalls which let outgoing traffic through but block all incoming traffic.

So that's a reason to rely on consent from client to server rather than from server to client, right? And I don't understand anyway. The NAT is open, otherwise there couldn't be incoming and outgoing ICE (requests or responses, DTLS, RTP, etc). So I don't get this argument at all.

And honestly I'm redoing this right now and it's being pain so I prefer no not discuss about this aeternum. I just assume that relying on consent requests sent by client is valid for ALL network scenarios.

fippo commented 9 months ago

No, that would be a reason to do what you proposed in addition to what @ggarber proposed. Such "enterprise" "firewalls" (quotes intentional!) are sometimes breaking enough stuff get get to a state where the DTLS handshake completes (over a different path which works in both directions such as TURN/UDP) but then the higher priority "direct" pair takes over sending from the client but the reverse channel is broken.

ibc commented 9 months ago

I promise I'm not gonna implement consent check in both directions (AKA sending server side requests plus checking received requests from clients).