feat(rust-proxy-engine): add a Rust SIP proxy engine with shared SIP and codec libraries
This commit is contained in:
67
rust/crates/proxy-engine/src/sip_transport.rs
Normal file
67
rust/crates/proxy-engine/src/sip_transport.rs
Normal file
@@ -0,0 +1,67 @@
|
||||
//! SIP UDP transport — owns the main SIP socket.
|
||||
//!
|
||||
//! Binds a UDP socket, receives SIP messages, and provides a send method.
|
||||
|
||||
use std::net::SocketAddr;
|
||||
use std::sync::Arc;
|
||||
use tokio::net::UdpSocket;
|
||||
|
||||
/// The SIP UDP transport layer.
|
||||
pub struct SipTransport {
|
||||
socket: Arc<UdpSocket>,
|
||||
}
|
||||
|
||||
impl SipTransport {
|
||||
/// Bind a UDP socket on the given address (e.g. "0.0.0.0:5070").
|
||||
pub async fn bind(bind_addr: &str) -> Result<Self, String> {
|
||||
let socket = UdpSocket::bind(bind_addr)
|
||||
.await
|
||||
.map_err(|e| format!("bind {bind_addr}: {e}"))?;
|
||||
Ok(Self {
|
||||
socket: Arc::new(socket),
|
||||
})
|
||||
}
|
||||
|
||||
/// Get a clone of the socket Arc for the receiver task.
|
||||
pub fn socket(&self) -> Arc<UdpSocket> {
|
||||
self.socket.clone()
|
||||
}
|
||||
|
||||
/// Send a raw SIP message to a destination.
|
||||
pub async fn send_to(&self, data: &[u8], dest: SocketAddr) -> Result<usize, String> {
|
||||
self.socket
|
||||
.send_to(data, dest)
|
||||
.await
|
||||
.map_err(|e| format!("send to {dest}: {e}"))
|
||||
}
|
||||
|
||||
/// Send a raw SIP message to an address:port pair.
|
||||
pub async fn send_to_addr(&self, data: &[u8], addr: &str, port: u16) -> Result<usize, String> {
|
||||
let dest: SocketAddr = format!("{addr}:{port}")
|
||||
.parse()
|
||||
.map_err(|e| format!("bad address {addr}:{port}: {e}"))?;
|
||||
self.send_to(data, dest).await
|
||||
}
|
||||
|
||||
/// Spawn the UDP receive loop. Calls the handler for every received packet.
|
||||
pub fn spawn_receiver<F>(
|
||||
&self,
|
||||
handler: F,
|
||||
) where
|
||||
F: Fn(&[u8], SocketAddr) + Send + 'static,
|
||||
{
|
||||
let socket = self.socket.clone();
|
||||
tokio::spawn(async move {
|
||||
let mut buf = vec![0u8; 65535];
|
||||
loop {
|
||||
match socket.recv_from(&mut buf).await {
|
||||
Ok((n, addr)) => handler(&buf[..n], addr),
|
||||
Err(e) => {
|
||||
eprintln!("[sip_transport] recv error: {e}");
|
||||
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user