In case an error happens for an outgoing connection, `Pool` reports an `OutgoingConnectionError`. This one is mapped to a `DialError` and reported via `SwarmEvent::OutgoingConnectionError` and `FromSwarm::DialFailure`.
For incoming connections, we didn't quite do the same thing. For one, `SwarmEvent::IncomingConnectionError` directly contained a `PendingInboundConnectionError`. Two, `FromSwarm::ListenFailure` did not include an error at all.
With this patch, we now introduce a `ListenError` enum which we use in `SwarmEvent::IncomingConnectionError` and we pass a reference to it along in `FromSwarm::ListenFailure`.
Instead of offering a public constructor, users are now no longer able to construct `ConnectionId`s at all. They only public API exposed are the derived traits. Internally, `ConnectionId`s are monotonically incremented using a static atomic counter, thus no two connections will ever get assigned the same ID.
Previously, we had one callback for each kind of message that a `ConnectionHandler` would receive from either its `NetworkBehaviour` or the connection itself.
With this patch, we combine these functions, resulting in two callbacks:
- `on_behaviour_event`
- `on_connection_event`
Resolves#3080.
* Remove unreachable error case
Instead of taking the connection out of the map again, construct
the event to be returned with the data we already have available.
* Remove `Pool::get` and `PoolConnection`
These are effectively not used.
* Replace `iter_pending_info` with its only usage: `is_dialing`
* Add `is_for_same_remote_as` convenience function
* Remove `PendingConnection`
* Rename `PendingConnectionInfo` to `PendingConnection`
With the latter being gone, the name is now free.
* Merge `EstablishedConnectionInfo` and `EstablishedConnection`
This is a leftover from when `Pool` was still in `libp2p-core` and
one of them was a public API and the other one wasn't.
All of this is private to `libp2p-swarm` so we no longer need to
differentiate.
* Don't `pub use` out of `pub(crate)` modules
Previously, the `DummyConnectionHandler` offered a "keep alive" functionality,
i.e. it allowed users to set the value of what is returned from
`ConnectionHandler::keep_alive`. This handler is primarily used in tests or
`NetworkBehaviour`s that don't open any connections (like mDNS). In all of these
cases, it is statically known whether we want to keep connections alive. As
such, this functionality is better represented by a static
`KeepAliveConnectionHandler` that always returns `KeepAlive::Yes` and a
`DummyConnectionHandler` that always returns `KeepAlive::No`.
To follow the naming conventions described in
https://github.com/libp2p/rust-libp2p/issues/2217, we introduce a top-level
`keep_alive` and `dummy` behaviour in `libp2p-swarm` that contains both the
`NetworkBehaviour` and `ConnectionHandler` implementation for either case.
* Provide separate functions for injecting in- and outbound streams
* Inline `HandlerWrapper` into `Connection`
* Only poll for new inbound streams if we are below the limit
* yamux: Buffer inbound streams in `StreamMuxer::poll`
Instead of having a mix of `poll_event`, `poll_outbound` and `poll_close`, we
flatten the entire interface of `StreamMuxer` into 4 individual functions:
- `poll_inbound`
- `poll_outbound`
- `poll_address_change`
- `poll_close`
This design is closer to the design of other async traits like `AsyncRead` and
`AsyncWrite`. It also allows us to delete the `StreamMuxerEvent`.
Remove the concept of individual `Transport::Listener` streams from `Transport`.
Instead the `Transport` is polled directly via `Transport::poll`. The
`Transport` is now responsible for driving its listeners.
* core/muxing: Remove `Into<io::Error>` bound from `StreamMuxer::Error`
This allows us to preserve the type information of a muxer's concrete
error as long as possible. For `StreamMuxerBox`, we leverage `io::Error`'s
capability of wrapping any error that implements `Into<Box<dyn Error>>`.
* Use `?` in `Connection::poll`
* Use `?` in `muxing::boxed::Wrap`
* Use `futures::ready!` in `muxing::boxed::Wrap`
* Fill PR number into changelog
* Put `Error + Send + Sync` bounds directly on `StreamMuxer::Error`
* Move `Send + Sync` bounds to higher layers
* Use `map_inbound_stream` helper
* Update changelog to match new implementation
Log peer ID and stream limit as well as reference config option when limit is
exceeded. This should help folks running into this limit debug what is going on.
This limit is shared across all `ConnectionHandler`s on a single connection. It
only enforces a limit on the number of negotiating substreams. Once negotiated a
`ConnectionHandler` manages the lifecycle of the substream and has to enforce
limits themselves.
A `ProtocolsHandler`, now `ConnectionHandler`, handels a connection, not
a protocol. Thus the name `CONNECTIONHandler` is more appropriate.
Next to the rename of `ProtocolsHandler` this commit renames the `mod
protocols_handler` to `mod handler`. Finally all combinators (e.g.
`ProtocolsHandlerSelect`) are renamed appropriately.
Previously one would wrap a `ProtocolsHandler` into a
`NodeHandlerWrapper` as early as possible, even though the functionality
of `NodeHandlerWrapper` is only needed within `mod connection`.
This commit makes `NodeHandlerWrapper` an implementation detail of `mod
connection`, thus neither `mod protocols_handler`, `mod pool` nor the
root level (`libp2p-swarm`) need to bother about the abstraction.
In addition to the above, this commit:
- Renames `NodeHandlerWrapper` to `HandlerWrapper`. The word `Node` is
outdated.
- Removes `NodeHandlerWrapperBuilder`. With this simplification it is no
longer needed.
- Folds `NodeHandlerWrapperError` into `ConnectionError`. No need for
upper layers to be aware of the fact that `ProtocolHandler`s are
wrapped.
The `ConnectionHandler` trait is not exposed to users. The only
implementor of `ConnectionHandler` is `NodeHandlerWrapper`. Thus
`ConnectionHandler` is a superfluous abstraction. This commit removes
`ConnectionHandler`.
Next to this large change, this commit removes the `Tmuxer` trait
parameter. `Swarm` enforces dynamic dispatching via `StreamMuxerBox`
anyways, thus the trait parameter is useless.
As a follow up to this commit one could rename `ProtocolsHandler` to
`ConnectionHandler` and `NodeHandlerWrapper` to
`ConnectionHandlerWrapper` or just `Wrapper`.
This commit removes the `Network` abstraction, thus managing `Listeners`
and the connection `Pool` in `Swarm` directly. This is done under the
assumption that noone uses the `Network` abstraction directly, but
instead everyone always uses it through `Swarm`. Both `Listeners` and
`Pool` are moved from `libp2p-core` into `libp2p-swarm`. Given that they
are no longer exposed via `Network`, they can be treated as an
implementation detail of `libp2p-swarm` and `Swarm`.
This change does not include any behavioural changes.
This change has the followin benefits:
- Removal of `NetworkEvent`, which was mostly an isomorphism of
`SwarmEvent`.
- Removal of the never-directly-used `Network` abstraction.
- Removal of now obsolete verbose `Peer` (`core/src/network/peer.rs`)
construct.
- Removal of `libp2p-core` `DialOpts`, which is a direct mapping of
`libp2p-swarm` `DialOpts`.
- Allowing breaking changes to the connection handling and `Swarm` API
interface without a breaking change in `libp2p-core` and thus a
without a breaking change in `/transport` protocols.
This change enables the following potential future changes:
- Removal of `NodeHandler` and `ConnectionHandler`. Thus allowing to
rename `ProtocolsHandler` into `ConnectionHandler`.
- Moving `NetworkBehaviour` and `ProtocolsHandler` into `libp2p-core`,
having `libp2p-xxx` protocol crates only depend on `libp2p-core` and
thus allowing general breaking changes to `Swarm` without breaking all
`libp2p-xxx` crates.