Skip to content

Commit 9b558e4

Browse files
committed
fix: eliminate sink removal race in send_to_tcp and send_to_tcp_sync
send_to_tcp previously removed the sink from tcp_punch before spawning a task, creating a window where a back-to-back call saw no entry and fell back to UDP (undeliverable for port-0 WebSocket peers). Replace the spawn with an inline await so the re-insert is atomic relative to the calling task and no concurrent caller can observe a missing entry. Apply the same re-insert-after-send fix to send_to_tcp_sync, which was also consuming the sink without putting it back.
1 parent fb8cc1a commit 9b558e4

1 file changed

Lines changed: 11 additions & 9 deletions

File tree

src/rendezvous_server.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -989,17 +989,16 @@ impl RendezvousServer {
989989

990990
#[inline]
991991
async fn send_to_tcp(&mut self, msg: RendezvousMessage, addr: SocketAddr) {
992-
let tcp_punch = self.tcp_punch.clone();
993992
let addr_v4 = try_into_v4(addr);
994-
let mut tcp = tcp_punch.lock().await.remove(&addr_v4);
993+
let mut tcp = self.tcp_punch.lock().await.remove(&addr_v4);
995994
if tcp.is_some() {
996-
tokio::spawn(async move {
997-
Self::send_to_sink(&mut tcp, msg).await;
998-
// Re-insert sink so this WebSocket peer can receive future messages
999-
if let Some(s) = tcp {
1000-
tcp_punch.lock().await.insert(addr_v4, s);
1001-
}
1002-
});
995+
Self::send_to_sink(&mut tcp, msg).await;
996+
// Re-insert sink so this WebSocket peer can receive future messages.
997+
// Done inline (no spawn) so there is no window where a concurrent send
998+
// sees the map entry missing and incorrectly falls back to UDP.
999+
if let Some(s) = tcp {
1000+
self.tcp_punch.lock().await.insert(addr_v4, s);
1001+
}
10031002
} else if addr.port() != 0 {
10041003
// Target not on a TCP/WS connection and has a real UDP port — fall back to UDP
10051004
self.tx.send(Data::Msg(msg.into(), addr)).ok();
@@ -1033,6 +1032,9 @@ impl RendezvousServer {
10331032
let mut sink = self.tcp_punch.lock().await.remove(&addr_v4);
10341033
if sink.is_some() {
10351034
Self::send_to_sink(&mut sink, msg).await;
1035+
if let Some(s) = sink {
1036+
self.tcp_punch.lock().await.insert(addr_v4, s);
1037+
}
10361038
} else if addr.port() != 0 {
10371039
self.tx.send(Data::Msg(msg.into(), addr)).ok();
10381040
}

0 commit comments

Comments
 (0)