Struct GenTcpConfig

Source
pub struct GenTcpConfig<T> { /* private fields */ }
Expand description

The configuration for a TCP/IP transport capability for libp2p.

A GenTcpConfig implements the Transport interface and thus is consumed on Transport::listen_on and Transport::dial. However, the config can be cheaply cloned to perform multiple such operations with the same config.

Implementations§

Source§

impl<T> GenTcpConfig<T>
where T: Provider + Send,

Source

pub fn new() -> Self

Creates a new configuration for a TCP/IP transport:

Source

pub fn ttl(self, value: u32) -> Self

Configures the IP_TTL option for new sockets.

Source

pub fn nodelay(self, value: bool) -> Self

Configures the TCP_NODELAY option for new sockets.

Source

pub fn listen_backlog(self, backlog: u32) -> Self

Configures the listen backlog for new listen sockets.

Source

pub fn port_reuse(self, port_reuse: bool) -> Self

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:

  1. 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.

  2. 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.

If enabled, the returned GenTcpConfig and all of its Clones keep track of the listen socket addresses as they are reported by polling TcpListenStreams obtained from GenTcpConfig::listen_on().

In contrast, two GenTcpConfigs constructed separately via GenTcpConfig::new() maintain these addresses independently. It is thus possible to listen on multiple addresses, enabling port reuse for each, knowing exactly which listen address is reused when dialing with a specific GenTcpConfig, as in the following example:

#[cfg(feature = "async-io")]
#[async_std::main]
async fn main() -> std::io::Result<()> {
use mwc_libp2p_tcp::TcpConfig;

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 tcp1 = TcpConfig::new().port_reuse(true);
let mut listener1 = tcp1.clone().listen_on(listen_addr1.clone()).expect("listener");
match listener1.next().await.expect("event")? {
    ListenerEvent::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 tcp2 = TcpConfig::new().port_reuse(true);
let mut listener2 = tcp2.clone().listen_on(listen_addr2).expect("listener");
match listener2.next().await.expect("event")? {
    ListenerEvent::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 single GenTcpConfig is used and cloned for the creation of multiple listening sockets or 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 GenTcpConfig 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.

Trait Implementations§

Source§

impl<T: Clone> Clone for GenTcpConfig<T>

Source§

fn clone(&self) -> GenTcpConfig<T>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug> Debug for GenTcpConfig<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T> Transport for GenTcpConfig<T>
where T: Provider + Send + 'static, T::Listener: Unpin, T::IfWatcher: Unpin, T::Stream: Unpin,

Source§

fn address_translation( &self, listen: &Multiaddr, observed: &Multiaddr, ) -> Option<Multiaddr>

When port reuse is disabled and hence ephemeral local ports are used for outgoing connections, the returned address is the observed address with the port replaced by the port of the listen address.

If port reuse is enabled, Some(observed) is returned, as there is a chance that the observed address and port are reachable for other peers if there is a NAT in the way that does endpoint- independent filtering. Furthermore, even if that is not the case and TCP hole punching techniques must be used for NAT traversal, the observed address is still the one that a remote should connect to for the purpose of the hole punching procedure, as it represents the mapped IP and port of the NAT device in front of the local node.

None is returned if one of the given addresses is not a TCP/IP address.

Source§

type Output = <T as Provider>::Stream

The result of a connection setup process, including protocol upgrades. Read more
Source§

type Error = Error

An error that occurred during connection setup.
Source§

type Dial = Pin<Box<dyn Future<Output = Result<<GenTcpConfig<T> as Transport>::Output, <GenTcpConfig<T> as Transport>::Error>> + Send>>

A pending Output for an outbound connection, obtained from dialing.
Source§

type Listener = TcpListenStream<T>

A stream of Outputs for inbound connections. Read more
Source§

type ListenerUpgrade = Ready<Result<<GenTcpConfig<T> as Transport>::Output, <GenTcpConfig<T> as Transport>::Error>>

A pending Output for an inbound connection, obtained from the Listener stream. Read more
Source§

fn listen_on( self, addr: Multiaddr, ) -> Result<Self::Listener, TransportError<Self::Error>>

Listens on the given Multiaddr, producing a stream of pending, inbound connections and addresses this transport is listening on (cf. ListenerEvent). Read more
Source§

fn dial( self, addr: Multiaddr, ) -> Result<Self::Dial, TransportError<Self::Error>>

Dials the given Multiaddr, returning a future for a pending outbound connection. Read more
Source§

fn boxed(self) -> Boxed<Self::Output>
where Self: Sized + Transport + Clone + Send + Sync + 'static, Self::Dial: Send + 'static, Self::Listener: Send + 'static, Self::ListenerUpgrade: Send + 'static, Self::Error: Send + Sync,

Boxes the transport, including custom transport errors.
Source§

fn map<F, O>(self, f: F) -> Map<Self, F>
where Self: Sized, F: FnOnce(Self::Output, ConnectedPoint) -> O + Clone,

Applies a function on the connections created by the transport.
Source§

fn map_err<F, E>(self, f: F) -> MapErr<Self, F>
where Self: Sized, F: FnOnce(Self::Error) -> E + Clone,

Applies a function on the errors generated by the futures of the transport.
Source§

fn or_transport<U>(self, other: U) -> OrTransport<Self, U>
where Self: Sized, U: Transport, <U as Transport>::Error: 'static,

Adds a fallback transport that is used when encountering errors while establishing inbound or outbound connections. Read more
Source§

fn and_then<C, F, O>(self, f: C) -> AndThen<Self, C>
where Self: Sized, C: FnOnce(Self::Output, ConnectedPoint) -> F + Clone, F: TryFuture<Ok = O>, <F as TryFuture>::Error: Error + 'static,

Applies a function producing an asynchronous result to every connection created by this transport. Read more
Source§

fn upgrade(self, version: Version) -> Builder<Self>
where Self: Sized, Self::Error: 'static,

Begins a series of protocol upgrades via an upgrade::Builder.

Auto Trait Implementations§

§

impl<T> Freeze for GenTcpConfig<T>

§

impl<T> RefUnwindSafe for GenTcpConfig<T>
where T: RefUnwindSafe,

§

impl<T> Send for GenTcpConfig<T>
where T: Send,

§

impl<T> Sync for GenTcpConfig<T>
where T: Sync,

§

impl<T> Unpin for GenTcpConfig<T>
where T: Unpin,

§

impl<T> UnwindSafe for GenTcpConfig<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> ErasedDestructor for T
where T: 'static,