STUN (Session Traversal Utilities for NAT) is a protocol that assists in establishing peer-to-peer (P2P) connections over the Internet, particularly in scenarios involving Network Address Translators (NATs). NATs are devices that map private IP addresses within a local network to public IP addresses on the Internet. This process is helpful for security but poses challenges for direct P2P connections, as devices in different private networks may not easily reach each other. STUN facilitates the discovery of public IP addresses and port mappings, enabling devices behind NATs to establish P2P connections effectively.
STUN is a fundamental building block in WebRTC (Web Real-Time Communication), a technology for P2P communications such as audio, video, and data transfer between browsers.
How Does STUN Work?
When two devices want to establish a P2P connection, each device needs to know:
- Its own public IP address and port as seen by the Internet.
- Any NAT or firewall restrictions that could prevent direct communication.
A STUN server provides this information by reflecting the device’s request, which is then used to identify the public IP and port mappings assigned by the NAT. This process is commonly referred to as NAT traversal.
The typical flow with STUN works as follows:
- The client contacts a STUN server over the Internet.
- The server replies with the public IP address and port as seen by the Internet.
- The client uses this information in its connection request to another peer.
STUN vs. TURN
STUN works for NAT traversal in most cases. However, when both peers are behind symmetric NATs, STUN alone may not work. TURN (Traversal Using Relays around NAT) servers are used as intermediaries, relaying traffic between peers. TURN is more resource-intensive than STUN and is typically used as a fallback option.
STUN in WebRTC
WebRTC uses STUN to assist in creating peer-to-peer connections by determining the public-facing IP address of a client. This address is shared with other peers via a Session Description Protocol (SDP) message. The SDP contains information about how the peers can connect, including IP addresses, ports, and connection metadata.
Below, we’ll walk through how to set up a simple STUN-backed peer connection using WebRTC and examine the SDP exchange.
Example of a STUN-backed WebRTC Peer Connection
In this example, we’ll configure a WebRTC peer connection between two clients. We’ll demonstrate how STUN servers are configured in the peer connection and look at the SDP details that are exchanged.
Step 1: Setting Up the STUN Server in WebRTC
WebRTC’s RTCPeerConnection
object supports configuring STUN and TURN servers directly. Here’s how to add a STUN server in JavaScript:
const configuration = {
iceServers: [
{ urls: 'stun:stun.l.google.com:19302' } // Google’s public STUN server
]
};
const peerConnection = new RTCPeerConnection(configuration);
In this configuration, we use Google’s public STUN server. This will help each client determine its public IP and port.
Step 2: Generating and Sharing SDP
The process for establishing a connection involves the exchange of SDP (Session Description Protocol) messages. The SDP contains information about how media can be shared between the two peers.
Here’s an example of how to create an offer and generate an SDP on the first client:
peerConnection.createOffer().then((offer) => {
return peerConnection.setLocalDescription(offer);
}).then(() => {
// Send the SDP offer to the other peer via your signaling server
console.log("SDP Offer: ", peerConnection.localDescription);
});
This code:
- Creates an offer.
- Sets the offer as the local description of the peer connection.
- Logs the SDP, which you can send to the other peer through a signaling mechanism (e.g., WebSocket, HTTP).
Here’s what the generated SDP might look like:
v=0
o=- 46117349 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 9
c=IN IP4 203.0.113.1
a=rtcp:9 IN IP4 0.0.0.0
a=candidate:842163049 1 udp 1677729535 192.168.1.2 62604 typ srflx raddr 192.168.1.2 rport 62604 generation 0
a=ice-ufrag:EjYk
a=ice-pwd:asd88fgpdd777uzjYhagZg
a=fingerprint:sha-256 4F:90:41:59:48:1E:E8:A2:37:23:5A:CD:E3:8E:10:F6:A3:6A:C5:99:EB:FD:45:3B:EC:8A:52:1A:C6:97:DF:5E
...
Step 3: Receiving and Setting the SDP
On the receiving peer, set the received SDP as the remote description, then generate an answer to send back.
// Assume sdpOffer is the SDP received from the offerer
peerConnection.setRemoteDescription(new RTCSessionDescription(sdpOffer)).then(() => {
return peerConnection.createAnswer();
}).then((answer) => {
return peerConnection.setLocalDescription(answer);
}).then(() => {
// Send the SDP answer back to the offerer
console.log("SDP Answer: ", peerConnection.localDescription);
});
This sets up the receiving peer to respond to the initial offer with an SDP answer.
Detailed Breakdown of SDP
An SDP message consists of several sections:
- v=0: SDP version.
- o=: Origin of the session.
- s=: Session name.
- c=: Connection data, like the IP address.
- m=: Media information (e.g., audio, video).
- a=: Attributes, including ICE candidates.
The ICE candidates (a=candidate
) specify the IP and port combinations where each peer might be reachable. These candidates are collected with the help of the STUN server.
Example: Adding an ICE Candidate
When additional ICE candidates are discovered, they are sent to the peer to expand connection possibilities.
peerConnection.onicecandidate = (event) => {
if (event.candidate) {
// Send candidate to the peer
console.log("New ICE Candidate:", event.candidate);
}
};
Summary
- STUN allows devices to discover their public IP address and port mappings, enabling peer-to-peer connections across NATs.
- SDP is the format used to describe the media and connection setup required to establish a WebRTC session.
- By configuring STUN servers in
RTCPeerConnection
, WebRTC applications can collect the necessary ICE candidates to complete NAT traversal.
In combination with TURN and signaling servers, STUN is crucial for establishing reliable WebRTC connections across the Internet.