- Removes the `Swarm` type alias, renaming `ExpandedSwarm` to `Swarm`.
- Remove `TInEvent`, `TOutEvent` and `THandler` trait parameters on
`Swarm`, instead deriving them through `TBehaviour`. Move derive logic
to separate type aliases.
- Simplify trait bounds on `Swarm` main `impl` and `Stream` `impl`.
Don't close connection if ping protocol is unsupported by remote. Previously, a
failed protocol negotation for ping caused a force close of the connection. As a
result, all nodes in a network had to support ping. To allow networks where some
nodes don't support ping, we now emit `PingFailure::Unsupported` once for every
connection on which ping is not supported.
Co-authored-by: Max Inden <mail@max-inden.de>
Not all implementations of `NetworkBehaviour` need all callbacks.
We've have been adding new callbacks with default implementations
for a while now. There is no reason the initial ones cannot also
be defaulted, thus making it easier create new implementations.
Co-authored-by: Max Inden <mail@max-inden.de>
Add `ExpandedSwarm::disconnect_peer_id` and
`NetworkBehaviourAction::CloseConnection` to close connections to a specific
peer via an `ExpandedSwarm` or `NetworkBehaviour`.
Co-authored-by: Max Inden <mail@max-inden.de>
Change `Stream` implementation of `ExpandedSwarm` to return all
`SwarmEvents` instead of only the `NetworkBehaviour`'s events.
Remove `ExpandedSwarm::next_event`. Users can use `<ExpandedSwarm as
StreamExt>::next` instead.
Remove `ExpandedSwarm::next`. Users can use `<ExpandedSwarm as
StreamExt>::filter_map` instead.
Remove `Deref` and `DerefMut` implementations previously dereferencing
to the `NetworkBehaviour` on `Swarm`. Instead one can access the
`NetworkBehaviour` via `Swarm::behaviour` and `Swarm::behaviour_mut`.
Methods on `Swarm` can now be accessed directly, e.g. via
`my_swarm.local_peer_id()`.
Reasoning: Accessing the `NetworkBehaviour` of a `Swarm` through `Deref`
and `DerefMut` instead of a method call is an unnecessary complication,
especially for newcomers. In addition, `Swarm` is not a smart-pointer
and should thus not make use of `Deref` and `DerefMut`, see documentation
from the standard library below.
> Deref should only be implemented for smart pointers to avoid
confusion.
https://doc.rust-lang.org/std/ops/trait.Deref.html
* Implement `/dnsaddr` support on `libp2p-dns`.
To that end, since resolving `/dnsaddr` addresses needs
"fully qualified" multiaddresses when dialing, i.e. those
that end with the `/p2p/...` protocol, we make sure that
dialing always uses such fully qualified addresses by
appending the `/p2p` protocol as necessary. As a side-effect,
this adds support for dialing peers via "fully qualified"
addresses, as an alternative to using a `PeerId` together
with a `Multiaddr` with or without the `/p2p` protocol.
* Adapt libp2p-relay.
* Update versions, changelogs and small cleanups.
* Make clippy "happy".
Address all clippy complaints that are not purely stylistic (or even
have corner cases with false positives). Ignore all "style" and "pedantic" lints.
* Fix tests.
* Undo unnecessary API change.
Remove `NotifyHandler::All` thus removing the requirement for events
send from a `NetworkBehaviour` to a `ProtocolsHandler` to be `Clone`. An
implementor of `NetworkBehaviour` can still notify all
`ProtocolHandler`s for a given peer by emitting one `NotifyHandler`
event per connection to that peer.
Commit 335e55e6 removed the `ConnectionInfo` trait in favor of
`PeerId`s. Commit 1bd013c8 removed `ExpandedSwarm::connection_info` as
it would only return the `PeerId` that the caller is already aware of.
One could use `ExpandedSwarm::connection_info` not only to retrieve the
`ConnectionInfo` for a given peer, but also to check whether the
underlying `Network` has a connection to the peer.
This commit exposes the `is_connected` method on `Network` via
`ExpandedSwarm` to check whether the `Network` has an established
connection to a given peer.
* Refactor and extend configurable connection limits.
To better track different connection counts, permit configurable
limits for these counts and make these available for
inspection efficiently, introduce dedicated connection counters
via a `ConnectionCounters` structure that is exposed on the
API via the `NetworkInfo`. All connection or connection
states that are counted in this way can also have effective
configurable limits.
* Cleanup
* Add missing file.
* Refine naming and config API.
* Update core/CHANGELOG.md
Co-authored-by: Max Inden <mail@max-inden.de>
* Update core/CHANGELOG.md
Co-authored-by: Max Inden <mail@max-inden.de>
Co-authored-by: Max Inden <mail@max-inden.de>
* Add "infinite" scores for external addresses.
Extend address scores with an infinite cardinal, permitting
addresses to be retained "forever" or until explicitly removed.
Expose (external) address scores on the API.
* Update swarm/src/registry.rs
Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
* Fix compilation.
* Update CHANGELOG
Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
In all cases, we pass the PeerId directly as the connection info.
The flexbility of doing something different here was originally
envisioned but turned out to be never needed.
For reference see: https://github.com/libp2p/rust-libp2p/issues/1798#issuecomment-714526056
Co-authored-by: Max Inden <mail@max-inden.de>
* [multistream-select] Fix panic with V1Lazy and add integration tests.
Fixes a panic when using the `V1Lazy` negotiation protocol,
a regression introduced in https://github.com/libp2p/rust-libp2p/pull/1484.
Thereby adds integration tests for a transport upgrade with both
`V1` and `V1Lazy` to the `multistream-select` crate to prevent
future regressions.
* Cleanup.
* Update changelog.
* Simplify incoming connection handling.
Instead of handing out a mutable borrow to the connection
pool in the `IncomingConnectionEvent`, so one can call
`IncomingConnectionEvent::accept()`, just provide
`Network::accept()`.
* Update docs.
* Update CHANGELOG.
* Emit events for active connection close and fix `disconnect()`.
The `Network` does currently not emit events for actively
closed connections, e.g. via `EstablishedConnection::close`
or `ConnectedPeer::disconnect()`. As a result, when actively
closing connections, there will be `ConnectionEstablished`
events emitted without eventually a matching `ConnectionClosed`
event. This seems undesirable and has the consequence that
the `Swarm::ban_peer_id` feature in `libp2p-swarm` does not
result in appropriate calls to `NetworkBehaviour::inject_connection_closed`
and `NetworkBehaviour::inject_disconnected`. Furthermore,
the `disconnect()` functionality in `libp2p-core` is currently
broken as it leaves the `Pool` in an inconsistent state.
This commit does the following:
1. When connection background tasks are dropped
(i.e. removed from the `Manager`), they
always terminate immediately, without attempting
an orderly close of the connection.
2. An orderly close is sent to the background task
of a connection as a regular command. The
background task emits a `Closed` event
before terminating.
3. `Pool::disconnect()` removes all connection
tasks for the affected peer from the `Manager`,
i.e. without an orderly close, thereby also
fixing the discovered state inconsistency
due to not removing the corresponding entries
in the `Pool` itself after removing them from
the `Manager`.
4. A new test is added to `libp2p-swarm` that
exercises the ban/unban functionality and
places assertions on the number and order
of calls to the `NetworkBehaviour`. In that
context some new testing utilities have
been added to `libp2p-swarm`.
This addresses https://github.com/libp2p/rust-libp2p/issues/1584.
* Update swarm/src/lib.rs
Co-authored-by: Toralf Wittner <tw@dtex.org>
* Incorporate some review feedback.
* Adapt to changes in master.
* More verbose panic messages.
* Simplify
There is no need for a `StartClose` future.
* Fix doc links.
* Further small cleanup.
* Update CHANGELOGs and versions.
Co-authored-by: Toralf Wittner <tw@dtex.org>
* Ignore a node's own addresses on dialing.
Dialing attempts of a local node to one of its own
addresses for what appears to be a different peer
ID are futile and bound to fail with an `InvalidPeerId`
error. To avoid such futile dialing attempts, filter
out the node's own addresses from the addresses
reported by the `NetworkBehaviour` for any peer.
There can be a few reasons why a `NetworkBehaviour` may
think an address belongs to a different peer, e.g.:
1. In the context of e.g. `libp2p-kad`, the local node
may have changed its network identity (e.g. key rotation)
and "discovers" its former identity in the DHT, with the same
address(es).
2. Another peer may erroneously or intentionally, possibly even maliciously,
report one of the local node's addresses as its own, making the node
try to connect to itself.
Relates to https://github.com/paritytech/stakingops-issues/issues/18.
* Remove filtering of external addresses.
Since these are obtained from other peers, it would constitute
an attack vector. It is furthermore usually not possible for
a peer behind a NAT to dial its own external address so these
are unlikely to cause `InvalidPeerId` errors as a result of a
peer dialing itself under the expectation of one of its
former peer IDs.
* Allow StreamMuxer to notify changes in the address
* Fix doc link
* Revert accidental rename
* Other accidental rename
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
* Make the number of events buffered to/from tasks configurable
* Assign a PR number
* Fix comment
* Apply suggestions from code review
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
* Rename variables
* Apply suggestions from code review
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
* Permit concurrent dialing attempts per peer.
This is a follow-up to https://github.com/libp2p/rust-libp2p/pull/1440
and relates to https://github.com/libp2p/rust-libp2p/issues/925.
This change permits multiple dialing attempts per peer.
Note though that `libp2p-swarm` does not yet make use of this ability,
retaining the current behaviour. The essence of the changes are that the
`Peer` API now provides `Peer::dial()`, i.e. regardless of the state in
which the peer is. A dialing attempt is always made up of one or more
addresses tried sequentially, as before, but now there can be multiple
dialing attempts per peer. A configurable per-peer limit for outgoing
connections and thus concurrent dialing attempts is also included.
* Introduce `DialError` in `libp2p-swarm`.
For a cleaner API and to treat the case of no addresses
for a peer as an error, such that a `NetworkBehaviourAction::DialPeer`
request is always matched up with either `inject_connection_established`
or `inject_dial_error`.
* Fix rustdoc link.
* Add `DialPeerCondition::Always`.
* Adapt to master.
* Update changelog.
* Pass the error to inject_listener_closed method
If there is an error when the listener closes, found in the
`NetworkEvent::ListenerClosed` `reason` field, we would like to pass it
on to the `inject_listener_closed()` method so that implementors of this
method have access to it.
Add an error parameter to `inject_listener_closed`. Convert the
`reason` field from a `Result` to an `Option` and if there is an error
pass `Some(error)` at the method call site.
* Pass 'reason' as a Result
* Finish change
Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
* [libp2p-swarm] Make the multiple connections per peer first-class.
This commit makes the notion of multiple connections per peer
first-class in the API of libp2p-swarm, introducing the new
callbacks `inject_connection_established` and
`inject_connection_closed`. The `endpoint` parameter from
`inject_connected` and `inject_disconnected` is removed,
since the first connection to open may not be the last
connection to close, i.e. it cannot be guaranteed,
as was previously the case, that the endpoints passed
to these callbacks match up.
* Have identify track all addresses.
So that identify requests can be answered with the correct
observed address of the connection on which the request
arrives.
* Cleanup
* Cleanup
* Improve the `Peer` state API.
* Remove connection ID from `SwarmEvent::Dialing`.
* Mark `DialPeerCondition` non-exhaustive.
* Re-encapsulate `NetworkConfig`.
To retain the possibility of not re-exposing all
network configuration choices, thereby providing
a more convenient API on the \`SwarmBuilder\`.
* Rework Swarm::dial API.
* Update CHANGELOG.
* Doc formatting tweaks.
* [libp2p-swarm] Correct returned connections from notify_all.
If at least one connection was not ready (i.e. pending), only
those (pending) connections would be returned and considered on the next
iteration, whereas those which were ready should also remain
in the list of connections to notify on retry of `notify_all`.
* Simplify.
It seems unnecessary to use "poll all" -> "send all" semantics,
i.e. attempting an "atomic" broadcast. Rather, events send via
`notify_all` can be delivered as soon as possible, simplifying
the code further.
* Add addresses field for closing listeners
Add an addresses field to the ListenersEvent and the ListenerClosed to
hold the addresses of a listener that has just closed. When we return a
ListenerClosed network event loop over the addresses and call
inject_expired_listen_address on each one.
Fixes: #1482
* Use Vec instead of SmallVec
In order to not expose a third party dependency in our API use a `Vec`
type for the addresses list instead of a `SmallVec`.
* Do not clone for ListenersEvent::Closed
We would like to avoid clones where possible for efficiency reasons.
When returning a `ListenersEvent::Closed` we are already consuming the
listener (by way of a pin projection). We can therefore use a consuming
iterator instead of cloning.
Use `drain(..).collect()` instead of clone to consume the addresses when
returning a `ListenersEvent::Closed`.
* Expire addresses before listener
The listener and its addresses technically expire at the same time, but
since here we have to pick an order, it makes more sense that the
addresses expire first.
Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
* Fix regression w.r.t. reporting of dial errors.
PR [1440] introduced a regression w.r.t. the reporting of
dial errors. In particular, if a connection attempt fails
due to an invalid remote peer ID, any remaining addresses
for the same peer would not be tried (intentional) but
the dial failure would not be reported to the behaviour,
causing e.g. libp2p-kad queries to potentially stall.
In hindsight, I figured it is better to preserve the
previous behaviour to still try alternative addresses
of the peer even on invalid peer ID errors on an earlier
address. In particular because in the context of libp2p-kad
it is not uncommon for peers to report localhost addresses
while the local node actually has e.g. an ipfs node running
on that address, obviously with a different peer ID, which
is the scenario causing frequent invalid peer ID (mismatch)
errors when running the ipfs-kad example.
This commit thus restores the previous behaviour w.r.t.
trying all remaining addresses on invalid peer ID errors
as well as making sure `inject_dial_error` is always
called when the last attempt failed.
[1440]: https://github.com/libp2p/rust-libp2p/pull/1440.
* Remove an fmt::Debug requirement.
* Allow multiple connections per peer in libp2p-core.
Instead of trying to enforce a single connection per peer,
which involves quite a bit of additional complexity e.g.
to prioritise simultaneously opened connections and can
have other undesirable consequences [1], we now
make multiple connections per peer a feature.
The gist of these changes is as follows:
The concept of a "node" with an implicit 1-1 correspondence
to a connection has been replaced with the "first-class"
concept of a "connection". The code from `src/nodes` has moved
(with varying degrees of modification) to `src/connection`.
A `HandledNode` has become a `Connection`, a `NodeHandler` a
`ConnectionHandler`, the `CollectionStream` was the basis for
the new `connection::Pool`, and so forth.
Conceptually, a `Network` contains a `connection::Pool` which
in turn internally employs the `connection::Manager` for
handling the background `connection::manager::Task`s, one
per connection, as before. These are all considered implementation
details. On the public API, `Peer`s are managed as before through
the `Network`, except now the API has changed with the shift of focus
to (potentially multiple) connections per peer. The `NetworkEvent`s have
accordingly also undergone changes.
The Swarm APIs remain largely unchanged, except for the fact that
`inject_replaced` is no longer called. It may now practically happen
that multiple `ProtocolsHandler`s are associated with a single
`NetworkBehaviour`, one per connection. If implementations of
`NetworkBehaviour` rely somehow on communicating with exactly
one `ProtocolsHandler`, this may cause issues, but it is unlikely.
[1]: https://github.com/paritytech/substrate/issues/4272
* Fix intra-rustdoc links.
* Update core/src/connection/pool.rs
Co-Authored-By: Max Inden <mail@max-inden.de>
* Address some review feedback and fix doc links.
* Allow responses to be sent on the same connection.
* Remove unnecessary remainders of inject_replaced.
* Update swarm/src/behaviour.rs
Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>
* Update swarm/src/lib.rs
Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>
* Update core/src/connection/manager.rs
Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>
* Update core/src/connection/manager.rs
Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>
* Update core/src/connection/pool.rs
Co-Authored-By: Pierre Krieger <pierre.krieger1708@gmail.com>
* Incorporate more review feedback.
* Move module declaration below imports.
* Update core/src/connection/manager.rs
Co-Authored-By: Toralf Wittner <tw@dtex.org>
* Update core/src/connection/manager.rs
Co-Authored-By: Toralf Wittner <tw@dtex.org>
* Simplify as per review.
* Fix rustoc link.
* Add try_notify_handler and simplify.
* Relocate DialingConnection and DialingAttempt.
For better visibility constraints.
* Small cleanup.
* Small cleanup. More robust EstablishedConnectionIter.
* Clarify semantics of `DialingPeer::connect`.
* Don't call inject_disconnected on InvalidPeerId.
To preserve the previous behavior and ensure calls to
`inject_disconnected` are always paired with calls to
`inject_connected`.
* Provide public ConnectionId constructor.
Mainly needed for testing purposes, e.g. in substrate.
* Move the established connection limit check to the right place.
* Clean up connection error handling.
Separate connection errors into those occuring during
connection setup or upon rejecting a newly established
connection (the `PendingConnectionError`) and those
errors occurring on previously established connections,
i.e. for which a `ConnectionEstablished` event has
been emitted by the connection pool earlier.
* Revert change in log level and clarify an invariant.
* Remove inject_replaced entirely.
* Allow notifying all connection handlers.
Thereby simplify by introducing a new enum `NotifyHandler`,
used with a single constructor `NetworkBehaviourAction::NotifyHandler`.
* Finishing touches.
Small API simplifications and code deduplication.
Some more useful debug logging.
Co-authored-by: Max Inden <mail@max-inden.de>
Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
Co-authored-by: Toralf Wittner <tw@dtex.org>
* Implement FusedStream for Swarm
The stream for swarm will never terminate, and therefore does not have to
keep track of termination.
* Get rid of the wall of complex type constraints
...as they don't seem to be necessary anymore for latest master
* Simplify trait bounds requirements
* More work
* Moar
* Finish
* Fix final tests
* More simplification
* Use separate traits for Inbound/Outbound
* Update gossipsub and remove warnings
* Add documentation to swarm
* Remove BoxSubstream
* Fix tests not compiling
* Fix stack overflow
* Address concerns
* For some reason my IDE ignored libp2p-kad
* Allow configuring the tasks executor
* Minor tweaks
* Add executor_fn
* Create ThreadsPool at the end if necessary
* Allow configuring the tasks executor
* Minor tweaks
* Add executor_fn
* Create ThreadsPool at the end if necessary
* WIP
* Don't depend on async-std and tokio in core
* Replace FutureObj with PinBoxFuture
* Some docs on Executor
* Fix tests
Co-authored-by: Toralf Wittner <tw@dtex.org>
* Add listener ID and error event.
Report listener errors to client code so they are aware that an error
occurred within a listener. By default we continue to poll listeners
which produced an error, but clients can remove listeners by ID.
* tcp: Report errors.
Instead of silently waiting after errors we return all errors, but pause
after each error, before continuing.
* Add a test.
To ease testing, `Listener` is made generic and we test that no values
and errors are lost. Elapsed time between item generation is not
measured.
* Support the new methods in core-derive.
* Address review concerns.
* Remove `Display` impl of `ListenerId`.
* Add 'static bound to `on_listener_error` error.