3 unstable releases

0.2.1 Jul 12, 2024
0.2.0 Jul 8, 2024
0.1.1 Jun 7, 2024

#1756 in Network programming

Download history 54/week @ 2024-06-01 104/week @ 2024-06-08 3/week @ 2024-06-15 222/week @ 2024-07-06 39/week @ 2024-07-13 16/week @ 2024-07-20 25/week @ 2024-07-27

144 downloads per month
Used in gday

MIT license

58KB
811 lines

Note: this crate is still in early-development, so expect breaking changes.

gday_hole_punch

Crates.io Version docs.rs

Lets peers behind NAT (network address translation) try to establish a direct authenticated TCP connection. Uses TCP hole punching and a helper gday_server to do this.

See the documentation.

Used by

  • gday - Command line tool for sending files.

Depends on


lib.rs:

Note: this crate is still in early-development, so expect breaking changes.

Lets 2 peers behind NAT (network address translation) try to establish a direct authenticated TCP connection. Uses TCP hole punching and a helper gday_server to do this. This library is used by gday, a command line tool for sending files.

Example

#
let servers = server_connector::DEFAULT_SERVERS;
let timeout = std::time::Duration::from_secs(5);
let room_code = 123;
let shared_secret = 456;

//////// Peer 1 ////////

// Connect to a random server in the default server list
let (mut server_connection, server_id) = server_connector::connect_to_random_server(
    servers,
    timeout
)?;

// PeerCode useful for giving rendezvous info to peer
let peer_code = PeerCode { server_id, room_code, shared_secret };
let code_to_share = peer_code.to_string();

// Create a room in the server, and get my contact from it
let (contact_sharer, my_contact) = ContactSharer::create_room(
    &mut server_connection,
    room_code
)?;

// Wait for the server to send the peer's contact
let peer_contact = contact_sharer.get_peer_contact()?;

// Use TCP hole-punching to connect to the peer,
// verify their identity with the shared_secret,
// and get a cryptographically-secure shared key
let (tcp_stream, strong_key) = try_connect_to_peer(
    my_contact.local,
    peer_contact,
    &shared_secret.to_be_bytes(),
    timeout
)?;

//////// Peer 2 (on a different computer) ////////

let peer_code = PeerCode::from_str(&code_to_share)?;

// Connect to the same server as Peer 1
let mut server_connection = server_connector::connect_to_server_id(
    servers,
    peer_code.server_id,
    timeout
)?;

// Join the same room in the server, and get my local contact
let (contact_sharer, my_contact) = ContactSharer::join_room(
    &mut server_connection,
    peer_code.room_code
)?;

let peer_contact = contact_sharer.get_peer_contact()?;

let (tcp_stream, strong_key) = try_connect_to_peer(
    my_contact.local,
    peer_contact,
    &peer_code.shared_secret.to_be_bytes(),
    timeout
)?;

Dependencies

~14–25MB
~460K SLoC