diff --git a/core/src/swarm.rs b/core/src/swarm.rs index 5c4c3c00..8decd043 100644 --- a/core/src/swarm.rs +++ b/core/src/swarm.rs @@ -54,7 +54,7 @@ use crate::{ }; use futures::prelude::*; use smallvec::SmallVec; -use std::{fmt, io, ops::{Deref, DerefMut}}; +use std::{error, fmt, io, ops::{Deref, DerefMut}}; pub use crate::nodes::raw_swarm::ConnectedPoint; @@ -261,8 +261,12 @@ where TBehaviour: NetworkBehaviour, }, Async::Ready(RawSwarmEvent::ListenerClosed { .. }) => {}, Async::Ready(RawSwarmEvent::IncomingConnectionError { .. }) => {}, - Async::Ready(RawSwarmEvent::DialError { .. }) => {}, - Async::Ready(RawSwarmEvent::UnknownPeerDialError { .. }) => {}, + Async::Ready(RawSwarmEvent::DialError { peer_id, multiaddr, error, .. }) => { + self.behaviour.inject_dial_failure(Some(&peer_id), &multiaddr, &error); + }, + Async::Ready(RawSwarmEvent::UnknownPeerDialError { multiaddr, error, .. }) => { + self.behaviour.inject_dial_failure(None, &multiaddr, &error); + }, } let behaviour_poll = { @@ -319,7 +323,7 @@ pub trait NetworkBehaviour { /// Addresses that this behaviour is aware of for this specific peer, and that may allow /// reaching the peer. - fn addresses_of_peer(&self, peer_id: &PeerId) -> Vec; + fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec; /// Indicates the behaviour that we connected to the node with the given peer id through the /// given endpoint. @@ -339,6 +343,10 @@ pub trait NetworkBehaviour { event: <::Handler as ProtocolsHandler>::OutEvent ); + /// Indicates to the behaviour that we tried to reach a node, but failed. + fn inject_dial_failure(&mut self, _peer_id: Option<&PeerId>, _addr: &Multiaddr, _error: &dyn error::Error) { + } + /// Polls for things that swarm should do. /// /// This API mimics the API of the `Stream` trait. @@ -549,7 +557,7 @@ mod tests { DummyProtocolsHandler::default() } - fn addresses_of_peer(&self, _: &PeerId) -> Vec { + fn addresses_of_peer(&mut self, _: &PeerId) -> Vec { Vec::new() } diff --git a/misc/core-derive/src/lib.rs b/misc/core-derive/src/lib.rs index dce3e681..f63f927d 100644 --- a/misc/core-derive/src/lib.rs +++ b/misc/core-derive/src/lib.rs @@ -191,6 +191,20 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { }) }; + // Build the list of statements to put in the body of `inject_dial_failure()`. + let inject_dial_failure_stmts = { + data_struct.fields.iter().enumerate().filter_map(move |(field_n, field)| { + if is_ignored(&field) { + return None; + } + + Some(match field.ident { + Some(ref i) => quote!{ self.#i.inject_dial_failure(peer_id, addr, error); }, + None => quote!{ self.#field_n.inject_dial_failure(peer_id, addr, error); }, + }) + }) + }; + // Build the list of variants to put in the body of `inject_node_event()`. // // The event type is a construction of nested `#either_ident`s of the events of the children. @@ -337,7 +351,7 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { #new_handler } - fn addresses_of_peer(&self, peer_id: &#peer_id) -> Vec<#multiaddr> { + fn addresses_of_peer(&mut self, peer_id: &#peer_id) -> Vec<#multiaddr> { let mut out = Vec::new(); #(#addresses_of_peer_stmts);* out @@ -353,6 +367,11 @@ fn build_struct(ast: &DeriveInput, data_struct: &DataStruct) -> TokenStream { #(#inject_disconnected_stmts);* } + #[inline] + fn inject_dial_failure(&mut self, peer_id: Option<&#peer_id>, addr: &#multiaddr, error: &dyn std::error::Error) { + #(#inject_dial_failure_stmts);* + } + #[inline] fn inject_node_event( &mut self, diff --git a/misc/mdns/src/behaviour.rs b/misc/mdns/src/behaviour.rs index 9aec1f97..6a7b835c 100644 --- a/misc/mdns/src/behaviour.rs +++ b/misc/mdns/src/behaviour.rs @@ -149,7 +149,7 @@ where DummyProtocolsHandler::default() } - fn addresses_of_peer(&self, peer_id: &PeerId) -> Vec { + fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec { let now = Instant::now(); self.discovered_nodes .iter() diff --git a/protocols/floodsub/src/layer.rs b/protocols/floodsub/src/layer.rs index 349f99a8..f7218b06 100644 --- a/protocols/floodsub/src/layer.rs +++ b/protocols/floodsub/src/layer.rs @@ -217,7 +217,7 @@ where Default::default() } - fn addresses_of_peer(&self, _: &PeerId) -> Vec { + fn addresses_of_peer(&mut self, _: &PeerId) -> Vec { Vec::new() } diff --git a/protocols/identify/src/identify.rs b/protocols/identify/src/identify.rs index 3fcfbfa3..08d5deba 100644 --- a/protocols/identify/src/identify.rs +++ b/protocols/identify/src/identify.rs @@ -75,7 +75,7 @@ where IdentifyListenHandler::new().select(PeriodicIdHandler::new()) } - fn addresses_of_peer(&self, _: &PeerId) -> Vec { + fn addresses_of_peer(&mut self, _: &PeerId) -> Vec { Vec::new() } diff --git a/protocols/kad/src/behaviour.rs b/protocols/kad/src/behaviour.rs index e56f28f4..0375ab62 100644 --- a/protocols/kad/src/behaviour.rs +++ b/protocols/kad/src/behaviour.rs @@ -282,7 +282,7 @@ where KademliaHandler::dial_and_listen() } - fn addresses_of_peer(&self, peer_id: &PeerId) -> Vec { + fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec { self.kbuckets .get(peer_id) .map(|l| l.iter().cloned().collect::>()) diff --git a/protocols/ping/src/lib.rs b/protocols/ping/src/lib.rs index 18751c57..8e01a848 100644 --- a/protocols/ping/src/lib.rs +++ b/protocols/ping/src/lib.rs @@ -90,7 +90,7 @@ where OneShotHandler::default() } - fn addresses_of_peer(&self, _peer_id: &PeerId) -> Vec { + fn addresses_of_peer(&mut self, _peer_id: &PeerId) -> Vec { Vec::new() }