add ice-servers config

This commit is contained in:
lc
2025-11-16 18:43:31 +08:00
parent 0da5d379fc
commit 7cb29b1117
3 changed files with 61 additions and 27 deletions

View File

@@ -2550,6 +2550,7 @@ pub mod keys {
pub const OPTION_TRACKPAD_SPEED: &str = "trackpad-speed"; pub const OPTION_TRACKPAD_SPEED: &str = "trackpad-speed";
pub const OPTION_REGISTER_DEVICE: &str = "register-device"; pub const OPTION_REGISTER_DEVICE: &str = "register-device";
pub const OPTION_RELAY_SERVER: &str = "relay-server"; pub const OPTION_RELAY_SERVER: &str = "relay-server";
pub const OPTION_ICE_SERVERS: &str = "ice-servers";
pub const OPTION_DISABLE_UDP: &str = "disable-udp"; pub const OPTION_DISABLE_UDP: &str = "disable-udp";
pub const OPTION_ALLOW_INSECURE_TLS_FALLBACK: &str = "allow-insecure-tls-fallback"; pub const OPTION_ALLOW_INSECURE_TLS_FALLBACK: &str = "allow-insecure-tls-fallback";
pub const OPTION_SHOW_VIRTUAL_MOUSE: &str = "show-virtual-mouse"; pub const OPTION_SHOW_VIRTUAL_MOUSE: &str = "show-virtual-mouse";
@@ -2746,6 +2747,7 @@ pub mod keys {
OPTION_ENABLE_ANDROID_SOFTWARE_ENCODING_HALF_SCALE, OPTION_ENABLE_ANDROID_SOFTWARE_ENCODING_HALF_SCALE,
OPTION_ENABLE_TRUSTED_DEVICES, OPTION_ENABLE_TRUSTED_DEVICES,
OPTION_RELAY_SERVER, OPTION_RELAY_SERVER,
OPTION_ICE_SERVERS,
OPTION_DISABLE_UDP, OPTION_DISABLE_UDP,
OPTION_ALLOW_INSECURE_TLS_FALLBACK, OPTION_ALLOW_INSECURE_TLS_FALLBACK,
]; ];

View File

@@ -1,3 +1,5 @@
#[cfg(feature = "webrtc")]
use crate::webrtc::{self, is_webrtc_endpoint};
use crate::{ use crate::{
config::{Config, NetworkType}, config::{Config, NetworkType},
tcp::FramedStream, tcp::FramedStream,
@@ -5,8 +7,6 @@ use crate::{
websocket::{self, check_ws, is_ws_endpoint}, websocket::{self, check_ws, is_ws_endpoint},
ResultType, Stream, ResultType, Stream,
}; };
#[cfg(feature = "webrtc")]
use crate::webrtc::{self, is_webrtc_endpoint};
use anyhow::Context; use anyhow::Context;
use std::{net::SocketAddr, sync::Arc}; use std::{net::SocketAddr, sync::Arc};
use tokio::net::{ToSocketAddrs, UdpSocket}; use tokio::net::{ToSocketAddrs, UdpSocket};

View File

@@ -138,14 +138,15 @@ impl WebRTCStream {
} }
#[inline] #[inline]
fn get_turn_server_from_url(url: &str) -> Option<RTCIceServer> { fn get_ice_server_from_url(url: &str) -> Option<RTCIceServer> {
// standard url format with turn scheme: turn://user:pass@host:port // standard url format with turn scheme: turn://user:pass@host:port
match Url::parse(url) { match Url::parse(url) {
Ok(u) => { Ok(u) => {
if u.scheme() == "turn" { if u.scheme() == "turn" || u.scheme() == "stun" {
Some(RTCIceServer { Some(RTCIceServer {
urls: vec![format!( urls: vec![format!(
"turn:{}:{}", "{}:{}:{}",
u.scheme(),
u.host_str().unwrap_or_default(), u.host_str().unwrap_or_default(),
u.port().unwrap_or(3478) u.port().unwrap_or(3478)
)], )],
@@ -161,6 +162,24 @@ impl WebRTCStream {
} }
} }
#[inline]
fn get_ice_servers() -> Vec<RTCIceServer> {
let mut ice_servers = Vec::new();
let cfg = config::Config::get_option(config::keys::OPTION_ICE_SERVERS);
for url in cfg.split(',').map(str::trim) {
if let Some(ice_server) = Self::get_ice_server_from_url(url) {
ice_servers.push(ice_server);
}
}
if ice_servers.is_empty() {
ice_servers.push(RTCIceServer {
urls: DEFAULT_ICE_SERVERS.iter().map(|s| s.to_string()).collect(),
..Default::default()
});
}
ice_servers
}
pub async fn new( pub async fn new(
remote_endpoint: &str, remote_endpoint: &str,
force_relay: bool, force_relay: bool,
@@ -191,21 +210,10 @@ impl WebRTCStream {
// Create the API object // Create the API object
let api = APIBuilder::new().with_setting_engine(s).build(); let api = APIBuilder::new().with_setting_engine(s).build();
let mut ice_servers = vec![RTCIceServer {
urls: DEFAULT_ICE_SERVERS.iter().map(|s| s.to_string()).collect(),
..Default::default()
}];
if start_local_offer {
// only offer needs TURN server
let relay_server = config::Config::get_option(config::keys::OPTION_RELAY_SERVER);
if let Some(turn_server) = Self::get_turn_server_from_url(&relay_server) {
ice_servers.push(turn_server);
}
}
// Prepare the configuration // Prepare the configuration, get ICE servers from config
let config = RTCConfiguration { let config = RTCConfiguration {
ice_servers, ice_servers: Self::get_ice_servers(),
ice_transport_policy: if force_relay { ice_transport_policy: if force_relay {
RTCIceTransportPolicy::Relay RTCIceTransportPolicy::Relay
} else { } else {
@@ -458,55 +466,79 @@ pub fn is_webrtc_endpoint(endpoint: &str) -> bool {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::config;
use crate::webrtc::DEFAULT_ICE_SERVERS;
use crate::webrtc::WebRTCStream; use crate::webrtc::WebRTCStream;
use webrtc::peer_connection::sdp::session_description::RTCSessionDescription; use webrtc::peer_connection::sdp::session_description::RTCSessionDescription;
#[test] #[test]
fn test_webrtc_turn_url() { fn test_webrtc_ice_url() {
assert_eq!( assert_eq!(
WebRTCStream::get_turn_server_from_url("turn://example.com:3478") WebRTCStream::get_ice_server_from_url("turn://example.com:3478")
.unwrap_or_default() .unwrap_or_default()
.urls[0], .urls[0],
"turn:example.com:3478" "turn:example.com:3478"
); );
assert_eq!( assert_eq!(
WebRTCStream::get_turn_server_from_url("turn://example.com") WebRTCStream::get_ice_server_from_url("turn://example.com")
.unwrap_or_default() .unwrap_or_default()
.urls[0], .urls[0],
"turn:example.com:3478" "turn:example.com:3478"
); );
assert_eq!( assert_eq!(
WebRTCStream::get_turn_server_from_url("turn://123@example.com") WebRTCStream::get_ice_server_from_url("turn://123@example.com")
.unwrap_or_default() .unwrap_or_default()
.username, .username,
"123" "123"
); );
assert_eq!( assert_eq!(
WebRTCStream::get_turn_server_from_url("turn://123@example.com") WebRTCStream::get_ice_server_from_url("turn://123@example.com")
.unwrap_or_default() .unwrap_or_default()
.credential, .credential,
"" ""
); );
assert_eq!( assert_eq!(
WebRTCStream::get_turn_server_from_url("turn://123:321@example.com") WebRTCStream::get_ice_server_from_url("turn://123:321@example.com")
.unwrap_or_default() .unwrap_or_default()
.credential, .credential,
"321" "321"
); );
assert_eq!( assert_eq!(
WebRTCStream::get_turn_server_from_url("stun://example.com:3478"), WebRTCStream::get_ice_server_from_url("stun://example.com:3478")
None .unwrap_or_default()
.urls[0],
"stun:example.com:3478"
); );
assert_eq!( assert_eq!(
WebRTCStream::get_turn_server_from_url("http://123:123@example.com:3478"), WebRTCStream::get_ice_server_from_url("http://123:123@example.com:3478"),
None None
); );
config::Config::set_option("ice-servers".to_string(), "".to_string());
assert_eq!(
WebRTCStream::get_ice_servers()[0].urls[0],
DEFAULT_ICE_SERVERS[0].to_string()
);
config::Config::set_option("ice-servers".to_string(), ",stun://example.com,turn://example.com,sdf".to_string());
assert_eq!(
WebRTCStream::get_ice_servers()[0].urls[0],
"stun:example.com:3478"
);
assert_eq!(
WebRTCStream::get_ice_servers()[1].urls[0],
"turn:example.com:3478"
);
assert_eq!(
WebRTCStream::get_ice_servers().len(),
2
);
} }
#[test] #[test]