95 Commits

Author SHA1 Message Date
Roman
e530118fb0
build(deps): Bump rand to 0.8 and quickcheck to 1 (#2857)
Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
Co-authored-by: Max Inden <mail@max-inden.de>
2022-09-22 18:48:32 +10:00
Thomas Eizinger
66c275520d
swarm/: Fix rare test failure of multiple_addresses_err (#2882)
In case we accidentally generate the same port twice, we will try to
issue two dial attempts to the same address but also expect two dial
errors which is exactly what this test is trying to catch.
Unfortunately, the assertion is badly written and does not catch
duplicate inputs.
2022-09-11 08:55:26 +02:00
Max Inden
ca07ce4d64
swarm/behaviour: Remove deprecated NetworkBehaviourEventProcess (#2840)
Removes the `NetworkBehaviourEventProcess` and all its associated logic.

See deprecation pull request https://github.com/libp2p/rust-libp2p/pull/2784.

Find rational in https://github.com/libp2p/rust-libp2p/pull/2751.
2022-08-26 07:08:33 +02:00
Max Inden
878c49fa14
swarm/src/behaviour: Deprecate NetworkBehaviourEventProcess (#2784)
In preparation for https://github.com/libp2p/rust-libp2p/pull/2751.
2022-08-16 06:58:17 +02:00
Kourosh
a4110a2b69
*: Remove inject_connected / inject_disconnected from docs (#2805) 2022-08-10 10:20:31 +02:00
Elena Frank
62622a1bad
core/src/transport: Poll Transport directly, remove Transport::Listener (#2652)
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.
2022-07-04 04:16:57 +02:00
Thomas Eizinger
eb490c08e9
core/muxing: Force StreamMuxer::Substream to implement Async{Read,Write} (#2707)
Co-authored-by: Max Inden <mail@max-inden.de>
2022-06-23 21:52:11 +10:00
Max Inden
2acbb457cd
swarm/: Limit negotiating inbound substreams per connection (#2697)
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.
2022-06-08 11:48:46 +02:00
Max Inden
afc5b8d8cd
swarm/src/lib: Prioritize Behaviour over Pool and Pool over Listeners (#2627)
Have the main event loop (`Swarm::poll_next_event`) prioritize:

1. Work on `NetworkBehaviour` over work on `Pool`, thus prioritizing
   local work over work coming from a remote.

2. Work on `Pool` over work on `ListenersStream`, thus prioritizing work
   on existing connections over upgrading new incoming connections.

Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
2022-05-05 20:15:24 +02:00
Max Inden
3cfbf89a3a
swarm/src/connection/pool: Remove 'a lifetime in PoolEvent (#2625)
Simplifies `PoolEvent`, no longer carrying a reference to an
`EstablishedConnection` or the `Pool`, but instead the `PeerId`,
`ConnectionId` and `ConnectedPoint` directly.

Co-authored-by: Elena Frank <elena.frank@protonmail.com>
2022-05-04 10:33:40 +02:00
Hubert
70d38520fd
*: Activate clippy::style lint group (#2620) 2022-05-03 13:11:48 +02:00
Hubert
22fbce34d5
*: Fix clippy warnings (#2615) 2022-04-19 12:13:45 +02:00
Max Inden
2ad905f35a
{core,swarm}/: Don't require Transport: Clone and take &mut (#2529)
Previously `libp2p-swarm` required a `Transport` to be `Clone`. Methods
on `Transport`, e.g. `Transport::dial` would take ownership, requiring
e.g. a `Clone::clone` before calling `Transport::dial`.

The requirement of `Transport` to be `Clone` is no longer needed in
`libp2p-swarm`. E.g.  concurrent dialing can be done without a clone per
dial.

This commit removes the requirement of `Clone` for `Transport` in
`libp2p-swarm`. As a follow-up methods on `Transport` no longer take
ownership, but instead a mutable reference (`&mut self`).

On the one hand this simplifies `libp2p-swarm`, on the other it
simplifies implementations of `Transport`.
2022-04-06 20:23:16 +02:00
Max Inden
b919d0002a
swarm/src/lib: Improve connection counting for test_behaviour_disconnect_all (#2532) 2022-03-02 12:10:57 +01:00
Max Inden
99855b1d10
*: Apply clippy suggestions (#2540) 2022-02-28 10:05:17 +01:00
Max Inden
fd2be38faf
swarm/: Rename ProtocolsHandler to ConnectionHandler (#2527)
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.
2022-02-21 13:32:24 +01:00
Max Inden
2ff9acee22
swarm/: Make NodeHandlerWrapper an impl detail of connection (#2523)
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.
2022-02-18 11:32:58 +01:00
Max Inden
eeb3504d5f
swarm/src/lib: Rework connection exports (#2525) 2022-02-17 21:12:37 +01:00
Max Inden
8ffa84e786
swarm/src: Remove ConnectionHandler (#2519)
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`.
2022-02-16 13:15:52 +01:00
Max Inden
146ed5f45e
swarm/: Report aborted connections (#2517)
Disconnect pending connections with `Swarm::disconnect` and eport aborted
connections via `SwarmEvent::OutgoingConnectionError`.

Co-authored-by: Jack Maloney <git@jmmaloney4.xyz>
Co-authored-by: Marco Munizaga <git@marcopolo.io>
2022-02-15 10:19:55 +01:00
Max Inden
7fc342e6c0
{core,swarm}: Remove Network abstraction (#2492)
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.
2022-02-13 21:57:38 +01:00
Divma
dc8433e3fc
swarm/src/behaviour: Merge inject_* paired methods (#2445)
Co-authored-by: Max Inden <mail@max-inden.de>
2022-02-09 16:08:28 +01:00
Max Inden
4001b565b6
*: Rework reporting of invalid and wrong PeerIds (#2441)
Previously, the negotiated PeerId was included in the swarm event and
inject_dial_failure’s arguments while the expected one was absent. This
patch adds the negotiated PeerId to the DialError and includes the expected
one in the notifications.

Co-authored-by: Roland Kuhn <rk@rkuhn.info>
2022-01-18 21:21:11 +01:00
Max Inden
96dbfcd1ad
core/src/transport: Add Transport::dial_as_listener (#2363)
Allows `NetworkBehaviour` implementations to dial a peer, but instruct
the dialed connection to be upgraded as if it were the listening
endpoint.

This is needed when establishing direct connections through NATs and/or
Firewalls (hole punching). When hole punching via TCP (QUIC is different
but similar) both ends dial the other at the same time resulting in a
simultaneously opened TCP connection. To disambiguate who is the dialer
and who the listener there are two options:

1. Use the Simultaneous Open Extension of Multistream Select. See
   [sim-open] specification and [sim-open-rust] Rust implementation.

2. Disambiguate the role (dialer or listener) based on the role within
   the DCUtR [dcutr] protocol. More specifically the node initiating the
   DCUtR process will act as a listener and the other as a dialer.

This commit enables (2), i.e. enables the DCUtR protocol to specify the
role used once the connection is established.

While on the positive side (2) requires one round trip less than (1), on
the negative side (2) only works for coordinated simultaneous dials.
I.e. when a simultaneous dial happens by chance, and not coordinated via
DCUtR, the connection attempt fails when only (2) is in place.

[sim-open]: https://github.com/libp2p/specs/blob/master/connections/simopen.md
[sim-open-rust]: https://github.com/libp2p/rust-libp2p/pull/2066
[dcutr]: https://github.com/libp2p/specs/blob/master/relay/DCUtR.md
2022-01-17 16:35:14 +01:00
Max Inden
a2621ad498
swarm/src/lib: Update outdated SwarmEvent::Dialing comment (#2429)
Since https://github.com/libp2p/rust-libp2p/pull/2248 dial attempts are
no longer reported per address, but instead reported for all addresses
of a single dial at once.

This commit updates the comment accordingly.
2022-01-14 13:17:45 +01:00
Max Inden
74f31f1266
{core,swarm}/: Allow configuring dial concurrency factor per dial (#2404)
Enable a `NetworkBehaviour` or a user via `Swarm::dial` to override the
dial concurrency factor per dial. This is especially relevant in the
case of libp2p-autonat where one wants to probe addresses in sequence to
reduce the amount of work a remote peer can force onto the local node.

To enable the above, this commit also:

- Introduces `libp2p_core::DialOpts` mirroring `libp2p_swarm::DialOpts`.
  Passed as an argument to `Network::dial`.
- Removes `Peer::dial` in favor of `Network::dial`.
- Simplifies `Swarm::dial_with_handler`.

The introduction of `libp2p_core::DialOpts` will be useful beyond this
feature, e.g. for https://github.com/libp2p/rust-libp2p/pull/2363.

In the long run I would like to move and merge `libp2p_core::Network`
and `libp2p_core::Pool` into `libp2p_swarm::Swarm` thus deduplicating
`libp2p_core::DialOpts` and `libp2p_swarm::DialOpts`.

Fixes #2385.
2022-01-13 18:07:07 +01:00
David Craven
df2e5a591e
protocols/mdns: Support multiple network interfaces (#2383)
Handling multiple interfaces in mdns. The socket logic was moved into an
instance while the mdns behaviour watches for interface changes and creates new
instances with a dedicated send/recv socket.

Co-authored-by: Max Inden <mail@max-inden.de>
2021-12-29 19:02:20 +01:00
David Craven
939e296266
swarm: Expose currently connected peers (#2378)
Co-authored-by: Max Inden <mail@max-inden.de>
2021-12-13 17:17:12 +01:00
Benoit Verkindt
dd9e0a14de
swarm/src/behaviour: Move Toggle into swarm::behaviour (#2375)
Co-authored-by: Max Inden <mail@max-inden.de>
2021-12-09 12:00:47 +01:00
Divma
fd417517ca
swarm/: Patch reporting on banned peer connections (#2350)
Don't report events of a connection to the `NetworkBehaviour`, if connection has
been established while the remote peer was banned. Among other guarantees this
upholds that `NetworkBehaviour::inject_event` is never called without a previous
`NetworkBehaviour::inject_connection_established` for said connection.

Co-authored-by: Max Inden <mail@max-inden.de>
2021-11-26 16:48:12 +01:00
Max Inden
220f84a97f
swarm/: Enable advanced dialing requests (#2317)
Enable advanced dialing requests both on `Swarm` and via
`NetworkBehaviourAction`. Users can now trigger a dial with a specific
set of addresses, optionally extended via
`NetworkBehaviour::addresses_of_peer`. In addition the whole process is
now modelled in a type safe way via the builder pattern.

Example of a `NetworkBehaviour` requesting a dial to a specific peer
with a set of addresses additionally extended through
`NetworkBehaviour::addresses_of_peer`:

```rust
NetworkBehaviourAction::Dial {
    opts: DialOpts::peer_id(peer_id)
              .condition(PeerCondition::Always)
              .addresses(addresses)
              .extend_addresses_through_behaviour()
              .build(),
    handler,
}
```

Example of a user requesting a dial to an unknown peer with a single
address via `Swarm`:

```rust
swarm1.dial(
    DialOpts::unknown_peer_id()
        .address(addr2.clone())
        .build()
)
```
2021-11-15 14:17:23 +01:00
Max Inden
4ef57383a6
swarm/src/lib: Continue polling network when behaviour is blocked (#2304)
With https://github.com/libp2p/rust-libp2p/pull/2248 a connection task
`await`s sending an event to the behaviour before polling for new events
from the behaviour [1].

When `Swarm::poll` is unable to deliver an event to a connection task it
returns `Poll::Pending` even though (a) polling `Swarm::network` might be
able to make progress (`network_not_ready` being `false`) and (b) it
does not register a waker to be woken up [2].

In combination this can lead to a deadlock where a connection task waits
to send an event to the behaviour and `Swarm::poll` returns
`Poll::Pending` failing to send an event to the connection task, not
registering a waiker in order to be polled again.

With this commit `Swarm::poll` will only return `Poll::Pending`, when
failing to deliver an event to a connection task, if the network is
unable to make progress (i.e. `network_not_ready` being `true`).

In the long-run `Swarm::poll` should likely be redesigned, prioritizing
the behaviour over the network, given the former is the control plane
and the latter potentially yields new work from the outside.

[1]: ca1b7cf043/core/src/connection/pool/task.rs (L224-L232)
[2]: ca1b7cf043/swarm/src/lib.rs (L756-L783)
2021-10-26 22:23:55 +02:00
Max Inden
40c5335e3b
core/: Concurrent dial attempts (#2248)
Concurrently dial address candidates within a single dial attempt.

Main motivation for this feature is to increase success rate on hole punching
(see https://github.com/libp2p/rust-libp2p/issues/1896#issuecomment-885894496
for details). Though, as a nice side effect, as one would expect, it does
improve connection establishment time.

Cleanups and fixes done along the way:

- Merge `pool.rs` and `manager.rs`.

- Instead of manually implementing state machines in `task.rs` use
  `async/await`.

- Fix bug where `NetworkBehaviour::inject_connection_closed` is called without a
  previous `NetworkBehaviour::inject_connection_established` (see
  https://github.com/libp2p/rust-libp2p/issues/2242).

- Return handler to behaviour on incoming connection limit error. Missed in
  https://github.com/libp2p/rust-libp2p/issues/2242.
2021-10-14 18:05:07 +02:00
Elena Frank
7718d1de38
core/connection/listeners: Create event on remove_listener (#2261)
Create a `ListenersEvent::Closed` when a listener is removed via
`Swarm::remove_listener`. This makes it more consistent with `Swarm::listen_on`,
and also informs the Swarm about the associated expired addresses.

Co-authored-by: Max Inden <mail@max-inden.de>
2021-10-11 22:38:55 +02:00
Roman
b79fd02f0b
*: Fix clippy warnings (#2227) 2021-09-14 15:00:05 +02:00
Max Inden
c161acfb50
*: Dial with handler and return handler on error and closed (#2191)
Require `NetworkBehaviourAction::{DialPeer,DialAddress}` to contain a
`ProtocolsHandler`. This allows a behaviour to attach custom state to its
handler. The behaviour would no longer need to track this state separately
during connection establishment, thus reducing state required in a behaviour.
E.g. in the case of `libp2p-kad` the behaviour can include a `GetRecord` request
in its handler, or e.g. in the case of `libp2p-request-response` the behaviour
can include the first request in the handler.

Return `ProtocolsHandler` on connection error and close. This allows a behaviour
to extract its custom state previously included in the handler on connection
failure and connection closing. E.g. in the case of `libp2p-kad` the behaviour
could extract the attached `GetRecord` from the handler of the failed connection
and then start another connection attempt with a new handler with the same
`GetRecord` or bubble up an error to the user.

Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
2021-08-31 17:00:51 +02:00
Max Inden
f701b24ec0
*: Format with rustfmt (#2188)
Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
2021-08-11 13:12:12 +02:00
Max Inden
008561283e
core/: Remove TInEvent and TOutEvent (#2183)
TInEvent and TOutEvent are implied through THandler and thus
superflucious. Both are removed in favor of a derivation through
THandler.
2021-08-11 12:41:28 +02:00
Max Inden
a0d690e259
swarm/src/lib: Refactor trait usage (#2182)
- 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`.
2021-08-09 15:29:58 +02:00
Thomas Eizinger
1e001a2e0e
protocols/ping: Don't force close conn if not supported by remote (#2149)
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>
2021-07-30 22:21:21 +02:00
Thomas Eizinger
ad90167042
swarm/: Provide additional default impls on NetworkBehaviour (#2150)
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>
2021-07-30 19:48:32 +02:00
Elena Frank
a414afd83c
swarm/: include ListenerId in SwarmEvents (#2123)
Co-authored-by: Max Inden <mail@max-inden.de>
2021-07-08 11:41:33 +02:00
Sergey O. Boyko
4eb0659e4d
swarm/: Allow disconnecting from Swarm and NetworkBehaviour (#2110)
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>
2021-07-02 19:35:51 +02:00
Elena Frank
e8fed53598
swarm/: Drive ExpandedSwarm via Stream trait only (#2100)
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.
2021-06-14 20:41:44 +02:00
David Craven
7779b8e2c1
swarm: Extend NetworkBehaviour callbacks. (#2011)
Co-authored-by: Max Inden <mail@max-inden.de>
2021-03-24 17:21:53 +01:00
Max Inden
63512e5f16
swarm/src/lib: Remove Deref and DerefMut impls on Swarm (#1995)
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
2021-03-18 14:55:33 +01:00
Roman Borschel
45f07bf863
[libp2p-dns] Implement /dnsaddr resolution. (#1931)
* 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.
2021-03-17 10:53:19 +01:00
Roman Borschel
6499e924a3
Make clippy "happy". (#1950)
* 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.
2021-02-15 11:59:51 +01:00
Joonas Koivunen
ab6fecd9f3
Fix DialPeerCondition::Always handling (#1937)
* fix: always dial with condition Always

* chore: changelog note

* refactor: exhaustive DialPeerCondition matching

Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
2021-01-27 11:05:35 +01:00
Max Inden
22817b5d2b
swarm: Remove NotifyHandler::All (#1880)
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.
2020-12-17 11:01:45 +01:00