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_REGISTER_DEVICE: &str = "register-device";
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_ALLOW_INSECURE_TLS_FALLBACK: &str = "allow-insecure-tls-fallback";
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_TRUSTED_DEVICES,
OPTION_RELAY_SERVER,
OPTION_ICE_SERVERS,
OPTION_DISABLE_UDP,
OPTION_ALLOW_INSECURE_TLS_FALLBACK,
];

View File

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

View File

@@ -138,14 +138,15 @@ impl WebRTCStream {
}
#[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
match Url::parse(url) {
Ok(u) => {
if u.scheme() == "turn" {
if u.scheme() == "turn" || u.scheme() == "stun" {
Some(RTCIceServer {
urls: vec![format!(
"turn:{}:{}",
"{}:{}:{}",
u.scheme(),
u.host_str().unwrap_or_default(),
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(
remote_endpoint: &str,
force_relay: bool,
@@ -191,21 +210,10 @@ impl WebRTCStream {
// Create the API object
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 {
ice_servers,
ice_servers: Self::get_ice_servers(),
ice_transport_policy: if force_relay {
RTCIceTransportPolicy::Relay
} else {
@@ -458,55 +466,79 @@ pub fn is_webrtc_endpoint(endpoint: &str) -> bool {
#[cfg(test)]
mod tests {
use crate::config;
use crate::webrtc::DEFAULT_ICE_SERVERS;
use crate::webrtc::WebRTCStream;
use webrtc::peer_connection::sdp::session_description::RTCSessionDescription;
#[test]
fn test_webrtc_turn_url() {
fn test_webrtc_ice_url() {
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()
.urls[0],
"turn:example.com:3478"
);
assert_eq!(
WebRTCStream::get_turn_server_from_url("turn://example.com")
WebRTCStream::get_ice_server_from_url("turn://example.com")
.unwrap_or_default()
.urls[0],
"turn:example.com:3478"
);
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()
.username,
"123"
);
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()
.credential,
""
);
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()
.credential,
"321"
);
assert_eq!(
WebRTCStream::get_turn_server_from_url("stun://example.com:3478"),
None
WebRTCStream::get_ice_server_from_url("stun://example.com:3478")
.unwrap_or_default()
.urls[0],
"stun:example.com:3478"
);
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
);
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]