What is STUN?
TL;DR: STUN is a “What is my IP?” service
WebRTC lets web applications talk to each other directly, peer-to-peer, with no intermediate server. The technology enabling this is called STUN. But what is STUN? What does it do? How does it work?
First let’s look at the browser’s traditional role. The browser is traditionally an HTTP client which connects to HTTP servers. These HTTP servers have known addresses. For example, I can ask a google.com web server to serve me the Google homepage:
% nc google.com 80 GET / HTTP/1.0 302 Found ...
We can use this traditional client-server architecture to build a chat server. Let’s say Bob wants to talk to Alice, so they use a web app which they both know is at
https://chat.com. The goal is that everyone who loads
https://chat.com in their browser can chat to everyone else who loads
https://chat.com. We would solve this by using the
chat.com server as a centralized pub/sub service. This means each client would have a TCP connection to the
chat.com server, and when the server receives a message on a connection, it would then copy the message to every other connection.
This client-server architecture works because the servers have publicly known addresses with known TCP ports. All of the connections in the traditional architecture are made from a client to the server, and this works because the clients know how to find the
Now let’s imagine we want to move this to a P2P architecture, so clients send their messages directly to each other. A client opening a connection to another client is more tricky, because neither client has a publicly known address or port for the other client to connect to.
But there’s a simple way to discover a client’s address: the server knows it! When a client opens a connection to the server, the client advertises its IP address. So the server could broadcast this IP address to all other clients. Then the clients could open a connection to it.
This is roughly how Session Traversal Utilities for NAT works.
But it doesn’t quite work that way. First, the clients discover their public address by connecting to a STUN server, and getting a response detailing the public return address of the request. It’s essentially a “What is my IP?” service! Then the client sends its STUN-discovered address to other services, such as the
chat.com server, which can broadcast the address to other clients. An example public STUN server runs at
stun.l.google.com, which anyone can use.
Second, STUN usually works over UDP. The
stun.l.google.com server works on UDP port
19302. This is unusual; the standard STUN port is
We can see our public UDP port with a tool called “Stuntman”:
% brew install stuntman % stunclient --verbosity 10 stun.l.google.com 19302 Resolved stun.l.google.com to 126.96.36.199:0 config.fBehaviorTest = false config.fFilteringTest = false config.timeoutSeconds = 0 config.uMaxAttempts = 0 config.addrServer = 188.8.131.52:19302 socketconfig.addrLocal = 0.0.0.0:0 Sending message to 184.108.40.206:19302 Got response (32 bytes) from 220.127.116.11:19302 on interface 192.168.1.2:53417 Binding test: success Local address: 192.168.1.2:53417 Mapped address: 18.104.22.168:53417
I wrote this because I felt like it. This post is not associated with my employer. This site is hosted by Netlify (who are great, but I'm not associated with them either).