Skip to content

Commit 4001b56

Browse files
mxindenrkuhn
andauthored
*: Rework reporting of invalid and wrong PeerIds (#2441)
Previously, the negotiated PeerId was included in the swarm event and inject_dial_failure’s arguments while the expected one was absent. This patch adds the negotiated PeerId to the DialError and includes the expected one in the notifications. Co-authored-by: Roland Kuhn <[email protected]>
1 parent 30fc882 commit 4001b56

File tree

9 files changed

+170
-73
lines changed

9 files changed

+170
-73
lines changed

core/CHANGELOG.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,17 @@
1414
- Enable overriding _dial concurrency factor_ per dial via
1515
`DialOpts::override_dial_concurrency_factor`.
1616

17-
- Introduces `libp2p_core::DialOpts` mirroring `libp2p_swarm::DialOpts`.
17+
- Introduces `libp2p_core::DialOpts` mirroring `libp2p_swarm::DialOpts`.
1818
Passed as an argument to `Network::dial`.
19-
- Removes `Peer::dial` in favor of `Network::dial`.
19+
- Removes `Peer::dial` in favor of `Network::dial`.
2020

2121
See [PR 2404].
2222

2323
- Implement `Serialize` and `Deserialize` for `PeerId` (see [PR 2408])
2424

25+
- Report negotiated and expected `PeerId` as well as remote address in
26+
`DialError::WrongPeerId` (see [PR 2428]).
27+
2528
- Allow overriding role when dialing. This option is needed for NAT and firewall
2629
hole punching.
2730

@@ -39,6 +42,7 @@
3942
[PR 2392]: https://github.com/libp2p/rust-libp2p/pull/2392
4043
[PR 2404]: https://github.com/libp2p/rust-libp2p/pull/2404
4144
[PR 2408]: https://github.com/libp2p/rust-libp2p/pull/2408
45+
[PR 2428]: https://github.com/libp2p/rust-libp2p/pull/2428
4246
[PR 2363]: https://github.com/libp2p/rust-libp2p/pull/2363
4347

4448
# 0.30.1 [2021-11-16]
@@ -127,7 +131,7 @@
127131

128132
# 0.28.3 [2021-04-26]
129133

130-
- Fix build with secp256k1 disabled [PR 2057](https://github.com/libp2p/rust-libp2p/pull/2057].
134+
- Fix build with secp256k1 disabled [PR 2057](https://github.com/libp2p/rust-libp2p/pull/2057).
131135

132136
# 0.28.2 [2021-04-13]
133137

core/src/connection/error.rs

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@
1818
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
1919
// DEALINGS IN THE SOFTWARE.
2020

21-
use crate::connection::ConnectionLimit;
2221
use crate::transport::TransportError;
2322
use crate::Multiaddr;
23+
use crate::{connection::ConnectionLimit, ConnectedPoint, PeerId};
2424
use std::{fmt, io};
2525

2626
/// Errors that can occur in the context of an established `Connection`.
@@ -84,14 +84,33 @@ pub enum PendingConnectionError<TTransErr> {
8484
Aborted,
8585

8686
/// The peer identity obtained on the connection did not
87-
/// match the one that was expected or is otherwise invalid.
88-
InvalidPeerId,
87+
/// match the one that was expected or is the local one.
88+
WrongPeerId {
89+
obtained: PeerId,
90+
endpoint: ConnectedPoint,
91+
},
8992

9093
/// An I/O error occurred on the connection.
9194
// TODO: Eventually this should also be a custom error?
9295
IO(io::Error),
9396
}
9497

98+
impl<T> PendingConnectionError<T> {
99+
pub fn map<U>(self, f: impl FnOnce(T) -> U) -> PendingConnectionError<U> {
100+
match self {
101+
PendingConnectionError::Transport(t) => PendingConnectionError::Transport(f(t)),
102+
PendingConnectionError::ConnectionLimit(l) => {
103+
PendingConnectionError::ConnectionLimit(l)
104+
}
105+
PendingConnectionError::Aborted => PendingConnectionError::Aborted,
106+
PendingConnectionError::WrongPeerId { obtained, endpoint } => {
107+
PendingConnectionError::WrongPeerId { obtained, endpoint }
108+
}
109+
PendingConnectionError::IO(e) => PendingConnectionError::IO(e),
110+
}
111+
}
112+
}
113+
95114
impl<TTransErr> fmt::Display for PendingConnectionError<TTransErr>
96115
where
97116
TTransErr: fmt::Display + fmt::Debug,
@@ -110,8 +129,12 @@ where
110129
PendingConnectionError::ConnectionLimit(l) => {
111130
write!(f, "Connection error: Connection limit: {}.", l)
112131
}
113-
PendingConnectionError::InvalidPeerId => {
114-
write!(f, "Pending connection: Invalid peer ID.")
132+
PendingConnectionError::WrongPeerId { obtained, endpoint } => {
133+
write!(
134+
f,
135+
"Pending connection: Unexpected peer ID {} at {:?}.",
136+
obtained, endpoint
137+
)
115138
}
116139
}
117140
}
@@ -125,7 +148,7 @@ where
125148
match self {
126149
PendingConnectionError::IO(err) => Some(err),
127150
PendingConnectionError::Transport(_) => None,
128-
PendingConnectionError::InvalidPeerId => None,
151+
PendingConnectionError::WrongPeerId { .. } => None,
129152
PendingConnectionError::Aborted => None,
130153
PendingConnectionError::ConnectionLimit(..) => None,
131154
}

core/src/connection/pool.rs

Lines changed: 31 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -733,7 +733,7 @@ where
733733
match event {
734734
task::PendingConnectionEvent::ConnectionEstablished {
735735
id,
736-
output: (peer_id, muxer),
736+
output: (obtained_peer_id, muxer),
737737
outgoing,
738738
} => {
739739
let PendingConnectionInfo {
@@ -777,49 +777,42 @@ where
777777
),
778778
};
779779

780-
enum Error {
781-
ConnectionLimit(ConnectionLimit),
782-
InvalidPeerId,
783-
}
784-
785-
impl<TransportError> From<Error> for PendingConnectionError<TransportError> {
786-
fn from(error: Error) -> Self {
787-
match error {
788-
Error::ConnectionLimit(limit) => {
789-
PendingConnectionError::ConnectionLimit(limit)
790-
}
791-
Error::InvalidPeerId => PendingConnectionError::InvalidPeerId,
792-
}
793-
}
794-
}
795-
796-
let error = self
780+
let error: Result<(), PendingInboundConnectionError<_>> = self
797781
.counters
798782
// Check general established connection limit.
799783
.check_max_established(&endpoint)
800-
.map_err(Error::ConnectionLimit)
784+
.map_err(PendingConnectionError::ConnectionLimit)
801785
// Check per-peer established connection limit.
802786
.and_then(|()| {
803787
self.counters
804788
.check_max_established_per_peer(num_peer_established(
805789
&self.established,
806-
peer_id,
790+
obtained_peer_id,
807791
))
808-
.map_err(Error::ConnectionLimit)
792+
.map_err(PendingConnectionError::ConnectionLimit)
809793
})
810794
// Check expected peer id matches.
811795
.and_then(|()| {
812796
if let Some(peer) = expected_peer_id {
813-
if peer != peer_id {
814-
return Err(Error::InvalidPeerId);
797+
if peer != obtained_peer_id {
798+
Err(PendingConnectionError::WrongPeerId {
799+
obtained: obtained_peer_id,
800+
endpoint: endpoint.clone(),
801+
})
802+
} else {
803+
Ok(())
815804
}
805+
} else {
806+
Ok(())
816807
}
817-
Ok(())
818808
})
819809
// Check peer is not local peer.
820810
.and_then(|()| {
821-
if self.local_id == peer_id {
822-
Err(Error::InvalidPeerId)
811+
if self.local_id == obtained_peer_id {
812+
Err(PendingConnectionError::WrongPeerId {
813+
obtained: obtained_peer_id,
814+
endpoint: endpoint.clone(),
815+
})
823816
} else {
824817
Ok(())
825818
}
@@ -832,7 +825,7 @@ where
832825
log::debug!(
833826
"Failed to close connection {:?} to peer {}: {:?}",
834827
id,
835-
peer_id,
828+
obtained_peer_id,
836829
e
837830
);
838831
}
@@ -845,9 +838,10 @@ where
845838
ConnectedPoint::Dialer { .. } => {
846839
return Poll::Ready(PoolEvent::PendingOutboundConnectionError {
847840
id,
848-
error: error.into(),
841+
error: error
842+
.map(|t| vec![(endpoint.get_remote_address().clone(), t)]),
849843
handler,
850-
peer: Some(peer_id),
844+
peer: expected_peer_id.or(Some(obtained_peer_id)),
851845
})
852846
}
853847
ConnectedPoint::Listener {
@@ -856,7 +850,7 @@ where
856850
} => {
857851
return Poll::Ready(PoolEvent::PendingInboundConnectionError {
858852
id,
859-
error: error.into(),
853+
error,
860854
handler,
861855
send_back_addr,
862856
local_addr,
@@ -866,7 +860,7 @@ where
866860
}
867861

868862
// Add the connection to the pool.
869-
let conns = self.established.entry(peer_id).or_default();
863+
let conns = self.established.entry(obtained_peer_id).or_default();
870864
let other_established_connection_ids = conns.keys().cloned().collect();
871865
self.counters.inc_established(&endpoint);
872866

@@ -875,20 +869,23 @@ where
875869
conns.insert(
876870
id,
877871
EstablishedConnectionInfo {
878-
peer_id,
872+
peer_id: obtained_peer_id,
879873
endpoint: endpoint.clone(),
880874
sender: command_sender,
881875
},
882876
);
883877

884-
let connected = Connected { peer_id, endpoint };
878+
let connected = Connected {
879+
peer_id: obtained_peer_id,
880+
endpoint,
881+
};
885882

886883
let connection =
887884
super::Connection::new(muxer, handler.into_handler(&connected));
888885
self.spawn(
889886
task::new_for_established_connection(
890887
id,
891-
peer_id,
888+
obtained_peer_id,
892889
connection,
893890
command_receiver,
894891
self.established_connection_events_tx.clone(),

core/src/network.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ use crate::{
3737
Executor, Multiaddr, PeerId,
3838
};
3939
use either::Either;
40+
use multihash::Multihash;
4041
use std::{
4142
convert::TryFrom as _,
4243
error, fmt,
@@ -241,7 +242,7 @@ where
241242
.transpose()
242243
{
243244
Ok(peer_id) => peer_id,
244-
Err(_) => return Err(DialError::InvalidPeerId { handler }),
245+
Err(multihash) => return Err(DialError::InvalidPeerId { handler, multihash }),
245246
};
246247

247248
(
@@ -576,11 +577,10 @@ pub enum DialError<THandler> {
576577
handler: THandler,
577578
},
578579
/// The dialing attempt is rejected because the peer being dialed is the local peer.
579-
LocalPeerId {
580-
handler: THandler,
581-
},
580+
LocalPeerId { handler: THandler },
582581
InvalidPeerId {
583582
handler: THandler,
583+
multihash: Multihash,
584584
},
585585
}
586586

0 commit comments

Comments
 (0)