pub struct Config { /* private fields */ }
Expand description
The configuration for a TCP/IP transport capability for libp2p.
Implementations§
source§impl Config
impl Config
sourcepub fn new() -> Config
pub fn new() -> Config
Creates a new configuration for a TCP/IP transport:
- Nagle’s algorithm, i.e.
TCP_NODELAY
, is enabled. SeeConfig::nodelay
. - Reuse of listening ports is disabled.
See
Config::port_reuse
. - No custom
IP_TTL
is set. The default of the OS TCP stack applies. SeeConfig::ttl
. - The size of the listen backlog for new listening sockets is
1024
. SeeConfig::listen_backlog
.
sourcepub fn listen_backlog(self, backlog: u32) -> Config
pub fn listen_backlog(self, backlog: u32) -> Config
Configures the listen backlog for new listen sockets.
sourcepub fn port_reuse(self, port_reuse: bool) -> Config
pub fn port_reuse(self, port_reuse: bool) -> Config
Configures port reuse for local sockets, which implies reuse of listening ports for outgoing connections to enhance NAT traversal capabilities.
Please refer to e.g. RFC 4787 section 4 and 5 for some of the NAT terminology used here.
There are two main use-cases for port reuse among local sockets:
-
Creating multiple listening sockets for the same address and port to allow accepting connections on multiple threads without having to synchronise access to a single listen socket.
-
Creating outgoing connections whose local socket is bound to the same address and port as a listening socket. In the rare case of simple NATs with both endpoint-independent mapping and endpoint-independent filtering, this can on its own already permit NAT traversal by other nodes sharing the observed external address of the local node. For the common case of NATs with address-dependent or address and port-dependent filtering, port reuse for outgoing connections can facilitate further TCP hole punching techniques for NATs that perform endpoint-independent mapping. Port reuse cannot facilitate NAT traversal in the presence of “symmetric” NATs that employ both address/port-dependent mapping and filtering, unless there is some means of port prediction.
Both use-cases are enabled when port reuse is enabled, with port reuse
for outgoing connections (2.
above) always being implied.
Note: Due to the identification of a TCP socket by a 4-tuple of source IP address, source port, destination IP address and destination port, with port reuse enabled there can be only a single outgoing connection to a particular address and port of a peer per local listening socket address.
Transport
keeps track of the listen socket addresses as they
are reported by polling it. It is possible to listen on multiple
addresses, enabling port reuse for each, knowing exactly which listen
address is reused when dialing with a specific Transport
, as in the
following example:
#[cfg(feature = "async-io")]
#[async_std::main]
async fn main() -> std::io::Result<()> {
let listen_addr1: Multiaddr = "/ip4/127.0.0.1/tcp/9001".parse().unwrap();
let listen_addr2: Multiaddr = "/ip4/127.0.0.1/tcp/9002".parse().unwrap();
let mut tcp1 = libp2p_tcp::async_io::Transport::new(libp2p_tcp::Config::new().port_reuse(true)).boxed();
tcp1.listen_on( listen_addr1.clone()).expect("listener");
match tcp1.select_next_some().await {
TransportEvent::NewAddress { listen_addr, .. } => {
println!("Listening on {:?}", listen_addr);
let mut stream = tcp1.dial(listen_addr2.clone()).unwrap().await?;
// `stream` has `listen_addr1` as its local socket address.
}
_ => {}
}
let mut tcp2 = libp2p_tcp::async_io::Transport::new(libp2p_tcp::Config::new().port_reuse(true)).boxed();
tcp2.listen_on( listen_addr2).expect("listener");
match tcp2.select_next_some().await {
TransportEvent::NewAddress { listen_addr, .. } => {
println!("Listening on {:?}", listen_addr);
let mut socket = tcp2.dial(listen_addr1).unwrap().await?;
// `stream` has `listen_addr2` as its local socket address.
}
_ => {}
}
Ok(())
}
If a wildcard listen socket address is used to listen on any interface,
there can be multiple such addresses registered for port reuse. In this
case, one is chosen whose IP protocol version and loopback status is the
same as that of the remote address. Consequently, for maximum control of
the local listening addresses and ports that are used for outgoing
connections, a new Transport
should be created for each listening
socket, avoiding the use of wildcard addresses which bind a socket to
all network interfaces.
When this option is enabled on a unix system, the socket
option SO_REUSEPORT
is set, if available, to permit
reuse of listening ports for multiple sockets.