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

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();
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()
);
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(); let peer_nat_info = NatInfo {
nat_type: NatType::Cone, public_ips: vec![Ipv4Addr::new(1, 1, 1, 1)], public_ports: vec![8080], 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 {
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,
};
}
});
}
}