Troubleshooting TURN server

1,055 views
Skip to first unread message

Ken Smith

unread,
Mar 26, 2013, 4:03:41 PM3/26/13
to discuss-webrtc
I've setup and configured a TURN server (Oleg's very helpful https://code.google.com/p/rfc5766-turn-server/), but I'm running into trouble getting it working. Presumably this is the result of some issue or ignorance on my part, but I haven't been able to track it down.

Here's what I've done so far:

- Installed an Ubuntu 12.10 instance on Azure.

- Opened up ports 3478 (tcp/udp) + 60000-60100 (udp) via the Azure management tools (i.e., created "endpoints" which map specific ports from the server's external IP address of 168.61.73.72 to the internal address of 100.68.58.111).

- Downloaded, compiled and installed rfc5766-turn-server v. 1.7.0.0

- Launched the turn server with this command-line:
turnserver -X 168.61.73.72 --no-tls --no-dtls --min-port 60000 --max-port 60100 -v

Using the "-v" parameter, this is what the TURN server says when it launches:

RFC 5389/5766/6062/6156 STUN/TURN Server, version Citrix-1.7.0.0 'Glokta'
File found: ../etc/turnserver.conf
File found: ../etc/turnserver.conf
File found: ../etc/turnuserdb.conf
===========Discovering listener addresses: =========
Listener address to use: 127.0.0.1
Listener address to use: 100.68.58.111
Listener address to use: ::1
=====================================================
===========Discovering relay addresses: =============
Relay address to use: 100.68.58.111
=====================================================
IO method (listener thread): epoll
create_server_socket:209:start

IPv4. UDP listener opened on : 127.0.0.1:3478
create_server_socket:243:end
create_server_socket:209:start

IPv4. UDP listener opened on : 127.0.0.1:3479
create_server_socket:243:end
create_server_listener:130:start

IPv4. TCP listener opened on : 127.0.0.1:3478
create_server_listener:168:end
create_server_listener:130:start

IPv4. TCP listener opened on : 127.0.0.1:3479
create_server_listener:168:end
create_server_socket:209:start

IPv4. UDP listener opened on : 100.68.58.111:3478
create_server_socket:243:end
create_server_socket:209:start

IPv4. UDP listener opened on : 100.68.58.111:3479
create_server_socket:243:end
create_server_listener:130:start

IPv4. TCP listener opened on : 100.68.58.111:3478
create_server_listener:168:end
create_server_listener:130:start

IPv4. TCP listener opened on : 100.68.58.111:3479
create_server_listener:168:end
create_server_socket:209:start

IPv6. UDP listener opened on : ::1:3478
create_server_socket:243:end
create_server_socket:209:start

IPv6. UDP listener opened on : ::1:3479
create_server_socket:243:end
create_server_listener:130:start

IPv6. TCP listener opened on : ::1:3478
create_server_listener:168:end
create_server_listener:130:start

IPv6. TCP listener opened on : ::1:3479
create_server_listener:168:end
IO method (auth thread): epoll
run_listener_server: cycle=1, stats=0
timer_event_handler: timeout 0xec38a0: timer_handler
timer_event_handler: timeout 0xec38a0: timer_handler

If I use this server merely for its STUN capabilities, it works. However, I haven't actually been able to get it to relay traffic.

In a scenario where I need it to relay traffic, using Chrome 26 stable on a PC going against Chrome 25 stable on a Mac (on a separate subnet, but connected to the same router), this is what I see (using Wireshark):

- An initial Binding Request against the TURN server, followed by a Binding Success Response.
- A whole bunch of (apparently failed) Binding Requests against the remote NAT router's external IP address.
- An Allocate Request against the TURN server, followed by a Allocate Success Response with the attributes XOR-RELAYED-ADDRESS 168.61.73.72:60005 (a port on my TURN server), an XOR-MAPPED-ADDRESS 98.247.37.95:63840 (a port on the router), and LIFETIME 600.

And then the scenario above repeats five or six times over the next 20 seconds or so.

In theory, I think that I should be seeing a Create Permission exchange after the Allocate Success Response packet, but I'm not.

On the Chrome client, I'm seeing this in the debug logs:

STUN server has found an ICE candidate (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Sending ICE candidate to the remote machine: {"sdpMLineIndex":0,"sdpMid":"audio","candidate":"a=candidate:1434301788 1 udp 2113937151 192.168.0.10 54604 typ host generation 0\r\n"} Alanta.min.js:336
STUN server has found an ICE candidate (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Sending ICE candidate to the remote machine: {"sdpMLineIndex":0,"sdpMid":"audio","candidate":"a=candidate:1493399139 1 udp 2113937151 192.168.1.12 54605 typ host generation 0\r\n"} Alanta.min.js:336
STUN server has found an ICE candidate (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Sending ICE candidate to the remote machine: {"sdpMLineIndex":0,"sdpMid":"audio","candidate":"a=candidate:2999745851 1 udp 2113937151 192.168.56.1 54606 typ host generation 0\r\n"} Alanta.min.js:336
STUN server has found an ICE candidate (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Sending ICE candidate to the remote machine: {"sdpMLineIndex":1,"sdpMid":"video","candidate":"a=candidate:1434301788 1 udp 2113937151 192.168.0.10 54604 typ host generation 0\r\n"} Alanta.min.js:336
STUN server has found an ICE candidate (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Sending ICE candidate to the remote machine: {"sdpMLineIndex":1,"sdpMid":"video","candidate":"a=candidate:1493399139 1 udp 2113937151 192.168.1.12 54605 typ host generation 0\r\n"} Alanta.min.js:336
STUN server has found an ICE candidate (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Sending ICE candidate to the remote machine: {"sdpMLineIndex":1,"sdpMid":"video","candidate":"a=candidate:2999745851 1 udp 2113937151 192.168.56.1 54606 typ host generation 0\r\n"} Alanta.min.js:336
STUN server has found an ICE candidate (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Sending ICE candidate to the remote machine: {"sdpMLineIndex":0,"sdpMid":"audio","candidate":"a=candidate:2741881992 1 udp 1845501695 98.247.37.95 54604 typ srflx raddr 192.168.0.10 rport 54604 generation 0\r\n"} Alanta.min.js:336
STUN server has found an ICE candidate (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Sending ICE candidate to the remote machine: {"sdpMLineIndex":1,"sdpMid":"video","candidate":"a=candidate:2741881992 1 udp 1845501695 98.247.37.95 54604 typ srflx raddr 192.168.0.10 rport 54604 generation 0\r\n"} Alanta.min.js:336
Preparing to handle ICE candidate from remote machine. Alanta.min.js:336
Adding ICE candidate received from remote machine to the local peerConnection: {"sdpMLineIndex":0,"sdpMid":"audio","candidate":"a=candidate:4033732497 1 udp 2113937151 192.168.0.104 55902 typ host generation 0\r\n"} Alanta.min.js:336
Ice candidate added (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Hiding details Alanta.min.js:336
Handling oneicechange (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Preparing to handle ICE candidate from remote machine. Alanta.min.js:336
Adding ICE candidate received from remote machine to the local peerConnection: {"sdpMLineIndex":1,"sdpMid":"video","candidate":"a=candidate:4033732497 1 udp 2113937151 192.168.0.104 55902 typ host generation 0\r\n"} Alanta.min.js:336
Ice candidate added (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Preparing to handle ICE candidate from remote machine. Alanta.min.js:336
Adding ICE candidate received from remote machine to the local peerConnection: {"sdpMLineIndex":0,"sdpMid":"audio","candidate":"a=candidate:4033732497 2 udp 2113937151 192.168.0.104 55902 typ host generation 0\r\n"} Alanta.min.js:336
Ice candidate added (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Preparing to handle ICE candidate from remote machine. Alanta.min.js:336
Adding ICE candidate received from remote machine to the local peerConnection: {"sdpMLineIndex":1,"sdpMid":"video","candidate":"a=candidate:4033732497 2 udp 2113937151 192.168.0.104 55902 typ host generation 0\r\n"} Alanta.min.js:336
Ice candidate added (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Preparing to handle ICE candidate from remote machine. Alanta.min.js:336
Adding ICE candidate received from remote machine to the local peerConnection: {"sdpMLineIndex":0,"sdpMid":"audio","candidate":"a=candidate:1898305829 1 udp 1845501695 98.247.37.95 55902 typ srflx raddr 192.168.0.104 rport 55902 generation 0\r\n"} Alanta.min.js:336
Ice candidate added (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Preparing to handle ICE candidate from remote machine. Alanta.min.js:336
Adding ICE candidate received from remote machine to the local peerConnection: {"sdpMLineIndex":0,"sdpMid":"audio","candidate":"a=candidate:1898305829 2 udp 1845501695 98.247.37.95 55902 typ srflx raddr 192.168.0.104 rport 55902 generation 0\r\n"} Alanta.min.js:336
Ice candidate added (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Preparing to handle ICE candidate from remote machine. Alanta.min.js:336
Adding ICE candidate received from remote machine to the local peerConnection: {"sdpMLineIndex":1,"sdpMid":"video","candidate":"a=candidate:1898305829 1 udp 1845501695 98.247.37.95 55902 typ srflx raddr 192.168.0.104 rport 55902 generation 0\r\n"} Alanta.min.js:336
Ice candidate added (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Preparing to handle ICE candidate from remote machine. Alanta.min.js:336
Adding ICE candidate received from remote machine to the local peerConnection: {"sdpMLineIndex":1,"sdpMid":"video","candidate":"a=candidate:1898305829 2 udp 1845501695 98.247.37.95 55902 typ srflx raddr 192.168.0.104 rport 55902 generation 0\r\n"} Alanta.min.js:336
Ice candidate added (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Preparing to handle ICE candidate from remote machine. Alanta.min.js:336
Adding ICE candidate received from remote machine to the local peerConnection: {"sdpMLineIndex":0,"sdpMid":"audio","candidate":"a=candidate:3203277665 1 tcp 1509957375 192.168.0.104 51524 typ host generation 0\r\n"} Alanta.min.js:336
Ice candidate added (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Preparing to handle ICE candidate from remote machine. Alanta.min.js:336
Adding ICE candidate received from remote machine to the local peerConnection: {"sdpMLineIndex":1,"sdpMid":"video","candidate":"a=candidate:3203277665 1 tcp 1509957375 192.168.0.104 51524 typ host generation 0\r\n"} Alanta.min.js:336
Ice candidate added (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
STUN server has found an ICE candidate (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Sending ICE candidate to the remote machine: {"sdpMLineIndex":0,"sdpMid":"audio","candidate":"a=candidate:469649836 1 tcp 1509957375 192.168.0.10 44349 typ host generation 0\r\n"} Alanta.min.js:336
STUN server has found an ICE candidate (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Sending ICE candidate to the remote machine: {"sdpMLineIndex":1,"sdpMid":"video","candidate":"a=candidate:469649836 1 tcp 1509957375 192.168.0.10 44349 typ host generation 0\r\n"} Alanta.min.js:336
STUN server has found an ICE candidate (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Sending ICE candidate to the remote machine: {"sdpMLineIndex":0,"sdpMid":"audio","candidate":"a=candidate:394300051 1 tcp 1509957375 192.168.1.12 44350 typ host generation 0\r\n"} Alanta.min.js:336
STUN server has found an ICE candidate (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Sending ICE candidate to the remote machine: {"sdpMLineIndex":0,"sdpMid":"audio","candidate":"a=candidate:4233069003 1 tcp 1509957375 192.168.56.1 44351 typ host generation 0\r\n"} Alanta.min.js:336
STUN server has found an ICE candidate (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Sending ICE candidate to the remote machine: {"sdpMLineIndex":1,"sdpMid":"video","candidate":"a=candidate:394300051 1 tcp 1509957375 192.168.1.12 44350 typ host generation 0\r\n"} Alanta.min.js:336
STUN server has found an ICE candidate (iceGatheringState=gathering; iceState=undefined; readyState=stable) Alanta.min.js:336
Sending ICE candidate to the remote machine: {"sdpMLineIndex":1,"sdpMid":"video","candidate":"a=candidate:4233069003 1 tcp 1509957375 192.168.56.1 44351 typ host generation 0\r\n"} Alanta.min.js:336
Call preparations succeeded

But neither audio nor video shows up at that point.

Sorry that this email is so long. But any thoughts about why it's not working, or what I'm doing wrong?

Oleg Moskalenko

unread,
Mar 26, 2013, 5:26:24 PM3/26/13
to discuss...@googlegroups.com
Hi Ken

as far as I can see in the provided information, you did not set the long-term authentication option (-a).WebRTC requires that TURN server must be "secure" - with authorized access. After initial Allocate request the TURN server must return 401 error and then the client will authenticate itself. In your case, it return Success immediately, it means that the authentication is not configured.

So, you have to add -a option and you have to set user accounts in turnuserdb.conf (with turnadmin), if you are using flat file user DB,or in PostgreSQL if you are using database.

See the turnserver man page or the README file.

Regards,
Oleg

Ken Smith

unread,
Mar 26, 2013, 6:38:27 PM3/26/13
to discuss-webrtc
Thanks, Oleg, that makes sense. I'd had the secure option turned on before, but was getting various odd "realm" errors that I didn't understand. I'm still not sure exactly what I was doing wrong previously, but I changed the command-line to this:

turnserver -X 168.61.73.72 --no-tls --no-dtls --min-port 60000 --max-port 60100 -u alanta:password -r alanta.com -a

And then set my RTCPeerConnection config like so:

var config = {
	iceServers: [
		{ url: "turn:ala...@alantaux1.cloudapp.net:3478""credential""password" },
	]
};
And that seems to work. I'll have to figure out the user database later, but that's a separate issue.


--
 
---
You received this message because you are subscribed to the Google Groups "discuss-webrtc" group.
To unsubscribe from this group and stop receiving emails from it, send an email to discuss-webrt...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Reply all
Reply to author
Forward
0 new messages