estun - Erlang STUN Client¶
estun is a modern Erlang/OTP 28+ STUN client library for NAT traversal and UDP hole punching.
Features¶
- RFC 5389 - Modern STUN protocol support
- RFC 5780 - NAT behavior discovery
- RFC 5769 - Test vectors verified
- RFC 3489 - Classic STUN compatibility
- OTP 28+ - Uses modern
socketmodule - UDP Hole Punching - P2P connection establishment
- gen_statem - Robust state machine implementation
Quick Example¶
%% Start the application
application:ensure_all_started(estun).
%% Add a STUN server
{ok, _} = estun:add_server(#{
host => "stun.l.google.com",
port => 19302
}).
%% Discover your public IP address
{ok, #stun_addr{address = IP, port = Port}} = estun:discover().
io:format("Public address: ~p:~p~n", [IP, Port]).
Use Cases¶
NAT Traversal¶
Discover your public IP address and port as seen from the internet, essential for:
- VoIP applications
- Video conferencing
- Online gaming
- IoT device connectivity
P2P Connections¶
Establish direct peer-to-peer connections through NAT using hole punching:
%% Open a socket and discover public address
{ok, SocketRef} = estun:open_socket().
{ok, MyAddr} = estun:bind_socket(SocketRef, default).
%% Exchange MyAddr with peer via signaling server
%% Then punch through to peer
{ok, connected} = estun:punch(SocketRef, PeerIP, PeerPort).
NAT Type Detection¶
Determine NAT behavior for connectivity planning:
{ok, Behavior} = estun:discover_nat(ServerId).
case Behavior#nat_behavior.mapping_behavior of
endpoint_independent ->
io:format("Easy NAT - hole punching will work~n");
address_port_dependent ->
io:format("Symmetric NAT - may need TURN relay~n")
end.
Examples¶
Simple P2P¶
%% Open socket and discover public address
{ok, SocketRef} = estun:open_socket().
{ok, MyAddr} = estun:bind_socket(SocketRef, default).
%% Connect to peer (after exchanging addresses)
{ok, connected} = estun:punch(SocketRef, PeerIP, PeerPort).
%% Use socket directly
{ok, Socket, _} = estun:transfer_socket(SocketRef).
socket:sendto(Socket, <<"Hello!">>, #{family => inet, addr => PeerIP, port => PeerPort}).
Full example: examples/simple_p2p/
Docker P2P (Cross-Subnet)¶
Test P2P across isolated networks:
Full example: examples/docker_p2p/
Requirements¶
- Erlang/OTP 28 or later
- No external dependencies (pure Erlang)
- Docker (for docker_p2p example)
License¶
MIT License