I currently have 2 ice servers -- STUN (from Google) and one TURN server (in the US).
If I add more ice servers (to the ice servers array passed to the peer connection) from different locations (IE Europe, Asia, South America etc.), will WebRTC be smart enough about using the optimal TURN servers between users who connect with each other (if TURN is needed between them)?
In theory ICE will take care of this.
However, this will keep open a NAT binding to each TURN server which is rather wasteful. Using geodns like Amazons route53 to let clients create an allocation on the TURN server that is closest is usually better.
Related
I have been reading a bit about WebRTC, and I'm not getting why we need a Turn Server if only 1 peer is using Symmetric NAT, and the other is using neither Symmetric nor Port Restricted NAT, so let’s say A is using Full Cone NAT, B is using Symmetric NAT:
STUN SERVER will send the correct IP address of B to A, and the correct IP + Port address of A to B.
A tries to connect to B (now A will be able to accept messages from B since it’s in the Dest Address Column).
B tries to connect to A, which will allow requests from A going to B (ofc A needs to update the port to the one received from B instead of the Sdp).
am I missing something, or is this correct (and implemented), or is this too complicated to be implemented?
And if this is correct, then theoretically, if I’m peer A and I'm using Full Cone NAT, any peer B can connect to me (as long as I send the connection request first), without needing a TURN server.
Thanks
If the symmetric NAT environment only changes the port, you would be correct with regarding connectivity to Full Cone NAT. The hole punching step would work.
But many enterprise and mobile environments have complex routing schemes and crazy network environments that are different from a legacy home network router. These environments aren't just a little router box that hooks up to a cable modem. It's a complex array of routers and load balancers using a bank of IP addresses. And each outbound connection might get an IP address different from a previous connection. So it's technically "symmetric NAT".
And so after a node within this environment obtains an external IP/port pair from a STUN server, subsequent sends to a peer address might change both both the port and the IP address as well.
As such, the NATs see completely different IP addresses than expected when the UDP packets arrive during the hole punching step. Hence, a relay address (TURN) is needed here.
This question is a little easier if you think in terms of Mapping/Filtering. The other NAT terms don't do a good job of describing how things actually work. My answer comes from RFC 4787 and WebRTC for the Curious: Connecting
Mapping is when your NAT allocates a IP/Port for an outbound packet. A remote peer can the send traffic to this mapping. Filtering are the rules around who can use these mappings.
Filtering and Mappings can then be address dependent and independent. If a mapping is address dependent it means a new mapping is created for each time you contact a new IP/Port. If a mapping is address independent it means it is re-used no matter where you send traffic. These same rules apply to filtering.
If one peer is address + filtering independent I don't believe a TURN server would provide a benefit.
If you want TCP connectivity deploying a TURN server is a good idea. Some WebRTC servers support TCP, but I don't believe any browsers generate passive TCP candidates.
Every time I set up WebRTC video call clients, it never works unless I specify a TURN server. No matter how many STUN servers I supply, it always falls back onto TURN. It could be the case that the people I have tested on all coincidentally happened to be behind symmetric NAT. The only time it doesn't fall back to TURN is when I test locally on my own network. Are STUN servers just very infrequently or rarely used? Or are they used more often and my experience just happens to be anomalous.
STUN servers get used very sparingly, during session setup, to help WebRTC endpoints behind NATs discover their public IP addresses. STUN services put a very small load on their server machines. They're similar to the "what's my ip?" websites on the internet.
TURN servers, when needed, relay the media data from endpoint to endpoint. All the video, audio, and media streams go up to a TURN server and then back down to a recipient. The TURN server load is higher. TURN service is only needed when endpoints cannot reach each other via direct peer-to-peer connections.
STUN isn't a substitute for TURN.
We use a provider of global TURN servers (Xirsys). When establishing a connection between peers, each peer first identifies the closest TURN server to their location, then fetches credentials for that server. The peers then exchange ICE candidates, including their respective TURN server URLs.
If those peers are in different regions, they will propose different TURN servers. According to the accepted answer to this question: TURN-Server for RTCConfiguration the respective TURN servers will connect to each other to relay streams from Peer1 <> TURN1 <> TURN2 <> Peer2. However, I have been unable to get this to work. Forcing TURN in the clients (i.e. no direct p2p connections), and attempting to establish a peerConnection using a TURN server in e.g. the United States to one in Brazil, negotiation always fails.
Is this because the servers require credentials that are not passed in the ICE candidates? Or perhaps it's a Xirsys-specific problem? Or should it actually work fine and we're doing something else wrong?
No it's not going to be because of the credentials. They are used between the client and its TURN server. The connection between the TURN server and remote end point doesn't use any authentication.
In fact each TURN server should be blissfully unaware that the remote party is even another TURN server. As far as they are concerned they forward packets to the remote end point just the same no matter whether it's a browser, another TURN server or some other application.
So, while working through two TURN servers is possible, it's definitely not easy. The reason is that the first TURN server will generate an allocation with a given port. The second TURN server will need to send data to this port. However, how does the first TURN server know where to send that data? The second TURN server will not yet have an allocation!
Typically, WebRTC applications use a singular TURN server. If you want to use two, it means having control of the allocation generation and massaging of the SDP.
I'm passing a handful of STUN and TURN servers for my WebRTC application (built on top of mediasoup). When I do this, I get a message in the console telling me: "Using more than two STUN/TURN servers slows down discovery"
I can cut down the servers to 2... but... why does more hurt? Wouldn't I want the most options available to make a connection?
Because how ICE works is that initially the browser looks at what IP based network interfaces it can find on your machine.
Then it takes the number of network interfaces and combines it with ever single STUN server and every single TURN server the service provides. Next it needs to send request to every single of the these combinations and keep track of the responses. In case of STUN it's just a single response, in case of TURN it is usually multiple round trips. So the more STUN and TURN servers you have the longer it takes to get answers from all of them.
Now if STUN server #1 reports your external IP address as A, with port 1, most likely STUN server #2 is also going to tell you it sees A as your external IP address, with the only difference it reports port 2. In almost all cases all the STUN servers are going to report back the exact same external IP A. But reporting the same external IP address over and over again to the ICE agent on the other end does not increase the chances of establishing the connection at all since its request are all going to hit the same router/NAT/firewall.
With TURN servers one can argue that more TURN servers could help more, as each TURN server should give the browser a different IP address for relaying. But it would be highly unusual if a given browser is able to reach one TURN server and not the another.
In the end all of these servers result in the browser emitting more ICE candidates. And so more ICE candidates need to get send to the other browser or ICE agent. As a result the ICE checking table which tries all possible permutations of local and remote ICE candidates grows bigger and bigger with each ICE candidate. And so it produces a lot more network traffic, while not much increasing the chances of establishing a connection.
I am building this video teaching site and did some research and got a good understanding but except for this thing. So when a user want's to connect to another user, P2P, I need signaling server to get their public IP to get them connected. Now STUN is doing that job and TURN will relay the media if the peers cannot connect. Now if I write signaling server with WebSocket to communicate the SDP messages and have ICE working, do I need coTURN installed? What will be the job of the job of them particularly?
Where exactly I am confused is the work of my simply written WebSocket Signaling server (from what I saw in different tutorials) and the work of the coTURN server I'll install. And how to connect them with the media server I'll install.
A second question, is there a way to use P2P when there is only two/three participants and get the media servers involved is there is more than that so that I don't use up the participant's bandwidth too much?
The signaling server is required to exchange messages between peers (SDP packets) until they have established a P2P connection.
A STUN server is there to help a peer discover information about its public IP and to open up firewall ports. The main problem this is solving is that a lot of devices are behind NAT routers within small private networks; NAT basically allows outgoing requests and their response, but blocks any other "unsolicited" incoming requests. You therefore have a Catch-22 scenario when both peers are behind a NAT router and could make an outgoing request, but have nowhere to send it to since the opposite peer doesn't expose anything to make a request to. STUN servers act as a temporary middleman to make requests to, which opens a port on the NAT device to allow the response to come back, which means there's now a known open port the other peer can use. It's a form of hole-punching.
A TURN server is a relay in a publicly accessible location, in case a P2P connection is impossible. There are still cases where hole-punching is unsuccessful, e.g. due to more restrictive firewalls. In those cases the two peers simply cannot talk 1-on-1 directly, and all their traffic is relayed through a TURN server. That's a 3rd party server that both peers can connect to unrestrictedly and that simply forwards data from one peer to the other. One popular implementation of a TURN server is coturn.
Yes, basically all those functions could be fulfilled by a single server, but they’re deliberately separated. The WebRTC specification has absolutely nothing to say about signaling servers, since the signaling mechanism is very unique to each application and could take many different forms. TURN is very bandwidth intensive and must usually be delegated to a larger server farm if you’re hoping to scale at all, so is impractical to mix in with any of the other two functions. So you end up with three separate components.
Regarding multi-peer connections: yes, you can set up a P2P group chat just fine. However, each peer will need to be connected to every other peer, so the number of connections and bandwidth per peer increases with each new peer. That’s probably going to work okay for 3 or 4 peers, but beyond that you may start to run into bandwidth and CPU limits of individual peers, especially if you’re doing decent quality video streaming.