Skip to content

Commit 327b62c

Browse files
committed
fix: WireGuard UDP socket not freed when disconnected
1 parent df50930 commit 327b62c

File tree

1 file changed

+17
-3
lines changed

1 file changed

+17
-3
lines changed

boltconn/src/transport/wireguard.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use std::io;
1515
use std::io::ErrorKind;
1616
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr};
1717
use std::sync::Arc;
18+
use std::time::Duration;
1819
use tokio::sync::Notify;
1920

2021
// We left AllowedIPs since it's boltconn that manages routing.
@@ -157,12 +158,16 @@ impl WireguardTunnel {
157158
let name = config.name.clone();
158159
local_async_run(async move {
159160
// dedicated to poll UDP from small kernel buffer
160-
loop {
161+
while !in_tx.is_disconnected() {
161162
let key = match pool.clone().create_owned() {
162163
Some(mut buf) => {
163164
let key = BufferIndex::Pool(buf.key());
164165
buf.resize(MAX_UDP_PKT_SIZE, 0);
165-
let Ok(len) = socket.recv(&mut buf).await else {
166+
let recv_result = tokio::select! {
167+
recv_result = socket.recv(&mut buf) => recv_result,
168+
_ = tokio::time::sleep(Duration::from_millis(500)) => continue,
169+
};
170+
let Ok(len) = recv_result else {
166171
tracing::warn!(
167172
"WireGuard #{} failed to receive from socket",
168173
name,
@@ -174,7 +179,11 @@ impl WireguardTunnel {
174179
}
175180
None => {
176181
let mut buf = vec![0; MAX_UDP_PKT_SIZE];
177-
let len = match socket.recv(&mut buf).await {
182+
let recv_result = tokio::select! {
183+
recv_result = socket.recv(&mut buf) => recv_result,
184+
_ = tokio::time::sleep(Duration::from_millis(500)) => continue,
185+
};
186+
let len = match recv_result {
178187
Ok(len) => len,
179188
Err(e) => {
180189
tracing::warn!(
@@ -190,9 +199,14 @@ impl WireguardTunnel {
190199
}
191200
};
192201
if let Err(err) = in_tx.try_send(key) {
202+
let is_disconnected =
203+
matches!(err, flume::TrySendError::Disconnected(_));
193204
if let BufferIndex::Pool(key) = err.into_inner() {
194205
pool.clear(key);
195206
}
207+
if is_disconnected {
208+
break;
209+
}
196210
tracing::warn!("channel full, dropping packet");
197211
}
198212
}

0 commit comments

Comments
 (0)