Crate rsipstack

Source
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:

§Transaction Layer

The transaction layer provides reliable message delivery:

§Dialog Layer

The dialog layer manages SIP dialogs and sessions:

§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;

Modules§

dialog
error
rsip_ext
transaction
transport

Macros§

header_pop

Type Aliases§

Result