udp punch hole in rust

Here's an example code for UDP Hole Punching in Rust:

main.rs
use std::net::{SocketAddr, UdpSocket};

const SERVER_ADDR: &str = "0.0.0.0:4000";
const CLIENT_ADDR: &str = "0.0.0.0:0";

fn main() -> std::io::Result<()> {
    // Create server socket
    let server_socket = UdpSocket::bind(SERVER_ADDR)?;
    server_socket.set_nonblocking(true)?;

    // Create client socket
    let client_socket = UdpSocket::bind(CLIENT_ADDR)?;
    client_socket.set_nonblocking(true)?;

    // Send a message from server to client
    let server_addr = "127.0.0.1:3000";
    let buf = "Hello from server".as_bytes();
    let sent_bytes = server_socket.send_to(buf, server_addr)?;

    // Send a message from client to server
    let client_addr = "127.0.0.1:2000";
    let buf = "Hello from client".as_bytes();
    let sent_bytes = client_socket.send_to(buf, client_addr)?;

    // Attempt to connect both sockets by sending messages to each other
    let mut server_success = false;
    let mut client_success = false;
    let mut buf = [0u8; 1024];

    for i in 0..10 {
        // Send a message from server to client
        let server_addr = "127.0.0.1:2000";
        let buf = format!("ping from server ({})", i).as_bytes();
        let sent_bytes = server_socket.send_to(buf, server_addr)?;

        // Receive a message from client
        if let Ok((bytes_read, client_addr)) = client_socket.recv_from(&mut buf) {
            let msg = std::str::from_utf8(&buf[0..bytes_read])?;
            println!("Received message from client: {}", msg);
            client_success = true;
        }

        // Send a message from client to server
        let client_addr = "127.0.0.1:3000";
        let buf = format!("ping from client ({})", i).as_bytes();
        let sent_bytes = client_socket.send_to(buf, client_addr)?;

        // Receive a message from server
        if let Ok((bytes_read, _server_addr)) = server_socket.recv_from(&mut buf) {
            let msg = std::str::from_utf8(&buf[0..bytes_read])?;
            println!("Received message from server: {}", msg);
            server_success = true;
        }

        if server_success && client_success {
            println!("UDP Hole Punching successful!");
            break;
        }
    }

    Ok(())
}
2194 chars
63 lines

This code binds a server socket to port 4000 and a client socket to a random port (using 0.0.0.0:0). It then sends messages from the server socket to the client socket and from the client socket to the server socket. Finally, it attempts to connect the two sockets by sending messages to each other and checking if messages are received back, indicating that hole punching was successful.

gistlibby LogSnag