Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

STUN/TURN server connectivity test

Tags:

webrtc

stun

turn

I am trying to figure out how to test whether a STUN/TURN server is alive and properly responding to connections. Ideally this test would be performed from an external machine, just in case the STUN/TURN machine is down for this case should also be reported by the connectivity test.

Has anyone looked into this case in the past? What solutions would be recommended?

like image 417
mirazour Avatar asked Feb 27 '15 18:02

mirazour


People also ask

How do I know if my STUN server is working?

You can easily determine if your server works with both tools or with your own JavaScript: A STUN server works if you can gather a candidate with type "srflx" . A TURN server works if you can gather a candidate with type "relay" .

What is STUN server vs TURN?

The STUN, TURN, and TURNS ProtocolsSession Traversal Utilities for NAT (STUN) - Used to establish a direct UDP connection between two clients. Traversal Using Relay around NAT (TURN) - Used to establish a relayed UDP or TCP connection between two clients.

What is trickle WebRTC?

ICE is used in WebRTC and in SIP for finding the possible media routes for a session. In essence, the process involves gathering candidates and checking connectivity to see if a connection between the parties is possible using each of the candidates.

Are STUN servers free?

Free and public Session Traversal Utilities for NAT serverThere are various free STUN servers available out there. It is lightweight and carry no real authentication mechanism to it. This makes it simple for developers to connect to freeservers without any technical hurdles. It is not advisable to do so.


2 Answers

Edit: A nice implementation in github.io taken from comment to another answer( choose "relay" in IceTransports value):

Test TURN Server


following Benjamin Trent's advice, I wrote the below code to test TURN server's connectivity, works on both firefox n chrome:

function checkTURNServer(turnConfig, timeout){     return new Promise(function(resolve, reject){      setTimeout(function(){         if(promiseResolved) return;         resolve(false);         promiseResolved = true;     }, timeout || 5000);      var promiseResolved = false       , myPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection   //compatibility for firefox and chrome       , pc = new myPeerConnection({iceServers:[turnConfig]})       , noop = function(){};     pc.createDataChannel("");    //create a bogus data channel     pc.createOffer(function(sdp){       if(sdp.sdp.indexOf('typ relay') > -1){ // sometimes sdp contains the ice candidates...         promiseResolved = true;         resolve(true);       }       pc.setLocalDescription(sdp, noop, noop);     }, noop);    // create offer and set local description     pc.onicecandidate = function(ice){  //listen for candidate events       if(promiseResolved || !ice || !ice.candidate || !ice.candidate.candidate || !(ice.candidate.candidate.indexOf('typ relay')>-1))  return;       promiseResolved = true;       resolve(true);     };   });    } 

example usage:

checkTURNServer({     urls: 'turn:127.0.0.1',     username: 'test',     credential: 'test' }).then(function(bool){     console.log('is TURN server active? ', bool? 'yes':'no'); }).catch(console.error.bind(console)); 

You can run the below snippet to check:

var res = id('result');    id('button').onclick = function(){  	res.innerHTML = 'Checking TURN Server...';    var url = 'turn:'+id('url').value+':'+id('port').value,    		useUDP = id('udp').checked;    url +='?transport=' + (useUDP ? 'udp': 'tcp');    checkTURNServer({        urls: url,        username: id('name').value,         credential: id('pass').value    }, id('time').value).then(function(bool){    		if(bool)           res.innerHTML = 'Yep, the TURN server works...';        else           throw new Error('Doesn\'t work');    }).catch(function(e){    	 console.log(e);       res.innerHTML = 'TURN server does not work.';    });  };      function checkTURNServer(turnConfig, timeout){   	console.log('turnConfig: ', turnConfig);    return new Promise(function(resolve, reject){        setTimeout(function(){          if(promiseResolved) return;          resolve(false);          promiseResolved = true;      }, timeout || 5000);        var promiseResolved = false        , myPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection   //compatibility for firefox and chrome        , pc = new myPeerConnection({iceServers:[turnConfig]})        , noop = function(){};      pc.createDataChannel("");    //create a bogus data channel      pc.createOffer(function(sdp){        if(sdp.sdp.indexOf('typ relay') > -1){ // sometimes sdp contains the ice candidates...          promiseResolved = true;          resolve(true);        }        pc.setLocalDescription(sdp, noop, noop);      }, noop);    // create offer and set local description      pc.onicecandidate = function(ice){  //listen for candidate events        if(promiseResolved || !ice || !ice.candidate || !ice.candidate.candidate || !(ice.candidate.candidate.indexOf('typ relay')>-1))  return;        promiseResolved = true;        resolve(true);      };    });     }      function id(val){  	return document.getElementById(val);  }
#url{    width: 250px;  }  #port{    width: 70px;  }
<h1>   Test TURN server  </h1>  <div>  TURN URL: <input id='url' placeholder='example.com  or  xxx.yyy.rrr.ddd'  />  Port: <input type='number' value='3478' id='port' placeholder='enter a port number' />  </div>  <div>  Transport: <input type="radio" name="transport" id="tcp" value="tcp" /> TCP  <input type="radio" name="transport" id="udp" value="udp" checked/>UDP  </div>    <div>  Username: <input id="name" placeholder="turn username" />  </div>  <div>  password: <input id="pass" placeholder="turn password" />  </div>    <div>  checking Timeout: <input type='number'  id="time" placeholder="wait time  before checking timeout" value=5000 />  </div>  <div>  <button id='button'>  Check TURN Server  </button>  </div>    <h4 id='result'></h4>
like image 67
mido Avatar answered Sep 19 '22 18:09

mido


You can test your servers here...

https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/

like image 25
gugaiz Avatar answered Sep 19 '22 18:09

gugaiz