194 return "[" +
address +
"]:" + std::to_string(
port);
223 return (
value.size() + 3) & ~3;
322 std::optional<std::vector<uint8_t>>
get_data()
const;
337 static std::optional<StunMessage>
deserialize(
const std::vector<uint8_t>& data);
416 const
std::
string& server,
431 const
std::
string& server,
467 const std::vector<uint8_t>& data);
473 const std::string& realm,
474 const std::string& password);
481 const std::array<uint8_t, STUN_TRANSACTION_ID_SIZE>& transaction_id);
STUN Client for NAT traversal.
StunClient(const StunClient &)=delete
void set_config(const StunClientConfig &config)
Set configuration.
StunClient(const StunClientConfig &config)
StunClient(StunClient &&) noexcept
const StunClientConfig & config() const
Get the configuration.
StunClient & operator=(const StunClient &)=delete
std::optional< StunMessage > send_request(socket_t socket, const StunMessage &request, const std::string &server, uint16_t port, int timeout_ms)
Send a raw STUN message and wait for response.
StunResult binding_request_with_socket(socket_t socket, const std::string &server, uint16_t port, int timeout_ms=0)
Send STUN Binding Request using existing socket Useful when you need to discover the mapped address f...
StunResult binding_request(const std::string &server, uint16_t port=STUN_DEFAULT_PORT, int timeout_ms=0)
Send STUN Binding Request to discover public address.
constexpr size_t STUN_HEADER_SIZE
STUN header size in bytes.
constexpr int STUN_MAX_RETRANSMISSIONS
Maximum retransmissions.
StunMethod
STUN method (12 bits, only Binding is defined in RFC 5389)
constexpr size_t STUN_MAX_MESSAGE_SIZE
Maximum STUN message size (RFC 5389 recommends path MTU, typically ~1500)
constexpr uint32_t STUN_MAGIC_COOKIE
STUN Magic Cookie (fixed value per RFC 5389)
constexpr int STUN_DEFAULT_RTO_MS
Default retransmission timeout (ms)
std::vector< std::pair< std::string, uint16_t > > get_public_stun_servers()
Get a list of well-known public STUN servers.
StunMessageType
Combined STUN message type (method + class)
@ ChannelBindSuccessResponse
@ AllocateSuccessResponse
@ CreatePermissionRequest
@ CreatePermissionSuccessResponse
@ CreatePermissionErrorResponse
@ ChannelBindErrorResponse
constexpr size_t STUN_TRANSACTION_ID_SIZE
STUN transaction ID size in bytes.
uint32_t stun_crc32(const uint8_t *data, size_t length)
Compute CRC32 for STUN FINGERPRINT attribute Uses CRC-32 as defined in RFC 5389 (ISO 3309)
std::vector< uint8_t > stun_compute_long_term_key(const std::string &username, const std::string &realm, const std::string &password)
Compute long-term credential key: MD5(username:realm:password)
StunMappedAddress stun_xor_address(const StunMappedAddress &addr, const std::array< uint8_t, STUN_TRANSACTION_ID_SIZE > &transaction_id)
XOR an address with the magic cookie and transaction ID Used for XOR-MAPPED-ADDRESS encoding/decoding...
std::array< uint8_t, 20 > stun_hmac_sha1(const std::vector< uint8_t > &key, const std::vector< uint8_t > &data)
Compute HMAC-SHA1 for MESSAGE-INTEGRITY attribute.
@ UnsupportedTransportProtocol
constexpr uint16_t STUNS_DEFAULT_PORT
STUN over TLS default port.
constexpr uint16_t STUN_DEFAULT_PORT
Default STUN port.
StunMessageClass
STUN message class (2 bits)
STUN attribute base class.
std::vector< uint8_t > value
size_t padded_length() const
StunAttribute(StunAttributeType t, const std::vector< uint8_t > &v)
STUN client configuration.
StunClientConfig()=default
StunError(StunErrorCode c, const std::string &r="")
STUN mapped address (result of binding request)
StunMappedAddress(StunAddressFamily f, const std::string &addr, uint16_t p)
std::string to_string() const
static bool is_stun_message(const std::vector< uint8_t > &data)
Check if data looks like a STUN message.
std::optional< StunMappedAddress > get_xor_peer_address() const
Parse XOR-PEER-ADDRESS from attributes (TURN)
void add_xor_peer_address(const StunMappedAddress &addr)
Add XOR-PEER-ADDRESS attribute (TURN)
static std::optional< StunMessage > deserialize(const std::vector< uint8_t > &data)
Deserialize message from bytes.
void add_error_code(StunErrorCode code, const std::string &reason="")
Add ERROR-CODE attribute.
void add_channel_number(uint16_t channel)
Add CHANNEL-NUMBER attribute (TURN)
std::vector< StunAttribute > attributes
void add_lifetime(uint32_t seconds)
Add LIFETIME attribute (TURN)
std::optional< std::string > get_realm() const
Parse REALM from attributes.
void add_realm(const std::string &realm)
Add REALM attribute.
void add_attribute(StunAttributeType attr_type, const std::vector< uint8_t > &value)
Add an attribute.
void add_xor_relayed_address(const StunMappedAddress &addr)
Add XOR-RELAYED-ADDRESS attribute (TURN)
void add_requested_transport(uint8_t protocol)
Add REQUESTED-TRANSPORT attribute (TURN)
bool is_error_response() const
Check if this is an error response.
std::optional< std::vector< uint8_t > > get_data() const
Parse DATA from attributes (TURN)
std::optional< uint32_t > get_lifetime() const
Parse LIFETIME from attributes (TURN)
void add_data(const std::vector< uint8_t > &data)
Add DATA attribute (TURN)
std::optional< StunError > get_error() const
Parse ERROR-CODE from attributes.
StunMethod get_method() const
Get method from type.
std::array< uint8_t, STUN_TRANSACTION_ID_SIZE > transaction_id
void add_nonce(const std::string &nonce)
Add NONCE attribute.
void add_xor_mapped_address(const StunMappedAddress &addr)
Add XOR-MAPPED-ADDRESS attribute.
const StunAttribute * find_attribute(StunAttributeType attr_type) const
Find attribute by type.
StunMessageClass get_class() const
Get message class from type.
std::optional< StunMappedAddress > get_mapped_address() const
Parse MAPPED-ADDRESS from attributes (legacy)
std::vector< uint8_t > serialize() const
Serialize message to bytes.
void generate_transaction_id()
Generate random transaction ID.
std::optional< std::string > get_nonce() const
Parse NONCE from attributes.
StunMessage(StunMessageType t)
void add_username(const std::string &username)
Add USERNAME attribute.
std::optional< StunMappedAddress > get_xor_mapped_address() const
Parse XOR-MAPPED-ADDRESS from attributes.
std::optional< StunMappedAddress > get_xor_relayed_address() const
Parse XOR-RELAYED-ADDRESS from attributes (TURN)
std::vector< uint8_t > serialize_with_integrity(const std::string &key) const
Serialize message with MESSAGE-INTEGRITY and FINGERPRINT.
bool is_request() const
Check if this is a request.
void add_software(const std::string &software)
Add SOFTWARE attribute.
bool is_success_response() const
Check if this is a success response.
std::optional< StunError > error
std::optional< StunMappedAddress > mapped_address