Skip to content

Commit 9ca0d44

Browse files
authored
fix(upnp): panic during a shutdown process
upnp panics [here](https://github.com/libp2p/rust-libp2p/blob/8c8b3c3e174bcbc59055ee6694a5cfdbd8b6e7f2/protocols/upnp/src/behaviour.rs#L388) in case where the gateway state is `Searching` and the task executor is shutting down, since the [search_gateway](https://github.com/libp2p/rust-libp2p/blob/b187c14ef36744ea6b2f29740321b5fe896a50ef/protocols/upnp/src/tokio.rs#L99-L166) task is terminated and the sender channel has been dropped. [Here](https://gist.github.com/ackintosh/95f60bb1fee8865965adde5a6e1ee0eb) is an example code that reproduces the issue based on the upnp example, along with the corresponding [error message](https://gist.github.com/ackintosh/95f60bb1fee8865965adde5a6e1ee0eb?permalink_comment_id=5546913#gistcomment-5546913). Since this case is expected during shutdown, I believe upnp should avoid panicking and continue its operation. Pull-Request: #5998.
1 parent 1682bd5 commit 9ca0d44

File tree

2 files changed

+28
-20
lines changed

2 files changed

+28
-20
lines changed

protocols/upnp/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@
33
- update igd-next to 0.16.1
44
See [PR 5944](https://github.com/libp2p/rust-libp2p/pull/5944).
55

6+
- Fix panic during a shutdown process.
7+
See [PR 5998](https://github.com/libp2p/rust-libp2p/pull/5998).
8+
69
## 0.4.0
710

811
- update igd-next to 0.15.1.

protocols/upnp/src/behaviour.rs

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -384,28 +384,33 @@ impl NetworkBehaviour for Behaviour {
384384
loop {
385385
match self.state {
386386
GatewayState::Searching(ref mut fut) => match Pin::new(fut).poll(cx) {
387-
Poll::Ready(result) => {
388-
match result.expect("sender shouldn't have been dropped") {
389-
Ok(gateway) => {
390-
if !is_addr_global(gateway.external_addr) {
391-
self.state =
392-
GatewayState::NonRoutableGateway(gateway.external_addr);
393-
tracing::debug!(
394-
gateway_address=%gateway.external_addr,
395-
"the gateway is not routable"
396-
);
397-
return Poll::Ready(ToSwarm::GenerateEvent(
398-
Event::NonRoutableGateway,
399-
));
400-
}
401-
self.state = GatewayState::Available(gateway);
402-
}
403-
Err(err) => {
404-
tracing::debug!("could not find gateway: {err}");
405-
self.state = GatewayState::GatewayNotFound;
406-
return Poll::Ready(ToSwarm::GenerateEvent(Event::GatewayNotFound));
387+
Poll::Ready(Ok(result)) => match result {
388+
Ok(gateway) => {
389+
if !is_addr_global(gateway.external_addr) {
390+
self.state =
391+
GatewayState::NonRoutableGateway(gateway.external_addr);
392+
tracing::debug!(
393+
gateway_address=%gateway.external_addr,
394+
"the gateway is not routable"
395+
);
396+
return Poll::Ready(ToSwarm::GenerateEvent(
397+
Event::NonRoutableGateway,
398+
));
407399
}
400+
self.state = GatewayState::Available(gateway);
401+
}
402+
Err(err) => {
403+
tracing::debug!("could not find gateway: {err}");
404+
self.state = GatewayState::GatewayNotFound;
405+
return Poll::Ready(ToSwarm::GenerateEvent(Event::GatewayNotFound));
408406
}
407+
},
408+
Poll::Ready(Err(err)) => {
409+
// The sender channel has been dropped. This typically indicates a shutdown
410+
// process is underway.
411+
tracing::debug!("sender has been dropped: {err}");
412+
self.state = GatewayState::GatewayNotFound;
413+
return Poll::Ready(ToSwarm::GenerateEvent(Event::GatewayNotFound));
409414
}
410415
Poll::Pending => return Poll::Pending,
411416
},

0 commit comments

Comments
 (0)