Expand description
§RSIPStack - A SIP Stack Implementation in Rust
RSIPStack is a comprehensive Session Initiation Protocol (SIP) implementation written in Rust. It provides a complete SIP stack with support for multiple transport protocols, transaction management, dialog handling, and more.
§Features
- Complete SIP Implementation - Full RFC 3261 compliance
- Multiple Transports - UDP, TCP, TLS, WebSocket support
- Transaction Layer - Automatic retransmissions and timer management
- Dialog Management - Full dialog state machine implementation
- Async/Await Support - Built on Tokio for high performance
- Type Safety - Leverages Rust’s type system for protocol correctness
- Extensible - Modular design for easy customization
§Architecture
The stack is organized into several layers following the SIP specification:
┌─────────────────────────────────────┐
│           Application Layer         │
├─────────────────────────────────────┤
│           Dialog Layer              │
├─────────────────────────────────────┤
│         Transaction Layer           │
├─────────────────────────────────────┤
│          Transport Layer            │
└─────────────────────────────────────┘§Quick Start
§Creating a SIP Endpoint
use rsipstack::EndpointBuilder;
use tokio_util::sync::CancellationToken;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create a SIP endpoint
    let endpoint = EndpointBuilder::new()
        .with_user_agent("MyApp/1.0")
        .build();
     
    // Get incoming transactions
    let mut incoming = endpoint.incoming_transactions();
     
    // Start the endpoint (in production, you'd run this in a separate task)
    // let endpoint_inner = endpoint.inner.clone();
    // tokio::spawn(async move {
    //     endpoint_inner.serve().await.ok();
    // });
     
    // Process incoming requests
    while let Some(transaction) = incoming.recv().await {
        // Handle the transaction
        println!("Received: {}", transaction.original.method);
        break; // Exit for example
    }
     
    Ok(())
}§Sending SIP Requests
use rsipstack::dialog::dialog_layer::DialogLayer;
use rsipstack::dialog::invitation::InviteOption;
use rsipstack::transaction::endpoint::EndpointInner;
use std::sync::Arc;
// Create a dialog layer
let dialog_layer = DialogLayer::new(endpoint.clone());
// Send an INVITE
let invite_option = InviteOption {
    caller: rsip::Uri::try_from("sip:alice@example.com")?,
    callee: rsip::Uri::try_from("sip:bob@example.com")?,
    contact: rsip::Uri::try_from("sip:alice@myhost.com:5060")?,
    content_type: Some("application/sdp".to_string()),
    offer: Some(sdp_body),
    credential: None,
    headers: None,
};
let (dialog, response) = dialog_layer.do_invite(invite_option, state_sender).await?;§Core Components
§Transport Layer
The transport layer handles network communication across different protocols:
- SipConnection- Abstraction over transport protocols
- SipAddr- SIP addressing with transport information
- TransportLayer- Transport management
§Transaction Layer
The transaction layer provides reliable message delivery:
- Transaction- SIP transaction implementation
- Endpoint- SIP endpoint for transaction management
- TransactionState- Transaction state machine
§Dialog Layer
The dialog layer manages SIP dialogs and sessions:
- Dialog- SIP dialog representation
- DialogId- Dialog identification
- DialogState- Dialog state management
§Error Handling
The stack uses a comprehensive error type that covers all layers:
use rsipstack::{Result, Error};
fn handle_sip_error(error: Error) {
    match error {
        Error::TransportLayerError(msg, addr) => {
            eprintln!("Transport error at {}: {}", addr, msg);
        },
        Error::TransactionError(msg, key) => {
            eprintln!("Transaction error {}: {}", key, msg);
        },
        Error::DialogError(msg, id) => {
            eprintln!("Dialog error {}: {}", id, msg);
        },
        _ => eprintln!("Other error: {}", error),
    }
}§Configuration
The stack can be configured for different use cases:
§Basic UDP Server
use rsipstack::EndpointBuilder;
use rsipstack::transport::{TransportLayer, udp::UdpConnection};
use tokio_util::sync::CancellationToken;
let transport_layer = TransportLayer::new(cancel_token.child_token());
let udp_conn = UdpConnection::create_connection("0.0.0.0:5060".parse()?, None).await?;
transport_layer.add_transport(udp_conn.into());
let endpoint = EndpointBuilder::new()
    .with_transport_layer(transport_layer)
    .build();§Secure TLS Server
#[cfg(feature = "rustls")]
use rsipstack::transport::tls::{TlsConnection, TlsConfig};
use rsipstack::transport::TransportLayer;
// Configure TLS transport
let tls_config = TlsConfig {
    cert: Some(cert_pem),
    key: Some(key_pem),
    ..Default::default()
};
// TLS connections would be created using the TLS configuration
// let tls_conn = TlsConnection::serve_listener(...).await?;§Standards Compliance
RSIPStack implements the following RFCs:
- RFC 3261 - SIP: Session Initiation Protocol (core specification)
- RFC 3581 - Symmetric Response Routing (rport)
- RFC 6026 - Correct Transaction Handling for 2xx Responses to INVITE
§Performance
The stack is designed for high performance:
- Zero-copy parsing where possible
- Async I/O with Tokio for scalability
- Efficient timer management for large numbers of transactions
- Memory-safe with Rust’s ownership system
§Testing
Comprehensive test suite covering:
- Unit tests for all components
- Integration tests for protocol compliance
- Performance benchmarks
- Interoperability testing
§Examples
See the examples/ directory for complete working examples:
- Simple SIP client
- SIP proxy server
- WebSocket SIP gateway
- Load testing tools
Re-exports§
- pub use crate::error::Error;
- pub use transaction::EndpointBuilder;