Skip to content

Commit 744ac18

Browse files
author
Rain
authored
Merge pull request #7 from algesten/close
close util::Conn connection on .close()
2 parents efba9c9 + 7227a2d commit 744ac18

File tree

7 files changed

+68
-25
lines changed

7 files changed

+68
-25
lines changed

crates/turn/examples/turn_server_udp.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ async fn main() -> Result<()> {
109109
let conn = Arc::new(UdpSocket::bind(format!("0.0.0.0:{}", port)).await?);
110110
println!("listening {}...", conn.local_addr()?);
111111

112-
let server = Server::new(ServerConfig {
112+
let mut server = Server::new(ServerConfig {
113113
conn_configs: vec![ConnConfig {
114114
conn,
115115
relay_addr_generator: Box::new(RelayAddressGeneratorStatic {
@@ -127,7 +127,7 @@ async fn main() -> Result<()> {
127127
println!("Waiting for Ctrl-C...");
128128
signal::ctrl_c().await.expect("failed to listen for event");
129129
println!("\nClosing connection now...");
130-
server.close()?;
130+
server.close().await?;
131131

132132
Ok(())
133133
}

crates/turn/src/allocation/allocation_manager/allocation_manager_test.rs

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -237,17 +237,30 @@ async fn test_allocation_timeout() -> Result<()> {
237237
allocations.push(a);
238238
}
239239

240-
tokio::time::sleep(lifetime + Duration::from_millis(100)).await;
240+
let mut count = 0;
241241

242-
for allocation in allocations {
243-
let mut a = allocation.lock().await;
244-
assert!(
245-
a.close().await.is_err(),
246-
"Allocation should be closed if lifetime timeout"
247-
);
248-
}
242+
'outer: loop {
243+
count += 1;
249244

250-
Ok(())
245+
if count >= 10 {
246+
assert!(false, "Allocations didn't timeout");
247+
}
248+
249+
tokio::time::sleep(lifetime + Duration::from_millis(100)).await;
250+
251+
let any_outstanding = false;
252+
253+
for allocation in &allocations {
254+
let mut a = allocation.lock().await;
255+
if !a.close().await.is_err() {
256+
continue 'outer;
257+
}
258+
}
259+
260+
if !any_outstanding {
261+
return Ok(());
262+
}
263+
}
251264
}
252265

253266
#[tokio::test]

crates/turn/src/allocation/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,9 @@ impl Allocation {
199199

200200
log::trace!("allocation with {} closed!", self.five_tuple);
201201

202+
let _ = self.turn_socket.close().await;
203+
let _ = self.relay_socket.close().await;
204+
202205
Ok(())
203206
}
204207

crates/turn/src/auth/auth_test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ async fn test_new_long_term_auth_handler() -> Result<()> {
5757
let conn = Arc::new(UdpSocket::bind("0.0.0.0:0").await?);
5858
let server_port = conn.local_addr()?.port();
5959

60-
let server = Server::new(ServerConfig {
60+
let mut server = Server::new(ServerConfig {
6161
conn_configs: vec![ConnConfig {
6262
conn,
6363
relay_addr_generator: Box::new(RelayAddressGeneratorStatic {
@@ -97,7 +97,7 @@ async fn test_new_long_term_auth_handler() -> Result<()> {
9797
let _allocation = client.allocate().await?;
9898

9999
client.close().await?;
100-
server.close()?;
100+
server.close().await?;
101101

102102
Ok(())
103103
}

crates/turn/src/client/client_test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ async fn test_client_nonce_expiration() -> Result<()> {
138138
let conn = Arc::new(UdpSocket::bind("0.0.0.0:0").await?);
139139
let server_port = conn.local_addr()?.port();
140140

141-
let server = Server::new(ServerConfig {
141+
let mut server = Server::new(ServerConfig {
142142
conn_configs: vec![ConnConfig {
143143
conn,
144144
relay_addr_generator: Box::new(RelayAddressGeneratorStatic {
@@ -183,7 +183,7 @@ async fn test_client_nonce_expiration() -> Result<()> {
183183

184184
// Shutdown
185185
client.close().await?;
186-
server.close()?;
186+
server.close().await?;
187187

188188
Ok(())
189189
}

crates/turn/src/server/mod.rs

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use request::*;
1313
use anyhow::Result;
1414
use std::collections::HashMap;
1515
use std::sync::Arc;
16-
use tokio::sync::Mutex;
16+
use tokio::sync::{watch, Mutex};
1717
use tokio::time::{Duration, Instant};
1818
use util::Conn;
1919

@@ -25,18 +25,22 @@ pub struct Server {
2525
realm: String,
2626
channel_bind_timeout: Duration,
2727
pub(crate) nonces: Arc<Mutex<HashMap<String, Instant>>>,
28+
shutdown_tx: Option<watch::Sender<bool>>,
2829
}
2930

3031
impl Server {
3132
// creates the TURN server
3233
pub async fn new(config: ServerConfig) -> Result<Self> {
3334
config.validate()?;
3435

36+
let (shutdown_tx, shutdown_rx) = watch::channel(false);
37+
3538
let mut s = Server {
3639
auth_handler: config.auth_handler,
3740
realm: config.realm,
3841
channel_bind_timeout: config.channel_bind_timeout,
3942
nonces: Arc::new(Mutex::new(HashMap::new())),
43+
shutdown_tx: Some(shutdown_tx),
4044
};
4145

4246
if s.channel_bind_timeout == Duration::from_secs(0) {
@@ -48,6 +52,7 @@ impl Server {
4852
let auth_handler = Arc::clone(&s.auth_handler);
4953
let realm = s.realm.clone();
5054
let channel_bind_timeout = s.channel_bind_timeout;
55+
let shutdown_rx = shutdown_rx.clone();
5156

5257
tokio::spawn(async move {
5358
let allocation_manager = Arc::new(Manager::new(ManagerConfig {
@@ -61,6 +66,7 @@ impl Server {
6166
auth_handler,
6267
realm,
6368
channel_bind_timeout,
69+
shutdown_rx,
6470
)
6571
.await;
6672
});
@@ -76,16 +82,29 @@ impl Server {
7682
auth_handler: Arc<Box<dyn AuthHandler + Send + Sync>>,
7783
realm: String,
7884
channel_bind_timeout: Duration,
85+
mut shutdown_rx: watch::Receiver<bool>,
7986
) {
8087
let mut buf = vec![0u8; INBOUND_MTU];
8188

8289
loop {
83-
//TODO: gracefully exit loop
84-
let (n, addr) = match conn.recv_from(&mut buf).await {
85-
Ok((n, addr)) => (n, addr),
86-
Err(err) => {
87-
log::debug!("exit read loop on error: {}", err);
88-
break;
90+
let (n, addr) = tokio::select! {
91+
v = conn.recv_from(&mut buf) => {
92+
match v {
93+
Ok(v) => v,
94+
Err(err) => {
95+
log::debug!("exit read loop on error: {}", err);
96+
break;
97+
}
98+
}
99+
},
100+
did_change = shutdown_rx.changed() => {
101+
if did_change.is_err() || *shutdown_rx.borrow() {
102+
// if did_change.is_err, sender was dropped, or if
103+
// bool is set to true, that means we're shutting down.
104+
break
105+
} else {
106+
continue;
107+
}
89108
}
90109
};
91110

@@ -106,10 +125,18 @@ impl Server {
106125
}
107126

108127
let _ = allocation_manager.close().await;
128+
let _ = conn.close().await;
109129
}
110130

111131
// Close stops the TURN Server. It cleans up any associated state and closes all connections it is managing
112-
pub fn close(&self) -> Result<()> {
132+
pub async fn close(&mut self) -> Result<()> {
133+
if let Some(tx) = self.shutdown_tx.take() {
134+
// errors if there are no receivers, but that's irrelevant.
135+
let _ = tx.send(true);
136+
// wait for all receivers to drop/close.
137+
let _ = tx.closed().await;
138+
}
139+
113140
Ok(())
114141
}
115142
}

crates/turn/src/server/server_test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ async fn test_server_simple() -> Result<()> {
4646
let conn = Arc::new(UdpSocket::bind("0.0.0.0:0").await?);
4747
let server_port = conn.local_addr()?.port();
4848

49-
let server = Server::new(ServerConfig {
49+
let mut server = Server::new(ServerConfig {
5050
conn_configs: vec![ConnConfig {
5151
conn,
5252
relay_addr_generator: Box::new(RelayAddressGeneratorStatic {
@@ -88,7 +88,7 @@ async fn test_server_simple() -> Result<()> {
8888
.await?;
8989

9090
client.close().await?;
91-
server.close()?;
91+
server.close().await?;
9292

9393
Ok(())
9494
}

0 commit comments

Comments
 (0)