### Synchronous STUN Client Query Source: https://github.com/vi/rust-stunclient/blob/master/README.md Use this synchronous example when you need to resolve your external IP address in a blocking context. Ensure the `stunclient` crate is added as a dependency. ```rust use std::net::UdpSocket; use stunclient::StunClient; use std::net::{SocketAddr,ToSocketAddrs}; let local_addr : SocketAddr = "0.0.0.0:0".parse().unwrap(); let stun_addr = "stun.l.google.com:19302".to_socket_addrs().unwrap().filter(|x|x.is_ipv4()).next().unwrap(); let udp = UdpSocket::bind(local_addr).unwrap(); let c = StunClient::new(stun_addr); let my_external_addr = c.query_external_address(&udp).unwrap(); ``` -------------------------------- ### Asynchronous STUN Client Query Source: https://github.com/vi/rust-stunclient/blob/master/README.md This asynchronous example is suitable for non-blocking I/O operations within an async runtime like Tokio. It requires the `tokio` runtime and the `stunclient` crate. ```rust use stunclient::StunClient; use std::net::{SocketAddr,ToSocketAddrs}; let local_addr : SocketAddr = "0.0.0.0:0".parse().unwrap(); let stun_addr = "stun.l.google.com:19302".to_socket_addrs().unwrap().filter(|x|x.is_ipv4()).next().unwrap(); let udp = tokio::net::udp::UdpSocket::bind(&local_addr).unwrap(); let c = StunClient::new(stun_addr); let f = c.query_external_address_async(&udp); let my_external_addr = f.await.unwrap(); ``` -------------------------------- ### Synchronous STUN Query with Error Handling Source: https://context7.com/vi/rust-stunclient/llms.txt Demonstrates a synchronous STUN query and how to handle potential errors using the library's comprehensive Error enum. This example shows accessing both the human-readable error message and the underlying cause. ```rust use std::net::{SocketAddr, ToSocketAddrs, UdpSocket}; use stunclient::{StunClient, Error}; fn main() { let stun_addr: SocketAddr = "stun.l.google.com:19302" .to_socket_addrs() .unwrap() .filter(|x| x.is_ipv4()) .next() .unwrap(); let udp = UdpSocket::bind("0.0.0.0:0").unwrap(); let client = StunClient::new(stun_addr); let result = client.query_external_address(&udp); // Handle specific error types match result { Ok(addr) => println!("Success: {}", addr), Err(ref e) => { // Display trait provides human-readable messages eprintln!("Error: {}", e); // std::error::Error trait allows accessing underlying cause if let Some(source) = std::error::Error::source(e) { eprintln!("Caused by: {}", source); } } } } ``` -------------------------------- ### Query External Address Asynchronously with Tokio Source: https://context7.com/vi/rust-stunclient/llms.txt Demonstrates the asynchronous version of querying an external address using Tokio. Ensure the 'async' feature is enabled (default). This example uses Tokio's select for concurrent timeout and retry handling. ```rust use std::net::SocketAddr; use stunclient::StunClient; #[tokio::main(flavor = "current_thread")] async fn main() -> Result<(), Box> { // Bind async UDP socket let local_addr: SocketAddr = "0.0.0.0:0".parse()?; let udp = tokio::net::UdpSocket::bind(&local_addr).await?; println!("Local address: {}", udp.local_addr()?); // Create STUN client (with_google_stun_server does blocking DNS resolution) let client = StunClient::with_google_stun_server(); // Query external address asynchronously match client.query_external_address_async(&udp).await { Ok(external_addr) => { println!("External address: {}", external_addr); } Err(e) => { eprintln!("Async STUN query failed: {}", e); } } Ok(()) } ``` -------------------------------- ### Configure STUN Client with Builder Pattern Source: https://context7.com/vi/rust-stunclient/llms.txt Demonstrates configuring a STUN client using builder methods to customize timeout, retry interval, and the software identifier. The software attribute can also be disabled. ```rust use std::net::{SocketAddr, ToSocketAddrs}; use std::time::Duration; use stunclient::StunClient; fn main() { let stun_addr: SocketAddr = "stun.l.google.com:19302" .to_socket_addrs() .unwrap() .filter(|x| x.is_ipv4()) .next() .unwrap(); // Create and configure client with builder pattern let mut client = StunClient::new(stun_addr); client .set_timeout(Duration::from_secs(5)) // 5 second timeout .set_retry_interval(Duration::from_millis(500)) // Retry every 500ms .set_software(Some("MyApp/1.0")); // Custom software identifier // Or disable software attribute entirely let mut minimal_client = StunClient::new(stun_addr); minimal_client.set_software(None); } ``` -------------------------------- ### Create STUN Client with Defaults Source: https://context7.com/vi/rust-stunclient/llms.txt Initializes a new STUN client with default parameters, targeting a specified STUN server address. Default settings include a 10-second timeout, 1-second retry interval, and a default software identifier. ```rust use std::net::{SocketAddr, ToSocketAddrs}; use stunclient::StunClient; fn main() { // Resolve STUN server address (using Google's public STUN server) let stun_addr: SocketAddr = "stun.l.google.com:19302" .to_socket_addrs() .expect("Failed to resolve STUN server") .filter(|x| x.is_ipv4()) .next() .expect("No IPv4 address found"); // Create client with default settings let client = StunClient::new(stun_addr); // Client is now ready to query external addresses // Default timeout: 10 seconds // Default retry_interval: 1 second // Default software: "SimpleRustStunClient" } ``` -------------------------------- ### Create STUN Client with Google STUN Server Source: https://context7.com/vi/rust-stunclient/llms.txt A convenience constructor for quickly setting up a STUN client preconfigured to use Google's public STUN server. This is useful for testing and prototyping but may block on DNS resolution. ```rust use stunclient::StunClient; fn main() { // Quick setup using Google's public STUN server // Note: May block during DNS resolution, not recommended for production let client = StunClient::with_google_stun_server(); // Ready to use immediately let udp = std::net::UdpSocket::bind("0.0.0.0:0").unwrap(); match client.query_external_address(&udp) { Ok(external_addr) => println!("External address: {}", external_addr), Err(e) => eprintln!("Error: {}", e), } } ``` -------------------------------- ### StunClient::with_google_stun_server Source: https://context7.com/vi/rust-stunclient/llms.txt Creates a STUN client preconfigured to use Google's public STUN server (`stun.l.google.com:19302`). This is a convenience constructor for testing, prototypes, and demos that automatically resolves the server address. ```APIDOC ## StunClient::with_google_stun_server ### Description Creates a STUN client preconfigured to use Google's public STUN server (`stun.l.google.com:19302`). This is a convenience constructor for testing, prototypes, and demos that automatically resolves the server address. ### Method Associated function (constructor) ### Endpoint N/A (Library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use stunclient::StunClient; fn main() { // Quick setup using Google's public STUN server // Note: May block during DNS resolution, not recommended for production let client = StunClient::with_google_stun_server(); // Ready to use immediately let udp = std::net::UdpSocket::bind("0.0.0.0:0").unwrap(); match client.query_external_address(&udp) { Ok(external_addr) => println!("External address: {}", external_addr), Err(e) => eprintln!("Error: {}", e), } } ``` ### Response N/A (Constructor returns a client instance) ### Response Example N/A ``` -------------------------------- ### StunClient::new Source: https://context7.com/vi/rust-stunclient/llms.txt Creates a new STUN client instance with default parameters targeting a specified STUN server address. Default configuration includes a 10-second timeout, 1-second retry interval, and "SimpleRustStunClient" as the software identifier. ```APIDOC ## StunClient::new ### Description Creates a new STUN client instance with default parameters targeting a specified STUN server address. Default configuration includes a 10-second timeout, 1-second retry interval, and "SimpleRustStunClient" as the software identifier. ### Method Associated function (constructor) ### Endpoint N/A (Library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use std::net::{SocketAddr, ToSocketAddrs}; use stunclient::StunClient; fn main() { // Resolve STUN server address (using Google's public STUN server) let stun_addr: SocketAddr = "stun.l.google.com:19302" .to_socket_addrs() .expect("Failed to resolve STUN server") .filter(|x| x.is_ipv4()) .next() .expect("No IPv4 address found"); // Create client with default settings let client = StunClient::new(stun_addr); // Client is now ready to query external addresses // Default timeout: 10 seconds // Default retry_interval: 1 second // Default software: "SimpleRustStunClient" } ``` ### Response N/A (Constructor returns a client instance) ### Response Example N/A ``` -------------------------------- ### Cargo.toml Configuration Source: https://context7.com/vi/rust-stunclient/llms.txt Illustrates how to add the `stunclient` crate to your project's `Cargo.toml` file, including options for enabling or disabling the `async` feature and adding `tokio` for asynchronous operations. ```APIDOC ## Cargo.toml Configuration ### Description Configuration options for adding the `stunclient` crate to your Rust project's `Cargo.toml` file. Shows how to manage features, particularly the `async` feature for Tokio support. ### Method N/A (Configuration file) ### Endpoint N/A ### Parameters None ### Request Example ```toml [dependencies] # With async support (default) stunclient = "0.4" # Without async support (sync only, smaller dependency footprint) stunclient = { version = "0.4", default-features = false } # Explicitly enable async stunclient = { version = "0.4", features = ["async"] } # For async usage, also add tokio tokio = { version = "1", features = ["rt", "net", "macros"] } ``` ### Response N/A ``` -------------------------------- ### StunClient Builder Methods Source: https://context7.com/vi/rust-stunclient/llms.txt Configure the STUN client using builder-pattern methods: `set_timeout` for overall operation timeout, `set_retry_interval` for request retry frequency, and `set_software` for the SOFTWARE attribute in binding requests. ```APIDOC ## StunClient Builder Methods ### Description Configure the STUN client using builder-pattern methods: `set_timeout` for overall operation timeout, `set_retry_interval` for request retry frequency, and `set_software` for the SOFTWARE attribute in binding requests. ### Method Builder pattern methods on `StunClient` instance ### Endpoint N/A (Library functions) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use std::net::{SocketAddr, ToSocketAddrs}; use std::time::Duration; use stunclient::StunClient; fn main() { let stun_addr: SocketAddr = "stun.l.google.com:19302" .to_socket_addrs() .unwrap() .filter(|x| x.is_ipv4()) .next() .unwrap(); // Create and configure client with builder pattern let mut client = StunClient::new(stun_addr); client .set_timeout(Duration::from_secs(5)) // 5 second timeout .set_retry_interval(Duration::from_millis(500)) // Retry every 500ms .set_software(Some("MyApp/1.0")); // Custom software identifier // Or disable software attribute entirely let mut minimal_client = StunClient::new(stun_addr); minimal_client.set_software(None); } ``` ### Response N/A (Methods modify the client instance in place) ### Response Example N/A ``` -------------------------------- ### Cargo.toml Dependency Configuration Source: https://context7.com/vi/rust-stunclient/llms.txt Shows how to add the stunclient library to your Cargo.toml file, including options for enabling or disabling the default 'async' feature and configuring Tokio for asynchronous operations. ```toml [dependencies] # With async support (default) stunclient = "0.4" # Without async support (sync only, smaller dependency footprint) stunclient = { version = "0.4", default-features = false } # Explicitly enable async stunclient = { version = "0.4", features = ["async"] } # For async usage, also add tokio tokio = { version = "1", features = ["rt", "net", "macros"] } ``` -------------------------------- ### Asynchronous External Address Query Source: https://context7.com/vi/rust-stunclient/llms.txt Demonstrates how to query the external IP address asynchronously using Tokio. This method is suitable for non-blocking applications and utilizes Tokio's select for concurrent timeout and retry handling. ```APIDOC ## POST /query_external_address_async ### Description Asynchronously queries the external IP address of the client using a UDP socket and a STUN server. This method requires the `async` feature to be enabled. ### Method POST (Conceptual - Rust function call) ### Endpoint N/A (Rust function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use std::net::SocketAddr; use stunclient::StunClient; #[tokio::main(flavor = "current_thread")] async fn main() -> Result<(), Box> { // Bind async UDP socket let local_addr: SocketAddr = "0.0.0.0:0".parse()?; let udp = tokio::net::UdpSocket::bind(&local_addr).await?; println!("Local address: {}", udp.local_addr()?); // Create STUN client (with_google_stun_server does blocking DNS resolution) let client = StunClient::with_google_stun_server(); // Query external address asynchronously match client.query_external_address_async(&udp).await { Ok(external_addr) => { println!("External address: {}", external_addr); } Err(e) => { eprintln!("Async STUN query failed: {}", e); } } Ok(()) } ``` ### Response #### Success Response (200) - **external_addr** (SocketAddr) - The discovered external IP address and port. #### Response Example ```json { "external_addr": "192.0.2.1:12345" } ``` ``` -------------------------------- ### Synchronous External Address Query and Error Handling Source: https://context7.com/vi/rust-stunclient/llms.txt Shows a synchronous method for querying the external IP address and demonstrates how to handle potential errors using the library's `Error` enum. ```APIDOC ## POST /query_external_address ### Description Synchronously queries the external IP address of the client using a UDP socket and a STUN server. Includes comprehensive error handling for various failure modes. ### Method POST (Conceptual - Rust function call) ### Endpoint N/A (Rust function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use std::net::{SocketAddr, ToSocketAddrs, UdpSocket}; use stunclient::{StunClient, Error}; fn main() { let stun_addr: SocketAddr = "stun.l.google.com:19302" .to_socket_addrs() .unwrap() .filter(|x| x.is_ipv4()) .next() .unwrap(); let udp = UdpSocket::bind("0.0.0.0:0").unwrap(); let client = StunClient::new(stun_addr); let result = client.query_external_address(&udp); // Handle specific error types match result { Ok(addr) => println!("Success: {}", addr), Err(ref e) => { // Display trait provides human-readable messages eprintln!("Error: {}", e); // std::error::Error trait allows accessing underlying cause if let Some(source) = std::error::Error::source(e) { eprintln!("Caused by: {}", source); } } } } ``` ### Response #### Success Response (200) - **addr** (SocketAddr) - The discovered external IP address and port. #### Response Example ```json { "addr": "192.0.2.1:12345" } ``` ### Error Handling The library provides a comprehensive `Error` enum covering all failure modes: encoding/decoding errors, broken STUN messages, missing address attributes, socket errors, and timeouts. ``` -------------------------------- ### Query External Address (Synchronous) Source: https://context7.com/vi/rust-stunclient/llms.txt Performs a synchronous query to a STUN server to discover the external IP address and port of a UDP socket. This method blocks until a response is received or a timeout occurs, with automatic retries. ```rust use std::net::{SocketAddr, ToSocketAddrs, UdpSocket}; use stunclient::StunClient; fn main() -> Result<(), Box> { // Setup STUN server address let stun_addr: SocketAddr = "stun.l.google.com:19302" .to_socket_addrs()? .filter(|x| x.is_ipv4()) .next() .ok_or("No IPv4 address")?; // Bind UDP socket to any available port let local_addr: SocketAddr = "0.0.0.0:0".parse()?; let udp = UdpSocket::bind(local_addr)?; println!("Local address: {}", udp.local_addr()?); // Create STUN client and query external address let client = StunClient::new(stun_addr); match client.query_external_address(&udp) { Ok(external_addr) => { println!("External address: {}", external_addr); // external_addr contains the public IP and port as seen by the STUN server // Example output: 203.0.113.45:54321 } Err(e) => { eprintln!("STUN query failed: {}", e); // Possible errors: // - "Time out while reading socket" // - "UDP socket error" // - "No XorMappedAddress or MappedAddress in STUN reply" } } Ok(()) } ``` -------------------------------- ### query_external_address (Synchronous) Source: https://context7.com/vi/rust-stunclient/llms.txt Queries the STUN server to discover the external (server-reflexive) IP address and port of a UDP socket. This synchronous method blocks until a response is received or timeout occurs, with automatic retries at the configured interval. ```APIDOC ## query_external_address (Synchronous) ### Description Queries the STUN server to discover the external (server-reflexive) IP address and port of a UDP socket. This synchronous method blocks until a response is received or timeout occurs, with automatic retries at the configured interval. ### Method `query_external_address` ### Endpoint N/A (Library function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use std::net::{SocketAddr, ToSocketAddrs, UdpSocket}; use stunclient::StunClient; fn main() -> Result<(), Box> { // Setup STUN server address let stun_addr: SocketAddr = "stun.l.google.com:19302" .to_socket_addrs()? .filter(|x| x.is_ipv4()) .next() .ok_or("No IPv4 address")?; // Bind UDP socket to any available port let local_addr: SocketAddr = "0.0.0.0:0".parse()?; let udp = UdpSocket::bind(local_addr)?; println!("Local address: {}", udp.local_addr()?); // Create STUN client and query external address let client = StunClient::new(stun_addr); match client.query_external_address(&udp) { Ok(external_addr) => { println!("External address: {}", external_addr); // external_addr contains the public IP and port as seen by the STUN server // Example output: 203.0.113.45:54321 } Err(e) => { eprintln!("STUN query failed: {}", e); // Possible errors: // - "Time out while reading socket" // - "UDP socket error" // - "No XorMappedAddress or MappedAddress in STUN reply" } } Ok(()) } ``` ### Response #### Success Response (200) - **external_addr** (SocketAddr) - The discovered external IP address and port. #### Response Example ```json { "external_addr": "203.0.113.45:54321" } ``` ``` -------------------------------- ### Convenience Function for UDP Socket and External Address Source: https://context7.com/vi/rust-stunclient/llms.txt Provides a simplified, synchronous function to obtain both a UDP socket bound to an available port and its corresponding external IP address in a single call. This is intended for quick prototyping and may block or panic on errors. ```APIDOC ## POST /just_give_me_the_udp_socket_and_its_external_address ### Description A convenience function that creates a UDP socket bound to any available port and immediately queries its external address using Google's STUN server. Returns both the socket and its external address in one call. Designed for quick prototyping only. ### Method POST (Conceptual - Rust function call) ### Endpoint N/A (Rust function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```rust use stunclient::just_give_me_the_udp_socket_and_its_external_address; fn main() { // Get both UDP socket and external address in one call // Note: May block and panic on errors - for prototyping only let (udp_socket, external_addr) = just_give_me_the_udp_socket_and_its_external_address(); println!("Local address: {}", udp_socket.local_addr().unwrap()); println!("External address: {}", external_addr); // The socket is ready for peer-to-peer communication // Share external_addr with peers so they can send UDP packets to you } ``` ### Response #### Success Response (200) - **udp_socket** (UdpSocket) - The created UDP socket. - **external_addr** (SocketAddr) - The discovered external IP address and port. #### Response Example ```json { "udp_socket": "", "external_addr": "192.0.2.1:12345" } ``` ``` -------------------------------- ### Convenience Function for UDP Socket and External Address Source: https://context7.com/vi/rust-stunclient/llms.txt A simplified function for quickly obtaining a UDP socket bound to an available port and its corresponding external address. This is intended for rapid prototyping and may panic on errors. ```rust use stunclient::just_give_me_the_udp_socket_and_its_external_address; fn main() { // Get both UDP socket and external address in one call // Note: May block and panic on errors - for prototyping only let (udp_socket, external_addr) = just_give_me_the_udp_socket_and_its_external_address(); println!("Local address: {}", udp_socket.local_addr().unwrap()); println!("External address: {}", external_addr); // The socket is ready for peer-to-peer communication // Share external_addr with peers so they can send UDP packets to you } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.