From 35e00c300f83a7c8e48c894aaa6b2bb67a762c53 Mon Sep 17 00:00:00 2001 From: Richard Russo Date: Wed, 11 Sep 2024 14:48:05 -0700 Subject: [PATCH] Group Calls: Allow connection to a TCP+TLS server candidate --- bin/fetch-artifact.py | 16 +++++------ config/version.properties | 2 +- src/rust/src/core/group_call.rs | 32 ++++++++++++++++++++-- src/rust/src/lite/sfu.rs | 24 +++++++++++++--- src/rust/src/webrtc/ffi/peer_connection.rs | 1 + src/rust/src/webrtc/peer_connection.rs | 29 ++++++++++++++++++-- src/rust/src/webrtc/sim/peer_connection.rs | 1 + 7 files changed, 87 insertions(+), 18 deletions(-) diff --git a/bin/fetch-artifact.py b/bin/fetch-artifact.py index ee1e1c70..41207dd9 100755 --- a/bin/fetch-artifact.py +++ b/bin/fetch-artifact.py @@ -18,14 +18,14 @@ UNVERIFIED_DOWNLOAD_NAME = "unverified.tmp" PREBUILD_CHECKSUMS = { - 'android': 'a1168d21eb5fda99ce535af8e61328f3eb18ec50fce0645059dc9c40b9f3c394', - 'ios': '0147f5884900ad4004f890b01bacaef8fc26c6c2016bf95864a80403efbb3c24', - 'linux-arm64': '649d1bbc0b40ad01452358121fe08c4cef9140dd180fe8519683d301f52fd571', - 'linux-x64': '39cab9e957d1b473e3b6920af6b8f23bb5d4c9b7a1097fb8480c07ba0a0d5aea', - 'mac-arm64': 'a8038bfbb4398c3c0b1912640cd5135e8a4e5064850e80ffe04012f155351c56', - 'mac-x64': 'c29e5bd97d8f106e7d48f4a9745c8e0eae090ecf0f60501ac46e5232b61e1e9e', - 'windows-arm64': 'c0086071f463d7733700750ddc86b72310c94d3b24659874d8cabba0c6dfd644', - 'windows-x64': '894cb01676c86ccde7807be97c72c89e3d95ee1adedc1920f8f66a33cff88006', + 'android': '117648e2bbd3c5614feb5ddc91142b3f4cc845aaeb22a1dc3183fc793600fd02', + 'ios': '2a5c6106091050bd67251a59dcc8af6678f7896083ddd27d10a88ca7d0a9f72d', + 'linux-arm64': 'c417d43b1d4322187e98dd3b77b20d369131e27020821771625137858fd92ba4', + 'linux-x64': '91f6003d8ee76c03fd369333bb54efb5b4b2f61664cb9447048556478d6fbcc7', + 'mac-arm64': '23c3b38462fb71917434de48d8504407c09f2c7a47b177a693ecdc38fdfe9abb', + 'mac-x64': 'fe27c4d8aa85fedf22060e20cbc1734f999ee81820ab7b2fa9a8bca12a7ff670', + 'windows-arm64': '78b8a4b7b2b132e4b5321569b4ef58caec344fa62e9df1a165e343a3efa40795', + 'windows-x64': 'cb9e5e6603b00345fdca701699248a3b93f4499ab496f67586545d2242c60f7b', } diff --git a/config/version.properties b/config/version.properties index b56d0144..7b3de8e2 100644 --- a/config/version.properties +++ b/config/version.properties @@ -1,4 +1,4 @@ -webrtc.version=6613a +webrtc.version=6613b ringrtc.version.major=2 ringrtc.version.minor=47 diff --git a/src/rust/src/core/group_call.rs b/src/rust/src/core/group_call.rs index 2f224033..50eaae58 100644 --- a/src/rust/src/core/group_call.rs +++ b/src/rust/src/core/group_call.rs @@ -49,7 +49,7 @@ use crate::{ media::{ AudioEncoderConfig, AudioTrack, VideoFrame, VideoFrameMetadata, VideoSink, VideoTrack, }, - peer_connection::{AudioLevel, PeerConnection, ReceivedAudioLevel, SendRates}, + peer_connection::{AudioLevel, PeerConnection, Protocol, ReceivedAudioLevel, SendRates}, peer_connection_factory::{self as pcf, AudioJitterBufferConfig, PeerConnectionFactory}, peer_connection_observer::{ IceConnectionState, NetworkRoute, PeerConnectionObserver, PeerConnectionObserverTrait, @@ -451,6 +451,8 @@ impl DheState { pub struct SfuInfo { pub udp_addresses: Vec, pub tcp_addresses: Vec, + pub tls_addresses: Vec, + pub hostname: Option, pub ice_ufrag: String, pub ice_pwd: String, } @@ -575,6 +577,8 @@ impl HttpSfuClient { sfu_info: SfuInfo { udp_addresses: join_response.server_udp_addresses, tcp_addresses: join_response.server_tcp_addresses, + tls_addresses: join_response.server_tls_addresses, + hostname: join_response.server_hostname, ice_ufrag: join_response.server_ice_ufrag, ice_pwd: join_response.server_ice_pwd, }, @@ -2647,7 +2651,7 @@ impl Client { state.peer_connection.add_ice_candidate_from_server( addr.ip(), addr.port(), - false, /* tcp */ + Protocol::Udp, )?; } @@ -2664,10 +2668,30 @@ impl Client { state.peer_connection.add_ice_candidate_from_server( addr.ip(), addr.port(), - true, /* tcp */ + Protocol::Tcp, )?; } + for addr in &sfu_info.tls_addresses { + if let Some(hostname) = &sfu_info.hostname { + // We use the octets instead of to_string() to bypass the IP address logging filter. + info!( + "Connecting to group call SFU via TLS with ip={:?} port={} hostname={}", + match addr.ip() { + std::net::IpAddr::V4(v4) => v4.octets().to_vec(), + std::net::IpAddr::V6(v6) => v6.octets().to_vec(), + }, + addr.port(), + &hostname + ); + state.peer_connection.add_ice_candidate_from_server( + addr.ip(), + addr.port(), + Protocol::Tls(hostname), + )?; + } + } + if state .peer_connection .receive_rtp(RTP_DATA_PAYLOAD_TYPE, true) @@ -4592,6 +4616,8 @@ mod tests { sfu_info: SfuInfo { udp_addresses: Vec::new(), tcp_addresses: Vec::new(), + tls_addresses: Vec::new(), + hostname: None, ice_ufrag: "fake ICE ufrag".to_string(), ice_pwd: "fake ICE pwd".to_string(), }, diff --git a/src/rust/src/lite/sfu.rs b/src/rust/src/lite/sfu.rs index f27b274a..7663b817 100644 --- a/src/rust/src/lite/sfu.rs +++ b/src/rust/src/lite/sfu.rs @@ -173,6 +173,10 @@ struct SerializedJoinResponse { server_port: u16, #[serde(rename = "portTcp")] server_port_tcp: u16, + #[serde(rename = "portTls", default)] + server_port_tls: Option, + #[serde(rename = "hostname", default)] + server_hostname: Option, #[serde(rename = "iceUfrag")] server_ice_ufrag: String, #[serde(rename = "icePwd")] @@ -184,7 +188,7 @@ struct SerializedJoinResponse { #[serde(rename = "conferenceId")] era_id: String, #[serde(rename = "clientStatus")] - client_status: Option, + client_status: String, } #[derive(PartialEq, Eq, Debug)] @@ -215,6 +219,8 @@ pub struct JoinResponse { pub client_demux_id: u32, pub server_udp_addresses: Vec, pub server_tcp_addresses: Vec, + pub server_tls_addresses: Vec, + pub server_hostname: Option, pub server_ice_ufrag: String, pub server_ice_pwd: String, pub server_dhe_pub_key: [u8; 32], @@ -236,19 +242,29 @@ impl JoinResponse { .iter() .map(|ip| SocketAddr::new(*ip, deserialized.server_port_tcp)) .collect(); + let server_tls_addresses = deserialized + .server_port_tls + .map_or(vec![], |server_port_tls| { + deserialized + .server_ips + .iter() + .map(|ip| SocketAddr::new(*ip, server_port_tls)) + .collect() + }); Self { client_demux_id: deserialized.client_demux_id, server_udp_addresses, server_tcp_addresses, + server_tls_addresses, + server_hostname: deserialized.server_hostname, server_ice_ufrag: deserialized.server_ice_ufrag, server_ice_pwd: deserialized.server_ice_pwd, server_dhe_pub_key: deserialized.server_dhe_pub_key, call_creator: member_resolver.resolve(&deserialized.call_creator), era_id: deserialized.era_id, - client_status: deserialized - .client_status - .and_then(|cs| ClientStatus::from_str(&cs).ok()) + client_status: ClientStatus::from_str(&deserialized.client_status) + .ok() .unwrap_or(ClientStatus::Pending), } } diff --git a/src/rust/src/webrtc/ffi/peer_connection.rs b/src/rust/src/webrtc/ffi/peer_connection.rs index a0089c83..0e1231bb 100644 --- a/src/rust/src/webrtc/ffi/peer_connection.rs +++ b/src/rust/src/webrtc/ffi/peer_connection.rs @@ -87,6 +87,7 @@ extern "C" { ip: RffiIp, port: u16, tcp: bool, + hostname: webrtc::ptr::Borrowed, ) -> bool; pub fn Rust_removeIceCandidates( diff --git a/src/rust/src/webrtc/peer_connection.rs b/src/rust/src/webrtc/peer_connection.rs index 802dd856..52364abc 100644 --- a/src/rust/src/webrtc/peer_connection.rs +++ b/src/rust/src/webrtc/peer_connection.rs @@ -77,6 +77,12 @@ pub struct RffiReceivedAudioLevel { pub type AudioLevel = RffiAudioLevel; pub type ReceivedAudioLevel = RffiReceivedAudioLevel; +pub enum Protocol<'a> { + Udp, + Tcp, + Tls(&'a str), +} + impl PeerConnection { pub fn new( rffi: webrtc::Arc, @@ -209,11 +215,30 @@ impl PeerConnection { &self, ip: std::net::IpAddr, port: u16, - tcp: bool, + protocol: Protocol, ) -> Result<()> { + let (tcp, hostname_c) = match protocol { + Protocol::Udp => (false, None), + Protocol::Tcp => (true, None), + Protocol::Tls(hostname) => (true, Some(CString::new(hostname)?)), + }; + let add_ok = unsafe { - pc::Rust_addIceCandidateFromServer(self.rffi.as_borrowed(), ip.into(), port, tcp) + let hostname_ptr = hostname_c + .as_ref() + .map_or(webrtc::ptr::Borrowed::null(), |h| { + webrtc::ptr::Borrowed::from_ptr(h.as_ptr()) + }); + + pc::Rust_addIceCandidateFromServer( + self.rffi.as_borrowed(), + ip.into(), + port, + tcp, + hostname_ptr, + ) }; + if add_ok { Ok(()) } else { diff --git a/src/rust/src/webrtc/sim/peer_connection.rs b/src/rust/src/webrtc/sim/peer_connection.rs index a43b90bb..eeec5078 100644 --- a/src/rust/src/webrtc/sim/peer_connection.rs +++ b/src/rust/src/webrtc/sim/peer_connection.rs @@ -236,6 +236,7 @@ pub unsafe fn Rust_addIceCandidateFromServer( _ip: RffiIp, _port: u16, _tcp: bool, + _hostname: webrtc::ptr::Borrowed, ) -> bool { info!("Rust_addIceCandidateFromServer():"); true