mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-26 00:01:33 +00:00
Fix regression w.r.t. reporting of dial errors. (#1493)
* 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.
This commit is contained in:
@ -55,7 +55,6 @@ use std::{
|
||||
error,
|
||||
fmt,
|
||||
hash::Hash,
|
||||
num::NonZeroUsize,
|
||||
pin::Pin,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
@ -331,7 +330,7 @@ where
|
||||
THandler::Handler: ConnectionHandler<Substream = Substream<TMuxer>, InEvent = TInEvent, OutEvent = TOutEvent> + Send + 'static,
|
||||
<THandler::Handler as ConnectionHandler>::Error: error::Error + Send + 'static,
|
||||
TConnInfo: Clone,
|
||||
TPeerId: AsRef<[u8]> + Send + 'static,
|
||||
TPeerId: Send + 'static,
|
||||
{
|
||||
// Poll the listener(s) for new connections.
|
||||
match ListenersStream::poll(Pin::new(&mut self.listeners), cx) {
|
||||
@ -383,7 +382,7 @@ where
|
||||
}
|
||||
Poll::Ready(PoolEvent::PendingConnectionError { id, endpoint, error, handler, pool, .. }) => {
|
||||
let dialing = &mut self.dialing;
|
||||
let (next, event) = on_connection_failed(pool, dialing, id, endpoint, error, handler);
|
||||
let (next, event) = on_connection_failed(dialing, id, endpoint, error, handler);
|
||||
if let Some(dial) = next {
|
||||
let transport = self.listeners.transport().clone();
|
||||
if let Err(e) = dial_peer_impl(transport, pool, dialing, dial) {
|
||||
@ -496,13 +495,11 @@ where
|
||||
/// If the failed connection attempt was a dialing attempt and there
|
||||
/// are more addresses to try, new `DialingOpts` are returned.
|
||||
fn on_connection_failed<'a, TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TPeerId>(
|
||||
pool: &Pool<TInEvent, TOutEvent, THandler, TTrans::Error,
|
||||
<THandler::Handler as ConnectionHandler>::Error, TConnInfo, TPeerId>,
|
||||
dialing: &mut FnvHashMap<TPeerId, peer::DialingAttempt>,
|
||||
id: ConnectionId,
|
||||
endpoint: ConnectedPoint,
|
||||
error: PendingConnectionError<TTrans::Error>,
|
||||
handler: Option<THandler>,
|
||||
handler: THandler,
|
||||
) -> (Option<DialingOpts<TPeerId, THandler>>, NetworkEvent<'a, TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TPeerId>)
|
||||
where
|
||||
TTrans: Transport,
|
||||
@ -518,41 +515,27 @@ where
|
||||
|
||||
if let Some(peer_id) = dialing_peer {
|
||||
// A pending outgoing connection to a known peer failed.
|
||||
let attempt = dialing.remove(&peer_id).expect("by (1)");
|
||||
let mut attempt = dialing.remove(&peer_id).expect("by (1)");
|
||||
|
||||
let num_remain = attempt.next.len();
|
||||
let failed_addr = attempt.current.clone();
|
||||
|
||||
let new_state = if pool.is_connected(&peer_id) {
|
||||
peer::PeerState::Connected
|
||||
} else if num_remain == 0 { // (2)
|
||||
peer::PeerState::Disconnected
|
||||
} else {
|
||||
peer::PeerState::Dialing {
|
||||
num_pending_addresses: NonZeroUsize::new(num_remain).expect("by (2)"),
|
||||
}
|
||||
};
|
||||
|
||||
let opts =
|
||||
if let Some(handler) = handler {
|
||||
if !attempt.next.is_empty() {
|
||||
let mut attempt = attempt;
|
||||
let next_attempt = attempt.next.remove(0);
|
||||
Some(DialingOpts {
|
||||
peer: peer_id.clone(),
|
||||
handler,
|
||||
address: next_attempt,
|
||||
remaining: attempt.next
|
||||
})
|
||||
} else {
|
||||
None
|
||||
}
|
||||
if num_remain > 0 {
|
||||
let next_attempt = attempt.next.remove(0);
|
||||
let opts = DialingOpts {
|
||||
peer: peer_id.clone(),
|
||||
handler,
|
||||
address: next_attempt,
|
||||
remaining: attempt.next
|
||||
};
|
||||
Some(opts)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
(opts, NetworkEvent::DialError {
|
||||
new_state,
|
||||
attempts_remaining: num_remain,
|
||||
peer_id,
|
||||
multiaddr: failed_addr,
|
||||
error,
|
||||
|
Reference in New Issue
Block a user