diff --git a/core/src/connection/error.rs b/core/src/connection/error.rs index 0d291c370cc..1836965e43e 100644 --- a/core/src/connection/error.rs +++ b/core/src/connection/error.rs @@ -29,10 +29,6 @@ pub enum ConnectionError { // TODO: Eventually this should also be a custom error? IO(io::Error), - /// The connection was dropped because the connection limit - /// for a peer has been reached. - ConnectionLimit(ConnectionLimit), - /// The connection handler produced an error. Handler(THandlerErr), } @@ -48,8 +44,6 @@ where write!(f, "Connection error: I/O error: {}", err), ConnectionError::Handler(err) => write!(f, "Connection error: Handler error: {}", err), - ConnectionError::ConnectionLimit(l) => - write!(f, "Connection error: Connection limit: {}.", l) } } } @@ -63,7 +57,6 @@ where match self { ConnectionError::IO(err) => Some(err), ConnectionError::Handler(err) => Some(err), - ConnectionError::ConnectionLimit(..) => None, } } } @@ -78,6 +71,10 @@ pub enum PendingConnectionError { /// match the one that was expected or is otherwise invalid. InvalidPeerId, + /// The connection was dropped because the connection limit + /// for a peer has been reached. + ConnectionLimit(ConnectionLimit), + /// An I/O error occurred on the connection. // TODO: Eventually this should also be a custom error? IO(io::Error), @@ -96,6 +93,8 @@ where write!(f, "Pending connection: Transport error: {}", err), PendingConnectionError::InvalidPeerId => write!(f, "Pending connection: Invalid peer ID."), + PendingConnectionError::ConnectionLimit(l) => + write!(f, "Connection error: Connection limit: {}.", l), } } } @@ -110,6 +109,7 @@ where PendingConnectionError::IO(err) => Some(err), PendingConnectionError::Transport(err) => Some(err), PendingConnectionError::InvalidPeerId => None, + PendingConnectionError::ConnectionLimit(..) => None, } } } diff --git a/core/src/connection/pool.rs b/core/src/connection/pool.rs index 56e112369e1..f8c9e1a7a36 100644 --- a/core/src/connection/pool.rs +++ b/core/src/connection/pool.rs @@ -112,7 +112,7 @@ pub enum PoolEvent<'a, TInEvent, TOutEvent, THandler, TTransErr, THandlerErr, TC error: PendingConnectionError, /// The handler that was supposed to handle the connection, /// if the connection failed before the handler was consumed. - handler: THandler, + handler: Option, /// The (expected) peer of the failed connection. peer: Option, /// A reference to the pool that managed the connection. @@ -558,7 +558,7 @@ where id, endpoint, error, - handler, + handler: Some(handler), peer, pool: self }) @@ -588,13 +588,13 @@ where .map_or(0, |conns| conns.len()); if let Err(e) = self.limits.check_established(current) { let connected = entry.close(); - let num_established = u32::try_from(e.current).unwrap(); - return Poll::Ready(PoolEvent::ConnectionError { + return Poll::Ready(PoolEvent::PendingConnectionError { id, - connected, - error: ConnectionError::ConnectionLimit(e), - num_established, - pool: self, + endpoint: connected.endpoint, + error: PendingConnectionError::ConnectionLimit(e), + handler: None, + peer, + pool: self }) } // Peer ID checks must already have happened. See `add_pending`. diff --git a/core/src/network.rs b/core/src/network.rs index 10b6e063202..ccb21e849ec 100644 --- a/core/src/network.rs +++ b/core/src/network.rs @@ -512,7 +512,7 @@ fn on_connection_failed<'a, TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TP id: ConnectionId, endpoint: ConnectedPoint, error: PendingConnectionError, - handler: THandler, + handler: Option, ) -> (Option>, NetworkEvent<'a, TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TPeerId>) where TTrans: Transport, @@ -533,22 +533,29 @@ where let num_remain = u32::try_from(attempt.next.len()).unwrap(); let failed_addr = attempt.current.clone(); - let opts = + let (opts, attempts_remaining) = 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) + if let Some(handler) = handler { + let next_attempt = attempt.next.remove(0); + let opts = DialingOpts { + peer: peer_id.clone(), + handler, + address: next_attempt, + remaining: attempt.next + }; + (Some(opts), num_remain) + } else { + // The error is "fatal" for the dialing attempt, since + // the handler was already consumed. All potential + // remaining connection attempts are thus void. + (None, 0) + } } else { - None + (None, 0) }; (opts, NetworkEvent::DialError { - attempts_remaining: num_remain, + attempts_remaining, peer_id, multiaddr: failed_addr, error, @@ -560,7 +567,6 @@ where (None, NetworkEvent::UnknownPeerDialError { multiaddr: address, error, - handler, }), ConnectedPoint::Listener { local_addr, send_back_addr } => (None, NetworkEvent::IncomingConnectionError { diff --git a/core/src/network/event.rs b/core/src/network/event.rs index afbedcf77e2..a63dc47946f 100644 --- a/core/src/network/event.rs +++ b/core/src/network/event.rs @@ -146,10 +146,6 @@ where /// The error that happened. error: PendingConnectionError, - - /// The handler that was passed to `dial()`, if the - /// connection failed before the handler was consumed. - handler: THandler, }, /// An established connection produced an event.