mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-22 22:31:33 +00:00
feat(quic): implement hole punching
Implement `Transport::dial_as_listener` for QUIC as specified by the [DCUtR spec](https://github.com/libp2p/specs/blob/master/relay/DCUtR.md). To facilitate hole punching in QUIC, one side needs to send random UDP packets to establish a mapping in the routing table of the NAT device. If successful, our listener will emit a new inbound connection. This connection needs to then be sent to the dialing task. We achieve this by storing a `HashMap` of hole punch attempts indexed by the remote's `SocketAddr`. A matching incoming connection is then sent via a oneshot channel to the dialing task which continues with upgrading the connection. Related #2883. Pull-Request: #3964.
This commit is contained in:
@ -23,13 +23,14 @@
|
||||
use clap::Parser;
|
||||
use futures::{
|
||||
executor::{block_on, ThreadPool},
|
||||
future::FutureExt,
|
||||
future::{Either, FutureExt},
|
||||
stream::StreamExt,
|
||||
};
|
||||
use libp2p::{
|
||||
core::{
|
||||
multiaddr::{Multiaddr, Protocol},
|
||||
transport::{OrTransport, Transport},
|
||||
muxing::StreamMuxerBox,
|
||||
transport::Transport,
|
||||
upgrade,
|
||||
},
|
||||
dcutr,
|
||||
@ -38,9 +39,9 @@ use libp2p::{
|
||||
swarm::{NetworkBehaviour, SwarmBuilder, SwarmEvent},
|
||||
tcp, yamux, PeerId,
|
||||
};
|
||||
use libp2p_quic as quic;
|
||||
use log::info;
|
||||
use std::error::Error;
|
||||
use std::net::Ipv4Addr;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
@ -91,19 +92,26 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
|
||||
let (relay_transport, client) = relay::client::new(local_peer_id);
|
||||
|
||||
let transport = OrTransport::new(
|
||||
relay_transport,
|
||||
block_on(DnsConfig::system(tcp::async_io::Transport::new(
|
||||
tcp::Config::default().port_reuse(true),
|
||||
)))
|
||||
.unwrap(),
|
||||
)
|
||||
.upgrade(upgrade::Version::V1Lazy)
|
||||
.authenticate(
|
||||
noise::Config::new(&local_key).expect("Signing libp2p-noise static DH keypair failed."),
|
||||
)
|
||||
.multiplex(yamux::Config::default())
|
||||
.boxed();
|
||||
let transport = {
|
||||
let relay_tcp_quic_transport = relay_transport
|
||||
.or_transport(tcp::async_io::Transport::new(
|
||||
tcp::Config::default().port_reuse(true),
|
||||
))
|
||||
.upgrade(upgrade::Version::V1)
|
||||
.authenticate(noise::Config::new(&local_key).unwrap())
|
||||
.multiplex(yamux::Config::default())
|
||||
.or_transport(quic::async_std::Transport::new(quic::Config::new(
|
||||
&local_key,
|
||||
)));
|
||||
|
||||
block_on(DnsConfig::system(relay_tcp_quic_transport))
|
||||
.unwrap()
|
||||
.map(|either_output, _| match either_output {
|
||||
Either::Left((peer_id, muxer)) => (peer_id, StreamMuxerBox::new(muxer)),
|
||||
Either::Right((peer_id, muxer)) => (peer_id, StreamMuxerBox::new(muxer)),
|
||||
})
|
||||
.boxed()
|
||||
};
|
||||
|
||||
#[derive(NetworkBehaviour)]
|
||||
#[behaviour(to_swarm = "Event")]
|
||||
@ -164,11 +172,10 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
.build();
|
||||
|
||||
swarm
|
||||
.listen_on(
|
||||
Multiaddr::empty()
|
||||
.with("0.0.0.0".parse::<Ipv4Addr>().unwrap().into())
|
||||
.with(Protocol::Tcp(0)),
|
||||
)
|
||||
.listen_on("/ip4/0.0.0.0/udp/0/quic-v1".parse().unwrap())
|
||||
.unwrap();
|
||||
swarm
|
||||
.listen_on("/ip4/0.0.0.0/tcp/0".parse().unwrap())
|
||||
.unwrap();
|
||||
|
||||
// Wait to listen on all interfaces.
|
||||
|
Reference in New Issue
Block a user