diff --git a/src/client.rs b/src/client.rs index 10330cfd6..4997a3f65 100644 --- a/src/client.rs +++ b/src/client.rs @@ -825,7 +825,14 @@ impl Client { }; let switch_code = interface.get_switch_code(); - if !key.is_empty() && (!token.is_empty() || !switch_code.is_empty()) { + // With an offer this socket also carries both sides' ICE candidates, every interface + // address of both machines, so it is encrypted whenever a key is configured. Only a + // server that forwards offers is ever sent one, and such a server does the exchange. + let carries_offer = webrtc_offerer + .as_ref() + .and_then(|g| g.stream()) + .is_some(); + if !key.is_empty() && (!token.is_empty() || !switch_code.is_empty() || carries_offer) { secure_tcp(&mut socket, &key) .await .map_err(|e| anyhow!("Failed to secure tcp: {}", e))?; diff --git a/src/rendezvous_mediator.rs b/src/rendezvous_mediator.rs index 0436f060a..895e0ee6a 100644 --- a/src/rendezvous_mediator.rs +++ b/src/rendezvous_mediator.rs @@ -806,6 +806,7 @@ impl RendezvousMediator { // trickle, and TCP reliability replaces the old 400ms duplicate re-send // (the controller keeps its own re-send for the server->peer UDP downlink). let mut conn = None; + let key = crate::get_key(true).await; while let Some(candidate) = local_ice_rx.recv().await { let mut msg = Message::new(); msg.set_ice_candidate(IceCandidate { @@ -819,7 +820,18 @@ impl RendezvousMediator { for _ in 0..2 { if conn.is_none() { match connect_tcp(&*host, CONNECT_TIMEOUT).await { - Ok(s) => conn = Some(s), + Ok(mut s) => { + // Candidates are every interface address of this machine; + // the server that routes them does the key exchange. + if let Err(err) = crate::secure_tcp(&mut s, &key).await { + log::warn!( + "failed to secure the WebRTC ICE candidate connection: {}", + err + ); + break; + } + conn = Some(s); + } Err(err) => { log::warn!( "failed to connect for WebRTC ICE candidate: {}", @@ -993,6 +1005,7 @@ impl RendezvousMediator { let mut msg_out = Message::new(); msg_out.set_punch_hole_sent(msg_punch); let mut socket = connect_tcp(&*self.host, CONNECT_TIMEOUT).await?; + crate::secure_tcp(&mut socket, &crate::get_key(true).await).await?; socket.send(&msg_out).await?; return Ok(()); }