STUN (Session Traversal Utilities for NAT) and TURN (Traversal Using Relays around NAT) are protocols that can be used to provide NAT traversal for VoIP and WebRTC. These projects provide a VoIP media traffic NAT traversal server and gateway.
TURN Server is a VoIP media traffic NAT traversal server and gateway.
This article describes working with some of the TURN servers
- rfc5766-turn-server ( legacy )
- COTURN
- Xirsys TURN service
- Twillio TURN Server
- Asterisk ICE resolution
- Kamailio NAT and STUN modules in Server
We know that a STUN only server such as the one below , may not work under firewalls like in enterperises or even in universities resulting in black video , one way video , inconcsistent streaming or even no video experience .
// google STUN
var iceservers_array=[{urls: 'stun:stun.l.google.com:19302'}] ;
To overcome this we rely on a publicaly avaiable TURN server which can step in and do ICE exchange to seup relay routes for the media stream. Some of the options for both self hosted and TURN as a service are described below .
rfc5766-turn-server
It is a legacy project mainly archives for reference( links at the end of section). This is a VoIP gateway for inter network communication which is opensource MIT licensed .
platforms supported : Any client platform is supported, including Android, iOS, Linux, OS X, Windows, and Windows Phone. This project can be successfully used on other *NIX platforms ( Aamazon EC2) too. It supports flat file or Database based user management system ( MySQL , postgress , redis ). The source code project contains , TURN server , TURN client messaging library and some sample scripts to test various modules like protocol , relay , security etc .
Protocols : Protocols between the TURN client and the TURN server – UDP, TCP, TLS, and DTLS. Relay protocol – UDP , TCP .
Authentication : The authentication mechanism is using key which is calculated over the user name, the realm, and the user password. Key for the HMAC depends on whether long-term or short-term credentials are in use. For long-term credentials, the key is 16 bytes: key = MD5(username “:” realm “:” SASLprep(password))
Installation : Since I used my Ubuntu Software center for installing the RFC turn server 5677 .

More information is on Ubuntu Manuals : http://manpages.ubuntu.com/manpages/trusty/man1/turnserver.1.html
The content got stored inside /usr/share/rfc5766-turn-server. Also install mysql for record keeping
sudo apt-get install mysql-server


Intall MySQL workbench to monitor the values feed into the turn database server in MysqL. connect to MySQL instance using the following screenshot

The database formed with mysql after successful operation is as follows . We shall notice that the initial db is absolutely null

Terminal Commands
These terminal command ( binary images ) get stored inside etc/init.d after installing
turnadmin – Its turn relay administration tool used for generating , updating keys and passwords . For generating a key to get long term crdentaial use -k command and for aading or updateing a long -term user use the -a command. Therefore a simple command to generate a key is
format : turnadmin -k -u -r -p
turnadmin -k -u turnwebrtc -r mycompany.com -p turnwebrtc
The generated key is displayed in console . For example the following screenshot shows this :
To fill in user with long term credentails
Format : turnadmin -a [-b | -e | -M | -N ] -u -r -p
turnadmin -a -M "host=localhost dbname=turn user=turn password=turn" -u altanai -r mycompany.com -p 123456
Check the values reflected in MySQL workbench for long term user table . ( screenshot depicts two entries for altanai and turnwebrtc user )

you can also check it on console using the -l command
format :turnadmin -l –mysql-userdb=””
turnadmin -l --mysql-userdb="host=127.0.0.1 dbname=turn user=turnwebrtc password=turnwebrtc connect_timeout=30"

or we can also check using the terminal based mySQL client
mysql> use turn;
Database changed
mysql> select * from turnusers_lt; +------------+----------------------------------+ | name | hmackey | +------------+----------------------------------+ | altanai | 57bdc681481c4f7626bffcde292c85e7 | | turnwebrtc | 6066cbe0b5ee14439b2ddfc177268309 | +------------+----------------------------------+ 2 rows in set (0.00 sec)
turnserver – Its command to handle the turnserver itself . We can use the simple turnserver command to start it without any db support using just turnserver. Screenshot for this is

We can use a database like mysql to start it with db connection string
Format : turnserver –mysql-userdb=””
turnserver --mysql-userdb="host=127.0.0.1 dbname=turn user=turnwebrtc password=turnwebrtc connect_timeout=30"
turnutils_uclient: emulates multiple UDP,TCP,TLS or DTLS clients.
turnutils_peer: simple stateless UDP-only “echo” server. For every incoming UDP packet, it simply echoes it back.
turnutils_stunclient: simple STUN client example that implements RFC 5389 ( using STUN as endpoint to determine the IP address and port allocated to it , keep-alive , check connectivity etc) and RFC 5780 (experimental NAT Behavior Discovery STUN usage) .
turnutils_rfc5769check: checks the correctness of the STUN/TURN protocol implementation. This program will perform several checks and print the result on the screen. It will exit with 0 status if everything is OK, and with (-1) if there was an error in the protocol implementation.
Test
1. Test vectors from RFC 5769 to double-check that our STUN/TURN message encoding algorithms work properly. Run the utility to check all protocols :
$ cd examples
$ ./scripts/rfc5769.sh
2. TURN functionality test (bare minimum TURN example).
If everything compiled properly, then the following programs must run together successfully, simulating TURN network routing in local loopback networking environment:
console 1 :
$ ./scripts/basic/relay.sh
console2 :
$ ./scripts/peer.sh
If the client application produces output and in approximately 22 seconds prints the jitter, loss and round-trip-delay statistics, then everything is fine.
Usage
iceServers:[
{ 'url': 'stun: altanai@mycompany.com'},
{ 'url': 'turn: altanai@mycompany.com', 'credential': '123456'}]
Insert the above piece of code on peer connection config . Now call from one network environment to another . For example call from a enterprise network behind a Wifi router to a public internet datacard webrtc agent . The call should connect with video flowing smoothly between the two .

website : https://code.google.com/p/rfc5766-turn-server/
Download the executable from : http://turnserver.open-sys.org/downloads/v3.2.5.4/
coturn
Project Coturn evolved from rfc5766-turn-server project with many new advanced TURN specs beyond the original RFC 5766 document. The databses supported are : SQLite , MySQL , PostgreSQL , Redis , MongoDB
Protocols :
The implementation fully supports the following client-to-TURN-server protocols: UDP , TCP , TLS SSL3/TLS1.0/TLS1.1/TLS1.2; ECDHE , DTLS versions 1.0 and 1.2. Supported relay protocols UDP (per RFC 5766) and TCP (per RFC 6062)
Authetication :
Supported message integrity digest algorithms:
- HMAC-SHA1, with MD5-hashed keys (as required by STUN and TURN standards)
- HMAC-SHA256, with SHA256-hashed keys (an extension to the STUN and TURN specs)
Supported TURN authentication mechanisms:
- ‘classic’ long-term credentials mechanism;
- TURN REST API (a modification of the long-term mechanism, for time-limited secret-based authentication, for WebRTC applications:http://tools.ietf.org/html/draft-uberti-behave-turn-rest-00);
- experimental third-party oAuth-based client authorization option;
Installation
Install libopenssl and libevent plus its dev or extra libraries .
OpenSSL has to be installed before libevent2 for TLS beacuse When libevent builds it checks whether OpenSSL has been already installed, and its version.
Download coturn readonly from
svn checkout http://coturn.googlecode.com/svn/trunk/ coturn-read-only
extract the tar contents
$ tar xvfz turnserver-.tar.gz
go inside the extracted folder and run the following command to build
$ ./configure
$ make
$ make install
Adding users in the format using turnadmin
$ Sudo turnadmin -a -u -r -p
$ Sudo turnadmin -a -u altanai -r myserver.com -p 123456
Start the turn Server using turnserver from inside of /etc/init.d using the start command
$ sudo /etc/init.d/coturn start

The logs are usually stored in /var/log . Screenshot of log file

The default configured port is 3478.If other port is needed, change the file /etc/turnserver.conf
Usuage:
Specify the values in Peer Connection
iceServers:[
{ ‘url’: ‘stun: altanai@myserver.com’},
{ ‘url’: ‘turn: altanai@myserver.com’, ‘credential’: ‘123456’}]
Specifications:
TURN specs:
- RFC 5766 -Traversal Using Relays around NAT (TURN):Relay Extensions to Session Traversal Utilities for NAT (STUN)
- RFC 6062 -Traversal Using Relays around NAT (TURN) Extensions for TCP Allocations
- RFC 6156 – IPv6 extension for TURN
- RFC 7443 – ALPN support for STUN & TURN
- Datagram Transport Layer Security (DTLS) as Transport for Traversal Using Relays around NAT (TURN) . It facilitate the resolution of TURN URIs into the IP address and port of TURN servers supporting DTLS as a transport protocol.
- Mobile ICE (MICE) – Mobility with TURN . It minimizes traffic disruption caused by changing IP address during a mobility event by shorter network path .
- TURN REST API (http://tools.ietf.org/html/draft-uberti-behave-turn-rest-00)
- Origin field in TURN (Multi-tenant TURN Server) (https://tools.ietf.org/html/draft-ietf-tram-stun-origin-05)
- TURN Bandwidth draft specs (http://tools.ietf.org/html/draft-thomson-tram-turn-bandwidth-01)
- TURN-bis (with dual allocation) draft specs (http://tools.ietf.org/html/draft-ietf-tram-turnbis-01)
- Third-party authorization support (http://tools.ietf.org/html/draft-ietf-tram-turn-third-party-authz-13).
STUN specs:
- RFC 3489 – STUN – Simple Traversal of User Datagram Protocol (UDP) Through Network Address Translators (NATs)
- RFC 5389 – Session Traversal Utilities for NAT (STUN)
- RFC 5769 – test vectors for STUN protocol testing
- RFC 5780 – NAT behavior discovery support
- RFC 7443 – Application-Layer Protocol Negotiation (ALPN) Labels for STUN and TURN
ICE :
- RFC 5245 – ICE
- RFC 5768 – ICE–SIP
- RFC 6336 – ICE–IANA Registry
- RFC 6544 – ICE–TCP
- RFC 5928 – TURN Resolution Mechanism
website : https://code.google.com/p/coturn/
Chorme WebRTC Internals Page for COTURN connection
Xirsys
Xirsys is a provider for WebRTC infrastructure which included stun and turn server hosting as well .
The process of using their services includes singing up for a account and choosing whether you want a paid service capable of handling more calls simultaneously or free one handling only upto 10 concurrent turn connections .
The dashboard appears like this :

To receive the api one need to make a one time call to their service , the result of which contains the keys to invoke the turn services from webrtc script .
window.addEventListener("load", function (e) {
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function ($evt) {
if (xhr.readyState == 4 && xhr.status == 200) {
let res = JSON.parse(xhr.responseText);
console.log("response: ", res);
iceservers_array.push(res.v.iceServers);
alert( iceservers_array);
}
};
xhr.open("PUT", "https://global.xirsys.net/_turn/webrtc", true);
xhr.setRequestHeader("Authorization","Basic " + btoa("altanai:<sec rettoken>"));
xhr.setRequestHeader("Content-Type","application/json");
xhr.send(JSON.stringify({"format": "urls"}));
});
The resulting output should look like ( my keys are hidden with a red rectangle ofcourse )


The process of adding a TURN / STUN to your webrtc script in JS is as follows :
iceServers:[
{"url":"stun:turn2.xirsys.com"},
{"username":"< put your API username>","url":"turn:turn2.xirsys.com:443?transport=udp","credential":"< put your API credentail>"},
{"username":"< put your API username>","url":"turn:turn2.xirsys.com:443?transport=tcp","credential":"< put your API credentail>"}]
website : http://xirsys.com/technology/
Twillio TURN Server
// before unload update status on main site
window.addEventListener("load", function (e) {
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function ($evt) {
if (xhr.readyState == 4 && xhr.status == 200) {
let res = JSON.parse(xhr.responseText);
console.log("response: ", res);
iceservers_array = res.iceServers;
console.log("iceservers_array: ", iceservers_array);
CallSessionBegins();
}
};
xhr.open("POST", "https://<ourdomain>:3000/token", true);
xhr.setRequestHeader("Content-Type","application/json");
xhr.send(JSON.stringify({"format": "urls"}));
});
Asterisk TURN module and service
Asterisk is an open source carrer grade SIP server which also provides Firewall traversal . A github repo containing some asterisk dialplan examples is https://github.com/altanai/asteriskexamples. An article discussing Asterisk and its implementation
Asterisk – installation and dial plans for WebRTC supported PJSIP clients
Asterisk is a framework or toolkit designed for VOIP systems . It can support Enterprise communication systems like PBXs, call distributors, VoIP gateways , conference bridges etc . It is open source and free to use . It is developed in C and runs in linux . Technically , Asterisk has protocol support for many…
Kamailio NAT and STUN modules in Server
It is also interesting to note that majority of popular open source SIP servers also have an implementation , libabary or module for STUN/TURN such as Kamailio’s STUN module https://www.kamailio.org/docs/modules/devel/modules/stun.html
You can read more about the kamailio DNS and NATing here
Kamailio DNS and NAT
DNS sub-system in Kamailio DNS failoverDNS load balancingNAT ( Network Address Translation)NAT ( Network Address Translation)Why is NAT is important in SIP?Types of NAT solutionsNAT behavioursRTP NATFixing NATNAT Traversal ModuleWhy use keepalive when Registrations are already there for NATing ?How keepalives work for NATing ?function nat_keepalive()ParamsFunctionsclient_nat_test()fix_contact()nat_keepalive()Pseudo VariablesStatisticsNATHelper ModuleNAT pinging typesUDP packetSIP requestparamsfunctionsPseudo VariablesRPC Commands In…