node: Make sure we properly disconnect outbounds
The previous change to the wire protocol introduced a bug: outbound peers that failed to connect fully would not notify the service on disconnect. This change fixes it.
This commit is contained in:
parent
e58419a9b0
commit
8858cefc89
|
|
@ -2205,6 +2205,12 @@ impl DisconnectReason {
|
||||||
pub fn is_connection_err(&self) -> bool {
|
pub fn is_connection_err(&self) -> bool {
|
||||||
matches!(self, Self::Connection(_))
|
matches!(self, Self::Connection(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn connection() -> Self {
|
||||||
|
DisconnectReason::Connection(Arc::new(std::io::Error::from(
|
||||||
|
std::io::ErrorKind::ConnectionReset,
|
||||||
|
)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for DisconnectReason {
|
impl fmt::Display for DisconnectReason {
|
||||||
|
|
|
||||||
|
|
@ -419,8 +419,10 @@ where
|
||||||
fn cleanup(&mut self, id: ResourceId, fd: RawFd) {
|
fn cleanup(&mut self, id: ResourceId, fd: RawFd) {
|
||||||
if self.inbound.remove(&fd).is_some() {
|
if self.inbound.remove(&fd).is_some() {
|
||||||
log::debug!(target: "wire", "Cleaning up inbound peer state with id={id} (fd={fd})");
|
log::debug!(target: "wire", "Cleaning up inbound peer state with id={id} (fd={fd})");
|
||||||
} else if self.outbound.remove(&fd).is_some() {
|
} else if let Some(outbound) = self.outbound.remove(&fd) {
|
||||||
log::debug!(target: "wire", "Cleaning up outbound peer state with id={id} (fd={fd})");
|
log::debug!(target: "wire", "Cleaning up outbound peer state with id={id} (fd={fd})");
|
||||||
|
self.service
|
||||||
|
.disconnected(outbound.nid, &DisconnectReason::connection());
|
||||||
} else {
|
} else {
|
||||||
log::warn!(target: "wire", "Tried to cleanup unknown peer with id={id} (fd={fd})");
|
log::warn!(target: "wire", "Tried to cleanup unknown peer with id={id} (fd={fd})");
|
||||||
}
|
}
|
||||||
|
|
@ -494,7 +496,7 @@ where
|
||||||
|
|
||||||
fn handle_registered(&mut self, fd: RawFd, id: ResourceId) {
|
fn handle_registered(&mut self, fd: RawFd, id: ResourceId) {
|
||||||
if let Some(outbound) = self.outbound.get_mut(&fd) {
|
if let Some(outbound) = self.outbound.get_mut(&fd) {
|
||||||
log::debug!(target: "wire", "Outbound peer resource registered with id={id} (fd={fd})");
|
log::debug!(target: "wire", "Outbound peer resource registered for {} with id={id} (fd={fd})", outbound.nid);
|
||||||
outbound.id = Some(id);
|
outbound.id = Some(id);
|
||||||
} else if let Some(inbound) = self.inbound.get_mut(&fd) {
|
} else if let Some(inbound) = self.inbound.get_mut(&fd) {
|
||||||
log::debug!(target: "wire", "Inbound peer resource registered with id={id} (fd={fd})");
|
log::debug!(target: "wire", "Inbound peer resource registered with id={id} (fd={fd})");
|
||||||
|
|
@ -673,28 +675,25 @@ where
|
||||||
// TODO: This should be a fatal error, there's nothing we can do here.
|
// TODO: This should be a fatal error, there's nothing we can do here.
|
||||||
log::error!(target: "wire", "Received error: listener {} disconnected", id);
|
log::error!(target: "wire", "Received error: listener {} disconnected", id);
|
||||||
}
|
}
|
||||||
reactor::Error::TransportDisconnect(id, session) => {
|
reactor::Error::TransportDisconnect(id, transport) => {
|
||||||
let fd = session.as_raw_fd();
|
let fd = transport.as_raw_fd();
|
||||||
log::error!(target: "wire", "Received error: peer id={id} (fd={fd}) disconnected");
|
log::error!(target: "wire", "Received error: peer id={id} (fd={fd}) disconnected");
|
||||||
|
|
||||||
// We're dropping the TCP connection here.
|
// We're dropping the TCP connection here.
|
||||||
drop(session);
|
drop(transport);
|
||||||
|
|
||||||
// The peer transport is already disconnected and removed from the reactor;
|
// The peer transport is already disconnected and removed from the reactor;
|
||||||
// therefore there is no need to initiate a disconnection. We simply remove
|
// therefore there is no need to initiate a disconnection. We simply remove
|
||||||
// the peer from the map.
|
// the peer from the map.
|
||||||
match self.peers.remove(&id) {
|
match self.peers.remove(&id) {
|
||||||
Some(mut peer) => {
|
Some(mut peer) => {
|
||||||
let reason = DisconnectReason::Connection(Arc::new(io::Error::from(
|
|
||||||
io::ErrorKind::ConnectionReset,
|
|
||||||
)));
|
|
||||||
|
|
||||||
if let Peer::Connected { streams, .. } = &mut peer {
|
if let Peer::Connected { streams, .. } = &mut peer {
|
||||||
streams.shutdown();
|
streams.shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(id) = peer.id() {
|
if let Some(id) = peer.id() {
|
||||||
self.service.disconnected(*id, &reason);
|
self.service
|
||||||
|
.disconnected(*id, &DisconnectReason::connection());
|
||||||
} else {
|
} else {
|
||||||
log::debug!(target: "wire", "Inbound disconnection before handshake; ignoring..")
|
log::debug!(target: "wire", "Inbound disconnection before handshake; ignoring..")
|
||||||
}
|
}
|
||||||
|
|
@ -795,6 +794,11 @@ where
|
||||||
NetTransport::<WireSession<G>>::with_session(session, Link::Outbound)
|
NetTransport::<WireSession<G>>::with_session(session, Link::Outbound)
|
||||||
}) {
|
}) {
|
||||||
Ok(transport) => {
|
Ok(transport) => {
|
||||||
|
log::debug!(
|
||||||
|
target: "wire",
|
||||||
|
"Registering transport for {node_id} (fd={})..",
|
||||||
|
transport.as_raw_fd()
|
||||||
|
);
|
||||||
self.outbound.insert(
|
self.outbound.insert(
|
||||||
transport.as_raw_fd(),
|
transport.as_raw_fd(),
|
||||||
Outbound {
|
Outbound {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue