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()
)
```
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.
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>
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>
- Change `PublicKey::into_protobuf_encoding` to
`PublicKey::to_protobuf_encoding`.
- Change `PublicKey::into_peer_id` to `PublicKey::to_peer_id`.
- Change `PeerId::from_public_key(PublicKey)` to
`PeerId::from_public_key(&PublicKey)`.
- Add `From<&PublicKey> for PeerId`.
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 /ipfs/id/push/1.0.0 alongside some refactoring.
* Implement /ipfs/id/push/1.0.0, i.e. the ability to actively
push information of the local peer to specific remotes.
* Make the initial delay as well as the recurring delay
for the periodic identification requests configurable,
introducing `IdentifyConfig`.
* Fix test.
* Fix example.
* Update protocols/identify/src/identify.rs
Co-authored-by: Max Inden <mail@max-inden.de>
* Update protocols/identify/src/identify.rs
Co-authored-by: Max Inden <mail@max-inden.de>
* Update versions and changelogs.
Co-authored-by: Max Inden <mail@max-inden.de>
* 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.
This commit implements the [libp2p circuit
relay](https://github.com/libp2p/specs/tree/master/relay) specification. It is
based on previous work from https://github.com/libp2p/rust-libp2p/pull/1134.
Instead of altering the `Transport` trait, the approach taken in this commit
is to wrap an existing implementation of `Transport` allowing one to:
- Intercept `dial` requests with a relayed address.
- Inject incoming relayed connections with the local node being the destination.
- Intercept `listen_on` requests pointing to a relay, ensuring to keep a
constant connection to the relay, waiting for incoming requests with the local
node being the destination.
More concretely one would wrap an existing `Transport` implementation as seen
below, allowing the `Relay` behaviour and the `RelayTransport` to communicate
via channels.
### Example
```rust
let (relay_transport, relay_behaviour) = new_transport_and_behaviour(
RelayConfig::default(),
MemoryTransport::default(),
);
let transport = relay_transport
.upgrade(upgrade::Version::V1)
.authenticate(plaintext)
.multiplex(YamuxConfig::default())
.boxed();
let mut swarm = Swarm::new(transport, relay_behaviour, local_peer_id);
let relay_addr = Multiaddr::from_str("/memory/1234").unwrap()
.with(Protocol::P2p(PeerId::random().into()))
.with(Protocol::P2pCircuit);
let dst_addr = relay_addr.clone().with(Protocol::Memory(5678));
// Listen for incoming connections via relay node (1234).
Swarm::listen_on(&mut swarm, relay_addr).unwrap();
// Dial node (5678) via relay node (1234).
Swarm::dial_addr(&mut swarm, dst_addr).unwrap();
```
Co-authored-by: Pierre Krieger <pierre.krieger1708@gmail.com>
Co-authored-by: Roman Borschel <romanb@users.noreply.github.com>
Co-authored-by: David Craven <david@craven.ch>