What does raddr and rport represent in an ICE candidate? - webrtc

Take this ICE candidate as an example
a=candidate:1853887674 1 udp 1518280447 47.61.61.61 36768 typ srflx raddr 192.168.0.196 rport 36768 generation 0.
What does the raddr and rport represent? Also, what if the typ is relay, would that have any effect on it?

raddr and rport are for debugging purpose. https://www.rfc-editor.org/rfc/rfc5245#appendix-B.3 explains the purpose.
For serverreflexive candidates, raddr/rport allow you figuring out which local port (host candidate) is associated with this candidate. For relay candidates it will do the same, but for a serverreflexive candidate.

As Philipp kindly pointed out, the documentation shows that raddr probably stands for relative address and rport stands for relative port, ie. the local ip address and local port. Also, if the type is "relay", it means the connection is being made through a TURN server.

Related

Webrtc connection over turn strange behavior with relay candidates

I have two clients communicating over webrtc. (Client A writen in js, Client B in Python with aiortc). Now it happens that Client A wants to connect from a mobile Network thus it requires a turn-relay connection.
I have already setup a turn server which seems to do his job. But only approx 50% of the connections succeed now. I already found out when they succeed and when they fail:
SDP relay information in case of success:
Offer Client A
a=candidate:3 2 UDP 92217086 172.31.16.8 59986 typ relay raddr 172.31.16.8 rport 59986
Response Client B
a=candidate:11 1 UDP 92086015 172.31.16.8 49910 typ relay raddr 172.31.16.8 rport 49910
SDP relay information in case of failure:
Offer Client A
a=candidate:7 1 UDP 92151551 172.31.16.8 49871 typ relay raddr 172.31.16.8 rport 49871
Response Client B
a=candidate:5820bb1602563a80c76891a80be14933 1 udp 16777215 18.185.84.96 53279 typ relay raddr 172.31.1.103 rport 49244
The important difference is the IP address shown in the Response from Client B, in the successfull scenario it is the IP adress of the net in which Client B is, in the failing scenario it is the IP address of the turnserver (18.185.84.96).
Actually I do not understand why it sometimes gives the IP of the turnserver and the other times not, and what it means that the IP address of the turnserver is not possible to use...
Anyone any ideas, on where to start looking for the issue?
It seems like our turn server was missconfigured.
I can not tell what was misconfigured, because sadly I have no access to the configuration of the turn server.
But I tested by deploying some turn servers on my local machine and they behaved similar when they where not correctly configured. By looking into the logs of thos turn servers I saw 401 Unauthorized popping up all the time. So I changed the configuration, until the authorization was working. With this config we deployed a new server which is now working.
Some words on the configuration for people also having troubles with that on the first run, those are the configurations we put into /etc/turnserver.conf and passed it when starting the server with turnserver -v -c /etc/turnserver.conf:
listening-port=<port>
alt-listening-port=<port>
listening-ip=<listening-ip>
external-ip=<external-ip>
realm=<realm>
fingerprint
lt-cred-mech
user=<user:pw>
bofore coming to that configuration we made some errors, maybe they are obious to experienced people but they were not to us:
we had the use-auth-secret in the config file, this should not be enabled when using user
we had the issue that the turn server was usable in firefox but not in chrome or others, (not possible to gather relay candidates), this was do to realm not beeing configured in the config

PeerJS not working with turn servers

I am Working with peerJS,
In LAN all is OK, but if I use turn servers from cellphone connection the stream connection fails.
The mediaStream is passed in peerJS connection.on('stream', (stream)=>{..
but crashes just after this, the problem seems related to stun/turn negotiation, here the console logs:
.callConnection.on('stream')... <-- I receive the stream
...
PeerJS: Set remoteDescription: ANSWER for: PEER_ID
PeerJS: Added ICE candidate for: PEER_ID
PeerJS: iceConnectionState is disconnected, closing connections to PEER_ID
myHandler.Negotiation of connection to PEER_ID failed.
And then this error catched:
Error: Negotiation of connection to PEER_ID failed.
at RTCPeerConnection.pc.oniceconnectionstatechange [as onicechange]
and here fails
what could it be?
I am not sure if it matters, in the signaling negotiation LOGS I cannot see the configured TURN IP, I only see other IPs:
{"type":"CANDIDATE","src":"itEthicsoftIdeskUserUUU1","dst":"itEthicsoftIdeskDeviceDDDfa53da20-5cc8-83dc-e259-df0ef328fbb7","payload":{"candidate":{"candidate":"candidate:1028452565 1 udp 2113937151 10.98.5.173 42892 typ host generation 0 ufrag lewL network-cost 50","sdpMid":"audio","sdpMLineIndex":0},"type":"media","connectionId":"mc_yzox790yv9b"}}
{"type":"CANDIDATE","src":"itEthicsoftIdeskUserUUU1","dst":"itEthicsoftIdeskDeviceDDDfa53da20-5cc8-83dc-e259-df0ef328fbb7","payload":{"candidate":{"candidate":"candidate:842163049 1 udp 1677729535 37.162.11.125 44523 typ srflx raddr 10.98.5.173 rport 42892 generation 0 ufrag lewL network-cost 50","sdpMid":"audio","sdpMLineIndex":0},"type":"media","connectionId":"mc_yzox790yv9b"}}
Thanks in advance

Which candidate from kurento is use for ReceiveCandidate in client?

I usec# IceLink for develop webrtc,When I sent json "operation":"gatherCandidates" to kurento
The Kurento answer many candidate to me like this::
{"jsonrpc":"2.0","method":"onEvent","params":{"value":{"data":{"candidate":{"__module__":"kurento","__type__":"IceCandidate","candidate":"candidate:1 1 UDP 2013266431 fe80::5054:ff:fef2:132e 58277 typ host","sdpMLineIndex":0,"sdpMid":"audio0"},"source":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","tags":[],"timestamp":"1475555352","type":"OnIceCandidate"},"object":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","type":"OnIceCandidate"}}}
{"jsonrpc":"2.0","method":"onEvent","params":{"value":{"data":{"candidate":{"__module__":"kurento","__type__":"IceCandidate","candidate":"candidate:2 1 TCP 1019217151 fe80::5054:ff:fef2:132e 9 typ host tcptype active","sdpMLineIndex":0,"sdpMid":"audio0"},"source":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","tags":[],"timestamp":"1475555352","type":"OnIceCandidate"},"object":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","type":"OnIceCandidate"}}}
{"jsonrpc":"2.0","method":"onEvent","params":{"value":{"data":{"candidate":{"__module__":"kurento","__type__":"IceCandidate","candidate":"candidate:3 1 TCP 1015022847 fe80::5054:ff:fef2:132e 49390 typ host tcptype passive","sdpMLineIndex":0,"sdpMid":"audio0"},"source":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","tags":[],"timestamp":"1475555352","type":"OnIceCandidate"},"object":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","type":"OnIceCandidate"}}}
{"jsonrpc":"2.0","method":"onEvent","params":{"value":{"data":{"candidate":{"__module__":"kurento","__type__":"IceCandidate","candidate":"candidate:4 1 UDP 2013266431 202.44.12.183 55877 typ host","sdpMLineIndex":0,"sdpMid":"audio0"},"source":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","tags":[],"timestamp":"1475555352","type":"OnIceCandidate"},"object":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","type":"OnIceCandidate"}}}
{"jsonrpc":"2.0","method":"onEvent","params":{"value":{"data":{"candidate":{"__module__":"kurento","__type__":"IceCandidate","candidate":"candidate:5 1 TCP 1019216383 202.44.12.183 9 typ host tcptype active","sdpMLineIndex":0,"sdpMid":"audio0"},"source":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","tags":[],"timestamp":"1475555352","type":"OnIceCandidate"},"object":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","type":"OnIceCandidate"}}}
{"jsonrpc":"2.0","method":"onEvent","params":{"value":{"data":{"candidate":{"__module__":"kurento","__type__":"IceCandidate","candidate":"candidate:6 1 TCP 1015022079 202.44.12.183 54635 typ host tcptype passive","sdpMLineIndex":0,"sdpMid":"audio0"},"source":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","tags":[],"timestamp":"1475555352","type":"OnIceCandidate"},"object":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","type":"OnIceCandidate"}}}
{"jsonrpc":"2.0","method":"onEvent","params":{"value":{"data":{"candidate":{"__module__":"kurento","__type__":"IceCandidate","candidate":"candidate:1 2 UDP 2013266430 fe80::5054:ff:fef2:132e 55435 typ host","sdpMLineIndex":0,"sdpMid":"audio0"},"source":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","tags":[],"timestamp":"1475555352","type":"OnIceCandidate"},"object":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","type":"OnIceCandidate"}}}
{"jsonrpc":"2.0","method":"onEvent","params":{"value":{"data":{"candidate":{"__module__":"kurento","__type__":"IceCandidate","candidate":"candidate:2 2 TCP 1019217150 fe80::5054:ff:fef2:132e 9 typ host tcptype active","sdpMLineIndex":0,"sdpMid":"audio0"},"source":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","tags":[],"timestamp":"1475555352","type":"OnIceCandidate"},"object":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","type":"OnIceCandidate"}}}
{"jsonrpc":"2.0","method":"onEvent","params":{"value":{"data":{"candidate":{"__module__":"kurento","__type__":"IceCandidate","candidate":"candidate:3 2 TCP 1015022846 fe80::5054:ff:fef2:132e 49448 typ host tcptype passive","sdpMLineIndex":0,"sdpMid":"audio0"},"source":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","tags":[],"timestamp":"1475555352","type":"OnIceCandidate"},"object":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","type":"OnIceCandidate"}}}
{"jsonrpc":"2.0","method":"onEvent","params":{"value":{"data":{"candidate":{"__module__":"kurento","__type__":"IceCandidate","candidate":"candidate:2 2 TCP 1019217150 fe80::5054:ff:fef2:132e 9 typ host tcptype active","sdpMLineIndex":0,"sdpMid":"audio0"},"source":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","tags":[],"timestamp":"1475555352","type":"OnIceCandidate"},"object":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","type":"OnIceCandidate"}}}
{"jsonrpc":"2.0","method":"onEvent","params":{"value":{"data":{"candidate":{"__module__":"kurento","__type__":"IceCandidate","candidate":"candidate:4 2 UDP 2013266430 202.44.12.183 52003 typ host","sdpMLineIndex":0,"sdpMid":"audio0"},"source":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","tags":[],"timestamp":"1475555352","type":"OnIceCandidate"},"object":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","type":"OnIceCandidate"}}}
{"jsonrpc":"2.0","method":"onEvent","params":{"value":{"data":{"candidate":{"__module__":"kurento","__type__":"IceCandidate","candidate":"candidate:6 2 TCP 1015022078 202.44.12.183 44986 typ host tcptype passive","sdpMLineIndex":0,"sdpMid":"audio0"},"source":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","tags":[],"timestamp":"1475555352","type":"OnIceCandidate"},"object":"5f0f76e9-270d-46e4-b93f-a04f0f98591b_kurento.MediaPipeline/b5af38f9-2696-4352-9965-f9af01caf055_kurento.WebRtcEndpoint","type":"OnIceCandidate"}}}
.
.
.
{"id":6,"jsonrpc":"2.0","result":{"sessionId":"5b12b64d-192a-4545-9812-16223ef3820f","value":null}}
It has both of TCP and UDP.
My Question is
1.which candidate to use for ReceiveCandidate in client. TCP or UDP if use TCP it's use typ host tcptype active or passive?
2.Or my client recieve all candidate from kurento?
thankyou fr advance,
During the WebRTC connection establishment, each peer sends a set of ICE candidates to the remote peer. Those candidates can be UDP, TCP, srflx (STUN), host or relay (TURN). When the remote peer receives the candidates, it starts probing those IPs and ports to see if a connection can be established. That's why each peer sends a number of them, so the remote peer has more chances of finding a valid candidate.
If you want to know which candidate pair is being used, you can subscribe to NewCandidatePairSelectedEvent from your WebRTC.

Which ICE candidate am I using and why?

[Questions in bold below]
I have setup Kurento Media Server 5.1.3 in a datacenter behind a firewall running OS Ubuntu 14.04. It has two network cards:
222.222.222.222 (eth0 - Private IP)
111.111.111.111 (eth1 - Public IP)
Attached below is the SDP (setRemoteDescription) when my browser connected to Kurento Media Server
type: answer, sdp: v=0
o=- 5487318114793304426 0 IN IP4 0.0.0.0
s=Kurento Media Server
c=IN IP4 0.0.0.0
t=0 0
a=group:BUNDLE audio video
m=audio 59068 RTP/SAVPF 111 0
c=IN IP4 111.111.111.111
a=rtpmap:111 opus/48000/2
a=rtpmap:0 PCMU/8000
a=sendrecv
a=rtcp:59068 IN IP4 111.111.111.111
a=rtcp-mux
a=ssrc:669011897 cname:user39019747#host-6e83e4c2
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=mid:audio
b=AS:20
a=ice-ufrag:YMdK
a=ice-pwd:LyLifK5UeqzPwM91DDj37e
a=fingerprint:sha-256 FF:0F:81:8C:41:4E:B4:B6:C6:D8:36:F3:D6:5F:09:FD:5F:AF:13:B3:9D:FC:12:66:AC:F3:56:D6:5B:0A:73:5D
a=candidate:1 1 UDP 2013266431 111.111.111.111 55239 typ host
a=candidate:2 1 UDP 2013266431 222.222.222.222 59068 typ host
a=candidate:4 1 UDP 1677721855 111.111.111.111 59068 typ srflx raddr 222.222.222.222 rport 59068
m=video 59068 RTP/SAVPF 100
c=IN IP4 111.111.111.111
b=AS:100
a=rtpmap:100 VP8/90000
a=sendrecv
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=rtcp-fb:100 goog-remb
a=rtcp:59068 IN IP4 111.111.111.111
a=rtcp-mux
a=ssrc:138242433 cname:user39019747#host-6e83e4c2
a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time
a=mid:video
a=ice-ufrag:YMdK
a=ice-pwd:LyLifK5UeqzPwM91DDj37e
a=fingerprint:sha-256 FF:0F:81:8C:41:4E:B4:B6:C6:D8:36:F3:D6:5F:09:FD:5F:AF:13:B3:9D:FC:12:66:AC:F3:56:D6:5B:0A:73:5D
a=candidate:1 1 UDP 2013266431 111.111.111.111 55239 typ host
a=candidate:2 1 UDP 2013266431 222.222.222.222 59068 typ host
a=candidate:4 1 UDP 1677721855 111.111.111.111 59068 typ srflx raddr 222.222.222.222 rport 59068
I am not sure, but it seems like I am using the following candidate:
a=candidate:4 1 UDP 1677721855 111.111.111.111 59068 typ srflx raddr 222.222.222.222 rport 59068
Am I right?
But given the fact that the IP 222.222.222.222 is an internal IP why does it appears in as ICE candidate?
Why doesn't it pick "a=candidate:1 1 UDP 2013266431 111.111.111.111 55239 typ host"? since this IP is publicly accessible.
When using tools like "nload" to check for traffic, eth0 doesn't have any traffic, and can noticed eth1 got a lot of traffic (video and audio stream)
What does this "a=candidate:4 1 UDP 1677721855 111.111.111.111 59068 typ srflx raddr 222.222.222.222 rport 59068" means?
The WebRTC client tries all ICE candidates until it finds one that works. There is a priority queue for the ICE candidates which all of the potential addresses are added to. WebRTC tries these one at a time, and once it finds one that works, it uses that candidate for media. WebRTC does not know which address is your public and which is your private, it simply tries candidates until one succeeds or all of them fail.
ICE is designed to create connections in the presence of NAT issues.
If you are experiencing delays, and you control the client software, you can dictate the order in which the candidates are picked. Some even start directly [A world class Social network] to the TURN addresses before negotiating back to other if possible. If the run in the order of top to bottom there is always a risk.
And if you have a few private interfaces due to VPN or Virtual Networks, it becomes even slower.
We have added an event in current development version (6.4.1-dev). That indicates the candidates that are in use on a webrtc connection. Maybe this can help you debugging your problems.

Handle WebRTC ICE candidates (from TURN Server) manually

I am working on WebRTC framework, establishing peer connection between two Android mobile devices for voice and video calls. And now I want to move my solution to the public network where the NAT plays a major role.
My solution has to work in Symmetric NAT as well, but my STUN server is failing to establish voice/video call when it the devices are connected in Symmetric NAT. So I went to TURN server setup and did the setup successfully by the help of the following tutorial.
Free open source implementation of TURN and STUN Server
Setting up a TURN Server for WebRTC Use
And I have successfully added this server into the ICEServers of my Android application and started getting relay ICE candidates.
The candidates I am getting looks something like this
a=candidate:2312680776 1 udp 33562367 115.113.119.170 52972 typ relay raddr 223.227.91.151 rport 25323 generation 0
a=candidate:2312680776 2 udp 33562366 115.113.119.170 64698 typ relay raddr 223.227.91.151 rport 25324 generation 0
Now my question starts:
How should I assume these candidates ?? (As I want to handle these candidates manually instead of just passing these candidates to the other end)
I know how to understand srflx but not relay.
relay is followed by my global IP address and port. So does that mean I have to listen on raddr and rport to catch the audio/video data??
How should I parse these candidates and get the audio/video data ??
Note : In wireshark I am able to see the data packets coming from my TURN server on the port which is not equal to both the rport fields mentioned above in candidates.
And I read somewhere that I have to listen for some Allocate Response from TURN server.
I really need to know how do I do that. Any help about this topic will be greatly appreciated. :(