fix(connlib): fuse event-loop future inside client session (#10399)

A `Future` in Rust should not be polled once it has been completed as
that may lead to panics or otherwise undesirable behaviour. To avoid
this, a `Future` can be `fuse`d which will make it return
`Poll::Pending` indefinitely after it has returned `Ready`.

We have received several Sentry alerts of poll-after-completion panics
that I believe are all stemming from this particular code.
This commit is contained in:
Thomas Eizinger
2025-09-20 12:35:32 +00:00
committed by GitHub
parent 88e801ad97
commit 7c326e003e

View File

@@ -8,6 +8,7 @@ pub use firezone_tunnel::messages::client::{IngressMessages, ResourceDescription
use anyhow::Result;
use connlib_model::{ResourceId, ResourceView};
use eventloop::{Command, Eventloop};
use futures::future::Fuse;
use futures::{FutureExt, StreamExt};
use phoenix_channel::{PhoenixChannel, PublicKeyParam};
use socket_factory::{SocketFactory, TcpSocket, UdpSocket};
@@ -38,7 +39,7 @@ pub struct Session {
#[derive(Debug)]
pub struct EventStream {
eventloop: JoinHandle<Result<(), DisconnectError>>,
eventloop: Fuse<JoinHandle<Result<(), DisconnectError>>>,
resource_list_receiver: WatchStream<Vec<ResourceView>>,
tun_config_receiver: WatchStream<Option<TunConfig>>,
}
@@ -81,7 +82,7 @@ impl Session {
(
Self { channel: cmd_tx },
EventStream {
eventloop,
eventloop: eventloop.fuse(),
resource_list_receiver: WatchStream::from_changes(resource_list_receiver),
tun_config_receiver: WatchStream::from_changes(tun_config_receiver),
},