Should a turn request include candidates for stun? - webrtc

There are two very similar questions here, but both haven't been answered:
rfc5766-turn-server as TURN and STUN for webrtc application question 1. says "with rfc5766-turn-server is enough to act as a TURN and also STUN server or do I also need to run a stun server".
missing relay candidates from TURN server speak about missing relay candidates, the effect I am seeing when making only a turn request.
We have coturn configured with turns and use-auth-secret and use https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/ for testing.
When I make a stun request stun:hostname:5349 without password I see the srflx candidate (my external IP).
When I make a turn request turns:hostname:5349[username:password] I see the relay candidate (the TURN server's public address).
This looks good, but do I need to make 2 requests to the same server? Shouldn't turn include stun and give me srflx and relay candidates?
Can I configure coturn to return both in a single request?
Or will the client have to make both requests? Is so, will all browsers do this correctly when using WebRTC?

If you have TURN/UDP configured in the client, configuring the same server as a STUN server isn't necessary.
TURN over UDP will return a srflx candidate automatically, you should be able to see that on the trickle-ice test page. If you look at the packets exchanged in Wireshark you'll see both
* a STUN binding request and the binding response containing the public ip as seen by the server in the xor-mapped-address field as well as
* a STUN (TURN) allocate request whose response also contains a xor-mapped-address
TURN over TLS or TURN over TCP won't do that since that would not work with udp hole punching.

Related

Understanding SFU's, TURN servers in WebRTC

If I am building a WebRTC app and using a Selective Forwarding Unit media server, does this mean that I will have no need for STUN / TURN servers?
From what I understand, STUN servers are used for clients to discover their public IP / port, and TURN servers are used to relay data between clients when they are unable to connect directly to each other via STUN.
My question is, if I deploy my SFU media server with a public address, does this eliminate the need for STUN and TURN servers? Since data will always be relayed through the SFU and the clients / peers will never actually talk to each other directly?
However, I noticed that the installation guide for Kurento (a popular media server with SFU functionality) contains a section about configuring STUN or TURN servers. Why would STUN or TURN servers be necessary?
You should still use a TURN server when running an SFU. To understand diving into ICE a little bit will help. All SFUs work a little differently, but this is true for most.
For each PeerConnection the SFU will listen on a random UDP (and sometimes TCP port)
This IP/Port combination is giving to each peer who then attempts to contact the SFU.
The SFU then checks the incoming packets if they contain a valid hash (determined by upwd). This ensures there is no attacker connecting to this port.
A TURN server works by
Provides a single allocation port that peers can connect to. You can use UDP, DTLS, TCP or TLS. You need a valid username/password.
Once authenticated you send packets via this connection and the TURN server relays them for you.
The TURN server will then listen on a random port so that others can then send stuff back to the Peer.
So a TURN server has a few nice things that an SFU doesn't
You only have to listen on a single public port. If you are communicating with a service not on the internet you can just have your clients only connect to the allocation
You can also make your service available via UDP, DTLS, TCP and TLS. Most ICE implementations only support UDP.
These two factors are really important in government/hospital situations. You have networks that only allow TLS traffic over port 443. So a TURN server is your only solution (you run your allocation on TLS 443)
So you need to design your system to your needs. But IMO you should always run a well configured TURN server in real world environments.

Why do we use STUN servers?

If stun servers give the browser the public IP for the clients, why couldn't the signaling server give us this as well?
Or is there something else that I am missing
I was reading this here: https://bloggeek.me/google-free-turn-server/
UDP and TCP might be routed differently, in particular when there is a HTTP proxy.
Also, a signaling server will know some address of the client, but it will not know a port that going to result in a connection as one needs UDP holepunching for that.

How does SDP in webrtc know candidate's ip?

Candidate attribute in a SDP provides connection address of the candidate. Which looks like this:
a=candidate:4022866446 1 udp 2113937151 192.168.0.197 36768 typ host
I want to know how does sdp collects information about my local ip.
It'd be great help if there's any specific webrtc code to look at. And, if it is possible to look at local IP, can sdp know my default gateway ?
WebRTC provides you some APIs. You can not see whats going on underneath. You call specific APIs and internally the SDK does its job which in this case gathering your ip information.
There are 3 types of candidates Host, Server Reflexive(public address) and relay address.
Host candidate is your interface address. The interface addresses are gathered through some system API calls and also a socket is created and bound for each interface to get the port.
As WebRTC internally uses ICE, STUN and TURN protocol, the server reflexive and relay candidate gathering has specific rule to follow.
To gather Server Reflexive candidate(NAT's public IP:Port) internally a STUN message is sent to STUN server and the response message contains mapped/XOR mapped address. This how your server reflexive address is gathered.
To gather Relay candidate a TURN allocate request is sent to TURN server and the response message contains relay address. TURN message response contains the server reflexive address also. So if you have TURN server then you don't need STUN server.
Edit:
I dont think there are WebRTC APIs that can help you with this.
You dont need WebRTC for finding out your default gateway. You can programmatically find that out by yourself. There are some system calls which will give your devices routing table entries. Or in some platform you need to read a specific configuration file to get those entries. You can parse these entries to find out the default gateway. See the following questions fie some examples.
How to get the WIFI gateway address on the iPhone?
Default Gateway in C on Linux
Whenever you create a PeerConnection object, it collects all the possible ice candidates( addresses through which the remote peer could reach you), you have to gather them using PeerConnection.onicecandiate event handler and pass them on the remote peer through signalling server.
Some of these candidates would reflect on the locally generated sdp, they are not mandatory part of the sdp, the main purpose of the sdp is to describe the mediasteam you are sharing.
It s called "ice gathering" and it s done internally in the browsers.
The browser does NOT know about your gateway, but if you use a STUN server, it will know your public IP.

Is ICE Necessary for Client-Server WebRTC Applications?

I have a WebRTC MCU (kurento) running on a public IP address
serving some clients that only send or only receive audio
So every clients is directly connected with MCU (not with each other ) that has a public IP address .
Q1: Is there still a necessity to use STUN and TURN for NAT traversal ?? if so Why ??
Q2: Is there any hack in WebRTC in browser that would remove the need for STUN and TURN ?
In my opinion : most of client-server architectures do not have any difficulty with clients behind NAT .What's the difference here with webrtc?
Yes ICE is absolutely must for WebRTC.
Q1: Is there still a necessity to use STUN and TURN for NAT traversal
?? if so Why ??
For your scenario you don't need to use STUN or TURN. Let me explain why.
Every client that are in private network is under some kind of NAT which has a public IP address. Outside world doesn't know this client's private IP address and even if they knew they can't connect with the client without knowing that public IP address. STUN server is used to gather this public IP address.
So if your server wants to initiates the connection then it needs the client to send its NAT's public IP. Client will use STUN server to know its public IP and send it to the server. But if client initiates the connection then there is no need to know the NAT's public IP. Client can send packets to the public server to initiate the connection. Server can know the cilents public IP from the clients packet and then they can connect. So no need for STUN.
Your server is doing TURN's role in this scenario. So you don't need TURN server.
Q2: Is there any hack in WebRTC in browser that would remove the need for STUN and TURN ?
There is no hack. Depending on scenarios TURN/STUN is used. For your scenario you don't need. If you wanted to make client-client connection then you would have needed STUN server.
ICE is mandatory
but using any stun and turn server is not.
since you are connecting to a server on a public port, you NEVER need to use a TURN server, but depending the kind of NAT/Firewall your clients are behind, you might need a STUN server
you do not need to modify the browsers at all. The application decides wether to use a stun server or not. if you pass an empty "iceservers" parameter to your peerconnection object at creation, the ICE UA in your browser will only generate host (local) candidates.

Is STUN server absolutely necessary for webrtc when I have a socket.io based signaling server?

My understanding about STUN server for webrtc is that when the clients are behind the NAT (in most cases, if not all), the STUN server will help the webrtc clients to identify their addresses and ports. And I also read some article saying that a signaling server is needed for webrtc clients. The signaling server could be a web server, socket.io, or even emailing a url. My first question would be: is the STUN server the signaling server?
Actually now I built a very simple socket.io based service which broadcasts client's session descriptions to all other clients. So I believe the socket.io based server should have enough knowledge about the clients' addresses and ports information. If this is the case, why do we bother to have another STUN server?
The STUN server is NOT the signalling server.
The purpose of the signalling server is to pass information between the peers at the start up of the session(how can they send an offer without knowing who to send to?). This information includes the SDPs that are created on the offers and the answers and also any Ice Candidates that are created by either party.
The reason to have a STUN server is so that the two peers can send the media to each other. The media streams will not hit your signalling server but instead will go straight to the other party(the definition of a peer-to-peer connection), the exception to this would be the case when a TURN server is used.
Media cannot magically go through a NAT or a firewall because the two parties do not have direct access to each other(like they would if they were on the same LAN).
In short STUN server is needed the large majority of the time when the two parties are not on the same network(to get valid connection candidates for peer-to-peer media streaming) and a signalling server is ALWAYS needed(whether they are on different networks or not) so that the negotiation and connection build up can take place. Good explanation of the connection and streaming process
STUN is used to implement the ICE protocol, which tries to find a working network path between the two clients. ICE will also use TURN relay servers (if configured in the RTCPeerConnection) for cases where the two clients (due to NAT/Firewall restrictions) can't make a direct peer-to-peer connection.
STUN servers are used to identify the external address used by the computer on the internet (the outside-the-NAT address) and to attempt to set up a port mapping usable by the peer (if the NAT isn't "symmetric") -- contacting the STUN server will tell you the external IP and port to try to use in ICE. These are the ICE candidates included in the SDP or in the trickle-ICE messages.
For almost-guaranteed connectivity, a server should have TURN servers (preferably supporting UDP and TCP TURN, though UDP is far preferred). Note that unlike STUN, TURN can use appreciable bandwidth, and so can cost money to host. Luckily, most connections succeed without needing to use a TURN server (i.e. they run peer-to-peer)
NAT(Network Address Transformation) is used to translate "Private IP', which is valid only in LAN into "Public IP" which is valid in WAN.
The problem is that "Public IP" is only visible from outside, so we need STUN or TURN server to send back "Public IP" to you.
This process enables a WebRTC peer to get a publicly accessible address for itself, and then pass that on to another peer via a signaling mechanism
A STUN server is used to get an external network address.
TURN servers are used to relay traffic if direct (peer to peer) connection fails.
for more you can also refer from below link: https://www.html5rocks.com/en/tutorials/webrtc/infrastructure/#what-is-signaling
In your case, you need STUN. Most clients will be behind NAT, so you need STUN to get the clients public IP. But if both your clients were not behind NAT, then you wouldn't need STUN. More generally, no, a STUN server is not strictly required. I know this because I successfully connected 2 WebRTC peers without a stun server. I used the example code from aiortc, a python WebRTC/ ORTC library where both clients were running locally on my laptop. The signalling channel used my manual copy-pasting. I literally copied the SD (session description) from the one peer to the other. Then, copied the SD from the 2nd peer to the 1st peer once again.
From the ICE RFC (RFC8445), which WebRTC uses
An ICE agent SHOULD gather server-reflexive and relayed candidates.
However, use of STUN and TURN servers may be unnecessary in certain
networks and use of TURN servers may be expensive, so some
deployments may elect not to use them.
It's not clear that STUN is a requirement for ICE, but the above says it may be unnecessary.
However, signalling has nothing to do with it. This question actually stems from not understanding what STUN does, and how STUN interplays with signalling. I would argue the other 3 answers here do not actually answer these 2 concerns.
Pre-requisite: Understand the basic concepts of NAT. STUN is a tool to go around NAT, so you have to understand it.
Signalling: Briefly, in WebRTC you need to implement your own signalling strategy. You can manually type the local session description created by one peer in the other peer, use WebSockets, socket.io, or any other methods (I saw a joke that smoke signals can be used, but how are you going to pass the following session description (aka. SDP message) through a smoke signal...). Again, I copy pasted something very similar to below:
v=0
o=alice 2890844526 2890844526 IN IP4 host.anywhere.com
s=
c=IN IP4 host.anywhere.com
t=0 0
m=audio 49170 RTP/AVP 0
a=rtpmap:0 PCMU/8000
m=video 51372 RTP/AVP 31
a=rtpmap:31 H261/90000
m=video 53000 RTP/AVP 32
a=rtpmap:32 MPV/90000
When both peers are not behind NAT, you don't need a STUN server, as the IP addresses located in the session description (the c= field above, known as connection data) generated by each peer would be enough for each peer to send datagrams or packets to each other. In the example above, they've provided the domain name instead of IP address, host.anywhere.com, but this can be resolved to an A record. (Study DNS for more information).
Why don't you need a STUN server in this case? From RFC8445:
There are different types of candidates; some are derived from physical or logical network interfaces, and others are discoverable via STUN and TURN.
If you're not using NAT, the client already knows the IP address which peers can directly address, so the additional ICE candidates that STUN would generate would not be helpful (it would just give you the same IP address you already know about).
But when a client is behind a NAT, the IP they think they won't help a peer contact them. Its like telling you my ip address is 192.168.1.235, it really is, but its my private IP. The NAT might be on the router, and your client may have no way of asking for the public IP. So STUN is a tool for dealing with this. Specifically,
It provides a means for an endpoint to determine the IP address and port allocated by a NAT that corresponds to its private IP address and port.
STUN basically lets the client find out what the IP address. If you were hosting a Call of Duty server from your laptop, and port forwarded a port to your machine in the router settings, you still had to look up your public IP address from a website like https://whatismyipaddress.com/. STUN lets a client do this for itself, without you accessing a browser.
Finally, how does STUN interplay with signalling?
The ICE candidates are generated locally and with the help of STUN (to get client public IP addresses when they're behind NAT) and even TURN. Session descriptions are sent to the peer using the signalling channel. If you don't use STUN, you might find that the ICE candidates generated that is tried by ICE all fail, and a connection (other than the signalling channel) does not successfully get created.