← View all posts
April 6, 2017

Active ICE TCP to punch through firewalls directly

Contributed by Nils Ohlmeier, Hacking on real time communications since 2002

Iceberg with hole near Sandersons Hope 2007-07-28 2

With the landing of bug 1335939 in Firefox 54 we will finally turn on active ICE TCP connections by default.

Does ICE TCP matter for me?

In essence it means that Firefox will try opening ICE connections over TCP towards any other ICE endpoint which provides ICE TCP candidates where it is listening for incoming connections. The most common use case for this is Firefox now being able to make direct TCP connections to media servers without the help of TURN TCP.

In more depth

ICE TCP is supposed to achieve connectivity in cases where the regular ICE over UDP does not work. It is supposed to generate three different new ICE candidates:

  • active ICE TCP candidates
  • passive ICE TCP candidates
  • simultaneous open ICE TCP candidates

Number one, the active ICE TCP candidate, means the ICE implementation can act as a TCP client. It will try to establish a new TCP connection to a listening socket on the other side. This is what we ship in Firefox 54 by default now.

The passive ICE TCP candidate means the implementation can listen on a port for an incoming TCP connection. While Firefox supports this for non-e10s, we don’t have support for it with e10s (a.k.a. multi-process support). Our assumption is that most Firefox instances are not running in environments where they are actually able to receive incoming connections. Therefore we will leave this off for now.

The last candidate type, simultaneous open, means the implementation listens on the same port it uses to form outgoing connections. In other words, it acts as a client and server from the same port at the same time. As we lack the ability to listen for incoming TCP connections with e10s, this mode also only works if e10s is off.

So what can Firefox do now?

Firefox 54 will start to emit active ICE TCP candidates. These candidates are not very useful by themselves as they are masked with port number 9 to prevent any one from trying to connect to them. Here is an example of what they look like:

  {"candidate":"candidate:4 1 TCP 2105458943 9 typ host tcptype active","sdpMid":"sdparta_0","sdpMLineIndex":0}
  {"candidate":"candidate:5 1 TCP 2105524479 2601:647:4601:ec84:149:a26e:2dba:f3fb 9 typ host tcptype active","sdpMid":"sdparta_0","sdpMLineIndex":0}

However, if Firefox receives passive ICE TCP candidates from the other side it will try to connect to them via a TCP connection from Firefox towards the other side.

The typical scenario here is that in environments where UDP is blocked completely, Firefox up to version 53 could only establish connections via the help of a TURN relay which supports TCP. Starting with Firefox 54, if the other side is a media server, conference bridge or in general some server running on a publicly route-able address it can provide passive ICE TCP candidates to Firefox and thus allow direct TCP connections between Firefox and the server, omitting the extra hop over the TURN server.

Where it won’t help

As we don’t support incoming TCP connections, this feature won’t help improve direct connectivity between two WebRTC enabled browsers. Our assumption is that the majority of browsers are running in environments (behind NATs) where they are unable to receive incoming connections. Even with support for passive ICE TCP, direct connectivity between browsers would not improve.



Picture By Kim Hansen (Own work (Own photo)) [GFDL (http://www.gnu.org/copyleft/fdl.html) or CC BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0)], via Wikimedia Commons