rust-p2p-core

Crates.iorust-p2p-core
lib.rsrust-p2p-core
version0.1.12
sourcesrc
created_at2024-09-12 01:17:18.630926
updated_at2024-12-05 03:04:48.668992
descriptionSimple, fast and easy Nat traversal for peer-to-peer
homepage
repositoryhttps://github.com/rustp2p/rustp2p
max_upload_size
id1372396
size244,269
(xmh0511)

documentation

README

rust-p2p

NAT traversal for p2p communication, this is implemented in terms of a hole-punching technique.

Crates.io rust-p2p-core

This crate provides a convenient way to create a pipe between multiple remote peers that may be behind Nats, these pipelines that are spawned from the pipe can be used to read/write bytes from/to a peer to another.

The underlying transport protocols are TCP, UDP in the pipelines, users can even extend the protocol for the pipeline by using the powerful trait.

This crate is built on the async ecosystem tokio

Supported Platforms

It's a cross-platform crate

Usage

Add this dependency to your cargo.toml

rust-p2p-core = {version = "0.1"}

Example


#[tokio::main]
async fn main() {
    let udp_config = UdpPipeConfig::default();
    let tcp_config = TcpPipeConfig::default();
    let config = PipeConfig::empty()
        .set_udp_pipe_config(udp_config)
        .set_tcp_pipe_config(tcp_config)
        .set_main_pipeline_num(2);
    let (mut pipe, puncher, idle_route_manager) = pipe(config).unwrap();
    // Handle the idle route
    tokio::spawn(async move {
        loop {
            let (peer_id, route, time) = idle_route_manager.next_idle().await;
            log::info!(
                "route timeout peer_id={peer_id},route={route:?},time={:?}",
                time.elapsed()
            );
            // delete the mapping associated with the route and peer_id
            idle_route_manager.remove_route(&peer_id, &route.route_key());
        }
    });
    let pipe_writer = pipe.writer_ref().to_owned();
    let peer_id = "peer_id".to_owned(); // The remote peer is said to be named "peer_id"
                                        // The Nat information of the peer for which we prepare to punch the hole between local and it
    let peer_nat_info = NatInfo {
        nat_type: NatType::Cone,                     //Nat type
        public_ips: vec![Ipv4Addr::new(1, 1, 1, 1)], // The public IP mapped by Nat
        public_ports: vec![8080],                    // The public port mapped by Nat
        mapping_tcp_addr: vec![],
        mapping_udp_addr: vec![],
        public_port_range: 0,
        local_ipv4: Ipv4Addr::new(1, 1, 1, 1),
        ipv6: None,
        local_udp_ports: vec![0],
        local_tcp_port: 0,
        public_tcp_port: 0,
    };
    tokio::spawn(async move {
        // We may need to keep calling this method until the peer receives "hello"
        let rs = puncher
            .punch(
                peer_id,
                b"hello",
                PunchInfo::new(PunchModelBoxes::all(), peer_nat_info),
            )
            .await;
    });
    loop {
        let pipe_line = pipe.accept().await.unwrap();
        let pipe_writer_ = pipe_writer.clone();
        tokio::spawn(async move {
            let mut buf = [0; 65536];
            loop {
                let (len, route_key) = match pipe_line.recv_from(&mut buf).await {
                    Ok(rs) => rs,
                    Err(e) => break,
                };
                // route_key denotes the source from which the buf is sent from in the pipeline
                // pipe_writer_.send_to(b"hello", &route_key).await.unwrap();
            }
        });
    }
}

Commit count: 262

cargo fmt