Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Only use one UDP port #47

Open
SimonBrandner opened this issue Nov 15, 2022 · 4 comments
Open

Only use one UDP port #47

SimonBrandner opened this issue Nov 15, 2022 · 4 comments
Labels
T-Enhancement New feature or request

Comments

@SimonBrandner
Copy link
Contributor

SimonBrandner commented Nov 15, 2022

@daniel-abramov:

As discussed during the daily, I'm adding a little bit more context here: we won't be able to achieve the desired effect by just setting a range of UDP ports to a single port, instead, what we need, is to enable a so-called UDP Muxing in Pion.

As we know, UDP (unlike TCP) does not really have a concept of a connection on a protocol level, so it's about sending and receiving datagrams from/to an address. Pion does not have a global WebRTC state out-of-the-box that would allow reading the information from a single UDP socket and then forwarding it to the appropriate peer connection that is meant to be associated with it. So to enable this behavior, we should rely upon ice.NewMultiUDPMuxFromPort(ourPort) and then configure the engine accordingly: webrtc.SettingEngine.setICEUDPMux(ourConfig) (then we can create a new peer connection specifying the configured settings engine).

Note, that it's probably not something we want to have before stabilizing the SFU since enabling this option might have some undesired side-effects that must be treated accordingly, there is an open issue about it: pion/ice#518

Perhaps a better idea would be to start with something that LiveKit has, i.e. allow configuration of the range of ports used for the UDP along with the support of the ICE-TCP. This should give us a good starting point. Then we could embed a TURN server into the SFU (the TURN server normally has fixed configured ports for both UDP and TCP) and only after it consider the usage of the UDPMux.

@daniel-abramov daniel-abramov added T-Enhancement New feature or request T-Task labels Nov 17, 2022
@dbkr
Copy link
Member

dbkr commented Nov 17, 2022

I guess my question here is exactly what the ICE UDP muxing does - looks like it gathers source addreses based on ice credentials in the check packets and then routes media packets based on the source addresses it matched. I couldn't find out for sure, but I guess this is necessary because otherwise there's no way of knowing which DTLS session to use to decrypt a packet (and since they're DTLSed, you can't just route based on SSRC). In which case, yeah, this is probably something we want to think about a little further down the line.

@daniel-abramov
Copy link
Contributor

daniel-abramov commented Nov 17, 2022

Something like this, yeah, though I think the issue that you described is rather an implication of a more generic problem, let me explain how I understood it (hope that my understanding is correct).

Imagine we don't use UDP mux, and just use different UDP sockets (each peer connection has its own dedicated socket). Code-wise it means that somewhere inside a PeerConnection there is a socket and I imagine that when you read the data it essentially just calls socket.read() and then passes the data down the line to process the received packet.

Now imagine we enforce the usage of a single UDP port naively (using the same architecture, without changes in code), now 5 separate PeerConnections will essentially have the same socket (bound to the same local address and port). If all of them continue to read from the socket the same way they did it before, each PeerConnection will end up reading a random datagram from a socket that may not necessarily have been addressed to this particular PeerConnection. What should PeerConnection do with it? - Well, the only thing it could do is to either drop it (treating it as an unknown or invalid message) or use some sort of a look-up table to understand which PeerConnection this packet was meant for (based on e.g. sender's address and port). This "look-up table" must then be some sort of a shared state between PeerConnections, so that they know to who the message must be forwarded. Alternatively, the underlying socket must be moved outside of the PeerConnection and read in a single place while dispatching the messages to the right PeerConnection based on the addresses. This is exactly what the UDP Muxing in Pion does I suppose (from a quick peek in their code it looks like Pion does indeed something similar though more elaborated).

@dbkr
Copy link
Member

dbkr commented Nov 17, 2022

Exactly - without DTLS this lookup would just be done on the SSRC of the incoming packet so it's trivial, but in a DTLS world you need to know which set of keys to use to decrypt the packet, so you end up guessing based on the sender address.

@daniel-abramov
Copy link
Contributor

UPD. An example to try out once we want to implement it: https://github.com/pion/webrtc/blob/master/examples/ice-single-port/main.go#L85

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-Enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants