100 lines
3.4 KiB
Rust
100 lines
3.4 KiB
Rust
//! Binary entry point that wires configuration, UDP listener, optional TLS listener, and allocation handling.
|
|
//! Backlog: graceful shutdown signals, structured metrics, and coordinated lifecycle management across listeners.
|
|
use std::net::SocketAddr;
|
|
use std::sync::Arc;
|
|
use tokio::net::UdpSocket;
|
|
use tracing::{error, info};
|
|
|
|
// Use the library crate's public modules instead of local `mod` declarations.
|
|
use niom_turn::alloc::AllocationManager;
|
|
use niom_turn::auth::{AuthManager, InMemoryStore};
|
|
use niom_turn::config::{AuthOptions, Config};
|
|
use niom_turn::server::udp_reader_loop;
|
|
|
|
#[tokio::main]
|
|
async fn main() -> anyhow::Result<()> {
|
|
niom_turn::logging::init_tracing();
|
|
|
|
info!("niom-turn starting");
|
|
|
|
// Bootstrap configuration: prefer appsettings.json, otherwise rely on baked-in demo defaults.
|
|
let cfg = match Config::load_default() {
|
|
Ok(c) => {
|
|
info!("loaded config from appsettings.json");
|
|
c
|
|
}
|
|
Err(e) => {
|
|
info!(
|
|
"no appsettings.json found or failed to load: {} — using defaults",
|
|
e
|
|
);
|
|
// defaults
|
|
Config {
|
|
server: niom_turn::config::ServerOptions {
|
|
bind: "0.0.0.0:3478".to_string(),
|
|
tls_cert: None,
|
|
tls_key: None,
|
|
},
|
|
credentials: vec![niom_turn::config::CredentialEntry {
|
|
username: "testuser".into(),
|
|
password: "secretpassword".into(),
|
|
}],
|
|
auth: AuthOptions::default(),
|
|
}
|
|
}
|
|
};
|
|
|
|
let bind_addr: SocketAddr = cfg.server.bind.parse()?;
|
|
|
|
// Materialise the credential backend before starting network endpoints.
|
|
let creds = InMemoryStore::new();
|
|
for c in cfg.credentials.iter() {
|
|
creds.insert(&c.username, &c.password);
|
|
}
|
|
|
|
let auth = AuthManager::new(creds.clone(), &cfg.auth);
|
|
|
|
// Bind the UDP socket that receives STUN/TURN traffic from WebRTC clients.
|
|
let udp = UdpSocket::bind(bind_addr).await?;
|
|
let udp = Arc::new(udp);
|
|
|
|
// Allocation manager shared by UDP + TLS frontends.
|
|
let alloc_mgr = AllocationManager::new();
|
|
|
|
// Spawn the asynchronous packet loop that handles all UDP requests.
|
|
let udp_clone = udp.clone();
|
|
let auth_clone = auth.clone();
|
|
let alloc_clone = alloc_mgr.clone();
|
|
tokio::spawn(async move {
|
|
if let Err(e) = udp_reader_loop(udp_clone, auth_clone, alloc_clone).await {
|
|
error!("udp loop error: {:?}", e);
|
|
}
|
|
});
|
|
|
|
// Optionally start the TLS listener so `turns:` clients can connect via TCP/TLS.
|
|
if let (Some(cert), Some(key)) = (cfg.server.tls_cert.clone(), cfg.server.tls_key.clone()) {
|
|
let udp_for_tls = udp.clone();
|
|
let auth_for_tls = auth.clone();
|
|
let alloc_for_tls = alloc_mgr.clone();
|
|
tokio::spawn(async move {
|
|
if let Err(e) = niom_turn::tls::serve_tls(
|
|
"0.0.0.0:5349",
|
|
&cert,
|
|
&key,
|
|
udp_for_tls,
|
|
auth_for_tls,
|
|
alloc_for_tls,
|
|
)
|
|
.await
|
|
{
|
|
error!("tls serve failed: {:?}", e);
|
|
}
|
|
});
|
|
}
|
|
|
|
// Keep the runtime alive while background tasks process packets.
|
|
loop {
|
|
tokio::time::sleep(std::time::Duration::from_secs(60)).await;
|
|
}
|
|
}
|