Table of Contents

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

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:

  1. Client sends initial request without credentials
  2. Server responds with 401 (Unauthorized) including realm and nonce
  3. Client computes key: MD5(username:realm:password)
  4. Client resends request with MESSAGE-INTEGRITY attribute
  5. 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