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.
This commit is contained in:
Max Inden
2021-10-14 18:05:07 +02:00
committed by GitHub
parent c0d7d4a9eb
commit 40c5335e3b
36 changed files with 2242 additions and 2319 deletions

View File

@ -202,6 +202,7 @@ impl NetworkBehaviour for Relay {
peer: &PeerId,
connection_id: &ConnectionId,
_: &ConnectedPoint,
_: Option<&Vec<Multiaddr>>,
) {
let is_first = self
.connected_peers
@ -304,9 +305,9 @@ impl NetworkBehaviour for Relay {
fn inject_dial_failure(
&mut self,
peer_id: &PeerId,
peer_id: Option<PeerId>,
_: Self::ProtocolsHandler,
error: DialError,
error: &DialError,
) {
if let DialError::DialPeerConditionFalse(
DialPeerCondition::Disconnected | DialPeerCondition::NotDialing,
@ -316,35 +317,37 @@ impl NetworkBehaviour for Relay {
return;
}
if let Entry::Occupied(o) = self.listeners.entry(*peer_id) {
if matches!(o.get(), RelayListener::Connecting { .. }) {
// By removing the entry, the channel to the listener is dropped and thus the
// listener is notified that dialing the relay failed.
o.remove_entry();
if let Some(peer_id) = peer_id {
if let Entry::Occupied(o) = self.listeners.entry(peer_id) {
if matches!(o.get(), RelayListener::Connecting { .. }) {
// By removing the entry, the channel to the listener is dropped and thus the
// listener is notified that dialing the relay failed.
o.remove_entry();
}
}
}
if let Some(reqs) = self.outgoing_relay_reqs.dialing.remove(peer_id) {
for req in reqs {
let _ = req.send_back.send(Err(OutgoingRelayReqError::DialingRelay));
if let Some(reqs) = self.outgoing_relay_reqs.dialing.remove(&peer_id) {
for req in reqs {
let _ = req.send_back.send(Err(OutgoingRelayReqError::DialingRelay));
}
}
}
if let Some(reqs) = self.incoming_relay_reqs.remove(peer_id) {
for req in reqs {
let IncomingRelayReq::DialingDst {
src_peer_id,
incoming_relay_req,
..
} = req;
self.outbox_to_swarm
.push_back(NetworkBehaviourAction::NotifyHandler {
peer_id: src_peer_id,
handler: NotifyHandler::Any,
event: RelayHandlerIn::DenyIncomingRelayReq(
incoming_relay_req.deny(circuit_relay::Status::HopCantDialDst),
),
})
if let Some(reqs) = self.incoming_relay_reqs.remove(&peer_id) {
for req in reqs {
let IncomingRelayReq::DialingDst {
src_peer_id,
incoming_relay_req,
..
} = req;
self.outbox_to_swarm
.push_back(NetworkBehaviourAction::NotifyHandler {
peer_id: src_peer_id,
handler: NotifyHandler::Any,
event: RelayHandlerIn::DenyIncomingRelayReq(
incoming_relay_req.deny(circuit_relay::Status::HopCantDialDst),
),
})
}
}
}
}
@ -411,15 +414,6 @@ impl NetworkBehaviour for Relay {
}
}
fn inject_addr_reach_failure(
&mut self,
_peer_id: Option<&PeerId>,
_addr: &Multiaddr,
_error: &dyn std::error::Error,
) {
// Handled in `inject_dial_failure`.
}
fn inject_listener_error(&mut self, _id: ListenerId, _err: &(dyn std::error::Error + 'static)) {
}