VAST.ICE Library
The VAST.ICE library provides a complete implementation of ICE (Interactive Connectivity Establishment), STUN (Session Traversal Utilities for NAT), and TURN (Traversal Using Relays around NAT) protocols. These protocols enable NAT traversal for WebRTC and other real-time communication applications.
Overview
| Feature | Description |
|---|---|
| TURN Server | Full-featured relay server with allocation management |
| TURN Client | Client-side relay allocation and data relay |
| STUN Binding | Server-reflexive address discovery |
| Transport Protocols | UDP, TCP, TLS, and DTLS support |
| Dual-Stack | IPv4 and IPv6 support |
| Authentication | Long-term credentials mechanism |
Requirements
- .NET: .NET 6.0 or later
- Dependencies: VAST.Common
Protocol Standards
| Protocol | RFC | Description |
|---|---|---|
| STUN | RFC 5389 | Session Traversal Utilities for NAT |
| TURN | RFC 5766 | Traversal Using Relays around NAT |
| ICE | RFC 8445 | Interactive Connectivity Establishment |
TURN Server
The TurnServer class implements a TURN relay server that manages client allocations, relay ports, peer permissions, and data relaying between clients and their peers.
Usage
var parameters = new VAST.ICE.TurnServerParameters
{
PublicIPv4Address = IPAddress.Parse("203.0.113.1"),
UdpServerIPv4EndPoint = new IPEndPoint(IPAddress.Any, 3478),
TcpServerIPv4EndPoint = new IPEndPoint(IPAddress.Any, 3478),
};
// Add user credentials
parameters.UserCredentials.Add("user1", "password1");
parameters.UserCredentials.Add("user2", "password2");
var server = new VAST.ICE.TurnServer(parameters);
server.Start();
Server Parameters
| Parameter | Description |
|---|---|
| PublicIPv4Address | Public IPv4 address for relay allocations |
| PublicIPv6Address | Public IPv6 address for relay allocations |
| UdpServerIPv4EndPoint | UDP listening endpoint (IPv4) |
| UdpServerIPv6EndPoint | UDP listening endpoint (IPv6) |
| TcpServerIPv4EndPoint | TCP listening endpoint (IPv4) |
| TcpServerIPv6EndPoint | TCP listening endpoint (IPv6) |
| TlsServerIPv4EndPoint | TLS listening endpoint (IPv4) |
| TlsServerIPv6EndPoint | TLS listening endpoint (IPv6) |
| AllowDtls | Enable DTLS on UDP endpoint |
| CertificateThumbprint | TLS/DTLS certificate thumbprint |
| UserCredentials | Username/password dictionary |
TLS/DTLS Support
For secure connections, provide a certificate thumbprint:
var parameters = new VAST.ICE.TurnServerParameters
{
PublicIPv4Address = IPAddress.Parse("203.0.113.1"),
// TLS over TCP
TlsServerIPv4EndPoint = new IPEndPoint(IPAddress.Any, 5349),
CertificateThumbprint = "A1B2C3...",
// DTLS over UDP (same port as plain UDP)
UdpServerIPv4EndPoint = new IPEndPoint(IPAddress.Any, 3478),
AllowDtls = true,
};
Default Ports
| Port | Protocol | Description |
|---|---|---|
| 3478 | UDP/TCP/DTLS | Default STUN/TURN port |
| 5349 | TLS | Default STUN/TURN TLS port |
TURN Client
The TurnClient class implements a TURN client that connects to a TURN server, obtains relay allocations, manages peer permissions and channel bindings, and relays data between the client and peers.
Usage
var client = new VAST.ICE.TurnClient();
client.Connected += (sender, e) =>
{
Console.WriteLine($"Relay endpoint: {e.RelayEndPoint}");
// Start sending data to peers
client.Send(peerEndPoint, data);
};
client.Received += (sender, e) =>
{
Console.WriteLine($"Received from {e.PeerEndPoint}");
ProcessData(e.Data);
};
client.Disconnected += (sender, e) =>
{
Console.WriteLine("Disconnected from TURN server");
};
var parameters = new VAST.ICE.TurnClientParameters
{
Username = "user1",
Password = "password1",
ServerEndPoint = new IPProtoEndPoint(
IPAddress.Parse("203.0.113.1"),
3478,
ProtocolType.Udp),
PublicAddress = IPAddress.Parse("192.168.1.100"),
};
client.Connect(parameters);
Client Parameters
| Parameter | Description |
|---|---|
| Username | TURN authentication username |
| Password | TURN authentication password |
| ServerEndPoint | TURN server address, port, and protocol |
| PublicAddress | Local public IP address |
| UseChannelMethod | Use ChannelData method for data relay (default: true) |
| RequestIPv4Relay | Request IPv4 relay address |
| RequestIPv6Relay | Request IPv6 relay address |
| ReserveEvenPort | Request even-numbered port (for RTP) |
| ReserveNextPort | Reserve next consecutive port (for RTCP) |
| ReservationToken | Token to claim a reserved port |
Data Relay Methods
The client supports two methods for relaying data to peers:
| Method | Description |
|---|---|
| ChannelData | More compact format, requires channel binding |
| Send Indication | Uses STUN indication messages |
The ChannelData method is more efficient but requires an additional channel binding step. Set UseChannelMethod to true (default) to use ChannelData, or false to use Send indications.
RTP/RTCP Port Reservation
For RTP/RTCP usage, request even-numbered ports with consecutive port reservation:
var rtpParameters = new VAST.ICE.TurnClientParameters
{
Username = "user1",
Password = "password1",
ServerEndPoint = serverEndPoint,
PublicAddress = localAddress,
ReserveEvenPort = true,
ReserveNextPort = true,
};
rtpClient.Connected += (sender, e) =>
{
Console.WriteLine($"RTP relay: {e.RelayEndPoint}");
Console.WriteLine($"Reservation token: {e.ReservationToken}");
// Use token to claim RTCP port
var rtcpParameters = new VAST.ICE.TurnClientParameters
{
Username = "user1",
Password = "password1",
ServerEndPoint = serverEndPoint,
PublicAddress = localAddress,
ReservationToken = e.ReservationToken,
};
rtcpClient.Connect(rtcpParameters);
};
rtpClient.Connect(rtpParameters);
Dual-Stack Support
Request both IPv4 and IPv6 relay addresses:
var parameters = new VAST.ICE.TurnClientParameters
{
Username = "user1",
Password = "password1",
ServerEndPoint = serverEndPoint,
PublicAddress = localAddress,
RequestIPv4Relay = true,
RequestIPv6Relay = true,
};
client.Connected += (sender, e) =>
{
Console.WriteLine($"IPv4 relay: {e.RelayEndPoint}");
Console.WriteLine($"IPv6 relay: {e.AdditionalRelayEndPoint}");
};
STUN Binding
The client can perform STUN binding requests to discover its server-reflexive address (public IP as seen by the server).
client.Bound += (sender, mappedAddress) =>
{
Console.WriteLine($"Server-reflexive address: {mappedAddress}");
};
client.BindingRequest();
Authentication
The library uses the TURN long-term credential mechanism:
- Client sends initial request without credentials
- Server responds with 401 (Unauthorized) including realm and nonce
- Client computes key: MD5(username:realm:password)
- Client resends request with MESSAGE-INTEGRITY attribute
- Server validates and processes request
The nonce is refreshed periodically. If the server returns 438 (Stale Nonce), the client automatically updates the nonce and retries.
UDP Retransmission
For UDP transport, the client implements automatic retransmission:
| Attempt | Interval |
|---|---|
| 1 | 500ms |
| 2 | 1000ms |
| 3 | 2000ms |
| 4 | 4000ms |
| ... | Doubles each time |
Integration with WebRTC
The TURN server and client are designed to work with the WebRTC library for NAT traversal in peer-to-peer connections:
// WebRTC configuration with TURN server
var config = new VAST.WebRTC.WebRtcServerParameters
{
IceServers = "turn:user1:password1@203.0.113.1:3478",
...
};
Troubleshooting
Common Issues
| Issue | Cause | Solution |
|---|---|---|
| Connection timeout | Firewall blocking | Check firewall rules for TURN ports |
| Authentication failed | Wrong credentials | Verify username/password |
| No relay address | Server at capacity | Increase MaxAllocationsPerServer |
| Permission denied | Peer not permitted | Ensure CreatePermission succeeds |
| Data not relaying | Channel not bound | Wait for ChannelBind success |
Debugging
Enable debug logging to diagnose issues:
VAST.Common.Log.Level = VAST.Common.Log.LogLevel.Debug;
See Also
- Supported Platforms - Platform compatibility matrix
- VAST.Common Library - Core types and interfaces
- VAST.Network Library - Network streaming infrastructure
- VAST.WebRTC Library - WebRTC implementation