I'm searching for a way to implement client to client communication without the peers knowing each others IP addresses. Using WebRTC with TURN (looking at coturn) would be ideal, for the clients already supporting the protocol. But reading from the TURN specification it states:
the client MUST include an XOR-PEER-ADDRESS attribute and a DATA attribute. The XOR-PEER-ADDRESS attribute contains the transport address of the peer to which the data is to be sent.
So it seems that the protocol dictates having the peer IP. Optimally for me this attribute could be a provided (anonymous) key which I could map to an IP on the TURN server in a routing table. Updating the routing table would be handled by the signaling server.
Is there something out there supporting functionality like this, or should I plan on writing the clients and the TURN functionality myself? In my case all the traffic would of course be routed through a TURN server.
User coTURN and set iceTransportPolicy option to relay (deafult is all), then peerConnection will generate only relay candidates(TURN).
So media will flow via TURN server only.
And peers won't aware of remote users IP(Reflex/Host).
Create peerConnection as fllowing
var iceServers = [{"urls":["turn:TURN_IP:3478?transport=udp"],"username":"TURN_USERNAME","credential":"TURN_PASWD"}];
var config = {"iceServers": iceServers, "iceTransportPolicy": "relay"};
var constraints = [{"DtlsSrtpKeyAgreement": true}];
pc = new RTCPeerConnection(config, constraints);
Related
As per my understanding from my previous question : Kurento: STUN/TURN
The TURN server configured from webrtcendpoint.conf.ini is used only for exchanging ice candidates. Also we can specify only one TURN server in webrtcendpoint.conf.ini because What I have observed is that if i provide 2 or more TRUN server in webrtcendpoint.conf.ini Kurento media server service fails to start, is this correct ?
Also is there any way to verify which STUN/TURN server is being used at Kurento media server and between two peers?
The STUN/TURN which we provide in conferenceroom.js will be used for the actual media flow/mediapipeline between peers. Is this correct ?
If we provide multiple TURN servers in conferenceroom.js then the TURN server neatest/fastest response time will be selected for media flow between the two peers? Same as we get response time form this Link.
Also what I have observed is that if the TURN server provided in webrtcendpoint.conf.ini and conferenceroom.js are different then we are not able to see remote participants video but if both the TURN server are the same then I am able to see remote participants video. Is this correct ?
Edit 1:
In groupcall sample example we have onExistingParticipants() and onNewParticipants() where we can define iceServers in receiveVideo() and onExistingParticipants() so what will happen if we specify TURN server t1 in kurentoUtils.WebRtcPeer.WebRtcPeerSendOnly() and TURN server t2 in kurentoUtils.WebRtcPeer.WebRtcPeerRecvOnly() then will these two TURN server communicate between each other as relay chain ?
The TURN server configured from webrtcendpoint.conf.ini is used only
for exchanging ice candidates. Also we can specify only one TURN
server in webrtcendpoint.conf.ini because What I have observed is that
if i provide 2 or more TRUN server in webrtcendpoint.conf.ini Kurento
media server service fails to start, is this correct ?
It is used for gathering candidates, and if needed as video relay. You KMS won't probably need this, as the location where it's deployed is managed by you. If you can do with STUN only which is the desired way, then the relay server won't be used.
Only one server can be configured,
Also is there any way to verify which STUN/TURN server is being used
at Kurento media server and between two peers?
Yes, the WebRtcEndpoint has methods for this
getStunServerPort()
getStunServerAddress()
getTurnUrl()
The STUN/TURN which we provide in conferenceroom.js will be used for
the actual media flow/mediapipeline between peers. Is this correct ?
It will be used to gather candidates in your client. Also, if your client is behind a NAT that needs to use a relay server, it will use the one configured in conferenceroom.js. Keep in mind that the media path might not be symmetric: while media going from client->kms might be not using a relay server, media going from KMS-> client might due to the network conditions at your client's location.
If we provide multiple TURN servers in conferenceroom.js then the TURN
server neatest/fastest response time will be selected for media flow
between the two peers? Same as we get response time form this Link.
Yes, candidates are probed and the best one is chosen.
Also what I have observed is that if the TURN server provided in
webrtcendpoint.conf.ini and conferenceroom.js are different then we
are not able to see remote participants video but if both the TURN
server are the same then I am able to see remote participants video.
Is this correct ?
This shouldn't be the case, unless one TURN is working and the other not.
EDIT
TURN servers will not exchange media between them. They will be used, if needed, to act as a relay with the other peer. The process is
Each peer gathers candidates: host, srflx (STUN) and relay (TURN). Nothe that if the TURN server is different, the relay candidates will also be different.
Candidates get sent to the other peer.
Each candidate is probed individually, and the best one is chosen.
Since all media is going through KMS, it will be the KMS the one sending media to the relay server. Keep in mind that KMS is always in between peers. It would be
kms->t2->client
client->t1->kms
Even if the connection was browser to browser, the TURN servers would not communicate directly, as they would act as relay for the media sent from one peer to the other. Here it would be
client1->t2->client2
client2->t1->client1
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.
I am beginner level.
I try to broadcast data to the browsers in local area ( Same router by sending . . . 255 ).
I should implement the real time streaming service to the local level browsers.
But it will occur high traffic when the client browsers is increased.
To broadcast data, it seems to need UDP protocol.
But web browser base on TCP.
So i investigated the webRTC that is based on UDP.
But i don't really know how to use this.
Is it possible to broadcast the data to the web browser like chrome in local area ?
If not, why it is impossible to implement ? just for hazard of DDOS ? How can i solve this high traffic problem ?
( It really occur high traffic when each clients respond to every data from server (TCP) or the server send same data to the every client amount to number of clients (not broadcasting).
I just want to implement that the server just send one broadcasting datagram packet to the local area and each clients in local level receive same one data from the server but not respond to that. )
From a web app (not a modified web browser itself), you cannot create nor manipulate raw (UDP/TCP) sockets.The sandboxing and other mechanisms won't let you.
with webRTC, you will need to make an handshake, and use ICE.
=> You cannot push to a peer knowing only his IP/port
=> You have to have the receiver accept and acknowledge the transfer
you might have more change with WebSockets, but that requires additional mechanisms as well and not all parties will be able to support web socket (or accept the upgrade from http to WS).
For illustration purpose, you can see the work of Jess on a web-based bit torrent. He has exactly the same problems. https://github.com/feross/webtorrent
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.
What I want is, basically, to create a connection between two different computers on same local network. But i want to do this by computers' local IP's. (like 192.168.2.23 etc)
This must be a totally local connection. no TURN or STUN Servers. I am not sure if this is possible. Because there are not much documentation/example/information about WebRTC.
So, how can I create a connection from my computer to another one just passing its local IP as parameter?
Update: To be more clear; imagine there is an html page contains some code that activates my camera and audio services. and another -almost same- page is open in other computer. Waiting a connection request... And there is a textbox in my page to type an IP belongs to other computer on my local network. type 192.168.2.xx and bingo! i have connection between me and other computer.
I want this process as IP based, because there may be more than 2 devices on the network. And all of them are possible devices to create connection. So i need to reach them by their IP's.
Any example code or explanation would be great! even if it tells that this is not possible.
Thanks
Peer discovery is a vital part in any WebRTC application. It's an expensive term for saying: "Hi, I'm computer 4 and I want to talk to you!".
See it as calling a friend over the phone. You need to dial his number first.
This part is not defined in the WebRTC standards. You need to implement this logic in your application. Once you know who you want to call, you need a way of exchanging vital information. This is called signaling, like flo850 put in his answer.
Signaling is needed before any peer-to-peer connection can be set up.
To come up with an idea for your use case of 7 devices in a LAN.
If you have these devices connected to for example a WebSockets server and are in the same channel.
The WebSockets server can be written to route messages to specific receivers.
Devices connected to the channel often are identified with some kind of ID, imagine you use the device's IP.
When you want to talk to computer 4 with IP 192.168.0.4 you send the exchange messages (signaling) on the channel to the receiver with ID, the IP of the device you want to connect with.
How to send the signaling (offer, answer) is described here with example code.
Hope this helps
Users usually sit behind NATs; that's why ICE concept implemented in WebRTC.
If both users are sitting behind same NAT; you can skip ICE servers by passing "NULL" parameter value over "RTCPeerConnection" constructor:
var peer = new [webkit|moz]RTCPeerConnection ( null );
Now, browser will use "host" candidates, also known as "local" candidates.
you still need a signaling server. During the ICE candidate search, your clients will exchange their local ip through this signaling server