Skip to content

Commit 37f3ef5

Browse files
authored
[bugfix] Tunnel not waiting on MixnetClient to shut down cleanly (#6225)
* return the handlefor a clean shutdown * cargo lock
1 parent 1a4d64a commit 37f3ef5

File tree

2 files changed

+77
-44
lines changed

2 files changed

+77
-44
lines changed

Cargo.lock

Lines changed: 7 additions & 7 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

nym-registration-client/src/lib.rs

Lines changed: 70 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
use tokio_util::sync::CancellationToken;
55

6-
use nym_authenticator_client::{AuthClientMixnetListener, AuthenticatorClient};
6+
use nym_authenticator_client::{
7+
AuthClientMixnetListener, AuthClientMixnetListenerHandle, AuthenticatorClient,
8+
};
79
use nym_bandwidth_controller::BandwidthTicketProvider;
810
use nym_credentials_interface::TicketType;
911
use nym_ip_packet_client::IprClientConnect;
@@ -35,9 +37,22 @@ pub struct RegistrationClient {
3537
event_rx: EventReceiver,
3638
}
3739

40+
enum MixnetClientHandle {
41+
Authenticator(AuthClientMixnetListenerHandle),
42+
Sdk(Box<MixnetClient>),
43+
}
44+
45+
impl MixnetClientHandle {
46+
async fn stop(self) {
47+
match self {
48+
Self::Authenticator(handle) => handle.stop().await,
49+
Self::Sdk(handle) => handle.disconnect().await,
50+
}
51+
}
52+
}
3853
// Bundle of an actual error and the underlying mixnet client so it can be shutdown correctly if needed
3954
struct RegistrationError {
40-
mixnet_client: Option<MixnetClient>,
55+
mixnet_client_handle: MixnetClientHandle,
4156
source: crate::RegistrationClientError,
4257
}
4358

@@ -49,7 +64,7 @@ impl RegistrationClient {
4964

5065
let Some(ipr_address) = self.config.exit.node.ipr_address else {
5166
return Err(RegistrationError {
52-
mixnet_client: Some(self.mixnet_client),
67+
mixnet_client_handle: MixnetClientHandle::Sdk(Box::new(self.mixnet_client)),
5368
source: RegistrationClientError::NoIpPacketRouterAddress {
5469
node_id: self.config.exit.node.identity.to_base58_string(),
5570
},
@@ -67,13 +82,17 @@ impl RegistrationClient {
6782
Some(Ok(addr)) => addr,
6883
Some(Err(e)) => {
6984
return Err(RegistrationError {
70-
mixnet_client: Some(ipr_client.into_mixnet_client()),
85+
mixnet_client_handle: MixnetClientHandle::Sdk(Box::new(
86+
ipr_client.into_mixnet_client(),
87+
)),
7188
source: RegistrationClientError::ConnectToIpPacketRouter(e),
7289
});
7390
}
7491
None => {
7592
return Err(RegistrationError {
76-
mixnet_client: Some(ipr_client.into_mixnet_client()),
93+
mixnet_client_handle: MixnetClientHandle::Sdk(Box::new(
94+
ipr_client.into_mixnet_client(),
95+
)),
7796
source: RegistrationClientError::Cancelled,
7897
});
7998
}
@@ -97,7 +116,7 @@ impl RegistrationClient {
97116
async fn register_wg(self) -> Result<RegistrationResult, RegistrationError> {
98117
let Some(entry_auth_address) = self.config.entry.node.authenticator_address else {
99118
return Err(RegistrationError {
100-
mixnet_client: Some(self.mixnet_client),
119+
mixnet_client_handle: MixnetClientHandle::Sdk(Box::new(self.mixnet_client)),
101120
source: RegistrationClientError::AuthenticationNotPossible {
102121
node_id: self.config.entry.node.identity.to_base58_string(),
103122
},
@@ -106,7 +125,7 @@ impl RegistrationClient {
106125

107126
let Some(exit_auth_address) = self.config.exit.node.authenticator_address else {
108127
return Err(RegistrationError {
109-
mixnet_client: Some(self.mixnet_client),
128+
mixnet_client_handle: MixnetClientHandle::Sdk(Box::new(self.mixnet_client)),
110129
source: RegistrationClientError::AuthenticationNotPossible {
111130
node_id: self.config.exit.node.identity.to_base58_string(),
112131
},
@@ -150,35 +169,50 @@ impl RegistrationClient {
150169
let exit_fut = exit_auth_client
151170
.register_wireguard(&*self.bandwidth_controller, TicketType::V1WireguardExit);
152171

153-
let (entry, exit) = Box::pin(
172+
let (entry, exit) = match Box::pin(
154173
self.cancel_token
155174
.run_until_cancelled(async { tokio::join!(entry_fut, exit_fut) }),
156175
)
157176
.await
158-
.ok_or(RegistrationError {
159-
mixnet_client: None,
160-
source: RegistrationClientError::Cancelled,
161-
})?;
162-
163-
let entry = entry.map_err(|source| RegistrationError {
164-
mixnet_client: None,
165-
source: RegistrationClientError::from_authenticator_error(
166-
source,
167-
self.config.entry.node.identity.to_base58_string(),
168-
entry_auth_address,
169-
true,
170-
),
171-
})?;
172-
173-
let exit = exit.map_err(|source| RegistrationError {
174-
mixnet_client: None,
175-
source: RegistrationClientError::from_authenticator_error(
176-
source,
177-
self.config.exit.node.identity.to_base58_string(),
178-
exit_auth_address,
179-
false,
180-
),
181-
})?;
177+
{
178+
Some((entry, exit)) => (entry, exit),
179+
None => {
180+
return Err(RegistrationError {
181+
mixnet_client_handle: MixnetClientHandle::Authenticator(mixnet_listener),
182+
source: RegistrationClientError::Cancelled,
183+
});
184+
}
185+
};
186+
187+
let entry = match entry {
188+
Ok(entry) => entry,
189+
Err(source) => {
190+
return Err(RegistrationError {
191+
mixnet_client_handle: MixnetClientHandle::Authenticator(mixnet_listener),
192+
source: RegistrationClientError::from_authenticator_error(
193+
source,
194+
self.config.entry.node.identity.to_base58_string(),
195+
entry_auth_address,
196+
true,
197+
),
198+
});
199+
}
200+
};
201+
202+
let exit = match exit {
203+
Ok(exit) => exit,
204+
Err(source) => {
205+
return Err(RegistrationError {
206+
mixnet_client_handle: MixnetClientHandle::Authenticator(mixnet_listener),
207+
source: RegistrationClientError::from_authenticator_error(
208+
source,
209+
self.config.exit.node.identity.to_base58_string(),
210+
exit_auth_address,
211+
false,
212+
),
213+
});
214+
}
215+
};
182216

183217
Ok(RegistrationResult::Wireguard(Box::new(
184218
WireguardRegistrationResult {
@@ -199,15 +233,14 @@ impl RegistrationClient {
199233
self.register_mix_exit().await
200234
};
201235

202-
// If we failed to register, and we were the owner of the mixnet client, shut it down
236+
// If we failed to register, shut down the mixnet client and wait for it to exit
203237
match registration_result {
204238
Ok(result) => Ok(result),
205239
Err(error) => {
206240
debug!("Registration failed");
207-
if let Some(mixnet_client) = error.mixnet_client {
208-
debug!("Shutting down mixnet client");
209-
mixnet_client.disconnect().await;
210-
}
241+
debug!("Shutting down mixnet client");
242+
error.mixnet_client_handle.stop().await;
243+
debug!("Mixnet client stopped");
211244
Err(error.source)
212245
}
213246
}

0 commit comments

Comments
 (0)