Crates.io | rvoip-sip-core |
lib.rs | rvoip-sip-core |
version | 0.1.26 |
created_at | 2025-07-03 05:35:20.339657+00 |
updated_at | 2025-08-15 17:48:19.431827+00 |
description | SIP protocol implementation for the rvoip stack |
homepage | https://github.com/eisenzopf/rvoip |
repository | https://github.com/eisenzopf/rvoip |
max_upload_size | |
id | 1735828 |
size | 4,661,285 |
rvoip-sip-core
provides a production-ready, RFC-compliant implementation of the Session Initiation Protocol (SIP) in Rust. This library serves as the foundational protocol layer for the entire rvoip VoIP ecosystem, offering a complete toolkit for building SIP-based applications including VoIP clients, SIP proxies, PBX systems, and other SIP-enabled communications infrastructure.
sip-transport
for UDP/TCP/TLS/SCTP protocolstransaction-core
for request/response matchingdialog-core
for call state and session trackingmedia-core
and rtp-core
for audio/video streamssession-core
and call-engine
for business logicThe SIP-Core sits at the protocol foundation layer, providing the building blocks for all higher-level VoIP functionality:
┌─────────────────────────────────────────┐
│ Application Layer │
├─────────────────────────────────────────┤
│ rvoip-call-engine │
├─────────────────────────────────────────┤
│ rvoip-session-core │
├─────────────────────────────────────────┤
│ rvoip-dialog-core │ rvoip-media-core │
├─────────────────────────────────────────┤
│ rvoip-transaction │ rvoip-rtp-core │
│ -core │ │
├─────────────────────────────────────────┤
│ rvoip-sip-core ⬅️ YOU ARE HERE
├─────────────────────────────────────────┤
│ rvoip-sip-transport │
├─────────────────────────────────────────┤
│ Network Layer │
└─────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ rvoip-sip-core │
│ ┌─────────────┬─────────────┬─────────────┬─────────────┐ │
│ │ parser │ builder │ types │ sdp │ │
│ ├─────────────┼─────────────┼─────────────┼─────────────┤ │
│ │ message │ headers │ headers │ attributes │ │
│ │ header │ macros │ uri │ builder │ │
│ │ uri │ multipart │ address │ macros │ │
│ │ sdp │ utils │ auth │ parser │ │
│ └─────────────┴─────────────┴─────────────┴─────────────┘ │
├─────────────────────────────────────────────────────────────┤
│ External Dependencies │
│ bytes │ nom │ uuid │ base64 │ md5 │ sha2 │ time │ regex │
└─────────────────────────────────────────────────────────────┘
parser/
: High-performance message and header parsing with nom combinatorsbuilder/
: Fluent APIs for type-safe message constructiontypes/
: Strongly-typed representations of SIP headers, URIs, and messagessdp/
: Complete Session Description Protocol implementation with WebRTC supportmacros/
: Declarative macros for concise SIP and SDP message definitionClean separation enables easy integration across the VoIP stack:
┌─────────────────┐ SIP Messages ┌─────────────────┐
│ │ ──────────────────────► │ │
│ Higher Layers │ │ sip-core │
│ (session-core, │ ◄──────────────────────── │ (Protocol │
│ dialog-core) │ Parsed Messages │ Foundation) │
└─────────────────┘ └─────────────────┘
│
Raw Network Data │ Type-Safe APIs
▼ ▼
┌─────────────────┐ ┌─────────────────┐
│ sip-transport │ │ Application │
│ (Network I/O) │ │ (VoIP Systems) │
└─────────────────┘ └─────────────────┘
Add to your Cargo.toml
:
[dependencies]
rvoip-sip-core = "0.1.0"
bytes = "1.4" # For handling raw message data
tokio = { version = "1.0", features = ["full"] } # For async examples
use rvoip_sip_core::prelude::*;
let message = parse_message(&bytes::Bytes::from("INVITE sip:bob@example.com SIP/2.0\r\n\r\n")).unwrap();
println!("Method: {}", message.method().unwrap());
use rvoip_sip_core::prelude::*;
use bytes::Bytes;
// Parse a SIP message
let data = Bytes::from(
"INVITE sip:bob@example.com SIP/2.0\r\n\
Via: SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds\r\n\
Max-Forwards: 70\r\n\
To: Bob <sip:bob@example.com>\r\n\
From: Alice <sip:alice@atlanta.com>;tag=1928301774\r\n\
Call-ID: a84b4c76e66710@pc33.atlanta.com\r\n\
CSeq: 314159 INVITE\r\n\
Contact: <sip:alice@pc33.atlanta.com>\r\n\
Content-Type: application/sdp\r\n\
Content-Length: 0\r\n\r\n"
);
let message = parse_message(&data).expect("Valid SIP message");
// Access message components
if let Message::Request(request) = message {
println!("Method: {}", request.method());
println!("URI: {}", request.uri());
let from = request.typed_header::<From>().expect("From header");
println!("From: {}", from.address());
}
use rvoip_sip_core::prelude::*;
// Create a SIP request with the RequestBuilder
let bob_uri = "sip:bob@example.com".parse::<Uri>().unwrap();
let alice_uri = "sip:alice@atlanta.com".parse::<Uri>().unwrap();
let contact_uri = "sip:alice@pc33.atlanta.com".parse::<Uri>().unwrap();
let request = RequestBuilder::new(Method::Invite, &bob_uri.to_string())
.unwrap()
.header(TypedHeader::From(From::new(Address::new_with_display_name("Alice", alice_uri.clone()))))
.header(TypedHeader::To(To::new(Address::new_with_display_name("Bob", bob_uri.clone()))))
.header(TypedHeader::CallId(CallId::new("a84b4c76e66710@pc33.atlanta.com")))
.header(TypedHeader::CSeq(CSeq::new(314159, Method::Invite)))
.header(TypedHeader::Via(Via::parse("SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds").unwrap()))
.header(TypedHeader::MaxForwards(MaxForwards::new(70)))
.header(TypedHeader::Contact(Contact::new(Address::new(contact_uri))))
.header(TypedHeader::ContentLength(ContentLength::new(0)))
.build();
use rvoip_sip_core::prelude::*;
// Create a SIP request with the sip! macro
let request = sip! {
method: Method::Invite,
uri: "sip:bob@example.com",
headers: {
Via: "SIP/2.0/UDP pc33.atlanta.com;branch=z9hG4bK776asdhds",
MaxForwards: 70,
To: "Bob <sip:bob@example.com>",
From: "Alice <sip:alice@atlanta.com>;tag=1928301774",
CallId: "a84b4c76e66710@pc33.atlanta.com",
CSeq: "314159 INVITE",
Contact: "<sip:alice@pc33.atlanta.com>",
ContentLength: 0
}
};
use rvoip_sip_core::sdp_prelude::*;
// Create an SDP session with the SdpBuilder
let sdp = SdpBuilder::new("My Session")
.origin("-", "1234567890", "2", "IN", "IP4", "127.0.0.1")
.time("0", "0") // Time 0-0 means permanent session
.media_audio(49170, "RTP/AVP")
.formats(&["0", "8"])
.direction(MediaDirection::SendRecv)
.rtpmap("0", "PCMU/8000")
.rtpmap("8", "PCMA/8000")
.done()
.build();
use rvoip_sip_core::sdp_prelude::*;
// Create an SDP session with the sdp! macro
let sdp = sdp! {
origin: ("-", "1234567890", "2", "IN", "IP4", "192.168.1.100"),
session_name: "Audio Call",
time: ("0", "0"),
media: {
type: "audio",
port: 49170,
protocol: "RTP/AVP",
formats: ["0", "8"],
rtpmap: ("0", "PCMU/8000"),
rtpmap: ("8", "PCMA/8000"),
direction: "sendrecv"
}
};
Header | Type | Status | Description |
---|---|---|---|
From |
Address | ✅ Complete | Initiator of the request with tag parameter |
To |
Address | ✅ Complete | Logical recipient with optional tag |
Contact |
Address | ✅ Complete | Direct communication URI with parameters |
Call-ID |
String | ✅ Complete | Unique identifier for call or registration |
CSeq |
Sequence | ✅ Complete | Sequence number with method for ordering |
Via |
List | ✅ Complete | Request path and response routing |
Max-Forwards |
Integer | ✅ Complete | Hop limit for loop prevention |
Route |
List | ✅ Complete | Mandatory routing path |
Record-Route |
List | ✅ Complete | Proxy insertion for dialog routing |
Accept |
List | ✅ Complete | Acceptable media types |
Accept-Encoding |
List | ✅ Complete | Acceptable content encodings |
Accept-Language |
List | ✅ Complete | Acceptable content languages |
Alert-Info |
List | ✅ Complete | Alternative ring tones |
Allow |
List | ✅ Complete | Supported SIP methods |
Content-Disposition |
Parameterized | ✅ Complete | Message body handling |
Content-Encoding |
List | ✅ Complete | Body encoding scheme |
Content-Language |
List | ✅ Complete | Body language |
Content-Length |
Integer | ✅ Complete | Body size in bytes |
Content-Type |
Media Type | ✅ Complete | Body media type |
Date |
DateTime | ✅ Complete | Message origination time |
Error-Info |
List | ✅ Complete | Error details URI |
Expires |
Integer | ✅ Complete | Registration/subscription expiration |
In-Reply-To |
List | ✅ Complete | Referenced Call-IDs |
MIME-Version |
Version | ✅ Complete | MIME protocol version |
Organization |
String | ✅ Complete | Organization identification |
Priority |
Enumerated | ✅ Complete | Request urgency (emergency, urgent, normal, non-urgent) |
Proxy-Require |
List | ✅ Complete | Proxy-required extensions |
Reply-To |
Address | ✅ Complete | Non-SIP reply address |
Require |
List | ✅ Complete | Required extensions |
Retry-After |
Integer | ✅ Complete | Retry delay after error |
Server |
String | ✅ Complete | Server software identification |
Subject |
String | ✅ Complete | Call subject/reason |
Supported |
List | ✅ Complete | Supported extensions |
Timestamp |
DateTime | ✅ Complete | Request timestamp |
Unsupported |
List | ✅ Complete | Unsupported extensions |
User-Agent |
String | ✅ Complete | Client software identification |
Warning |
List | ✅ Complete | Additional status information |
Header | Type | Status | Algorithms | Description |
---|---|---|---|---|
Authorization |
Credentials | ✅ Complete | MD5, SHA-256, SHA-512-256 | User agent credentials |
WWW-Authenticate |
Challenge | ✅ Complete | MD5, SHA-256, SHA-512-256 | Server authentication challenge |
Proxy-Authorization |
Credentials | ✅ Complete | MD5, SHA-256, SHA-512-256 | Proxy credentials |
Proxy-Authenticate |
Challenge | ✅ Complete | MD5, SHA-256, SHA-512-256 | Proxy authentication challenge |
Authentication-Info |
Info | ✅ Complete | All | Authentication success info |
Authentication Features:
Header | RFC | Status | Description |
---|---|---|---|
Event |
RFC 3265 | ✅ Complete | Event package for notifications |
Subscription-State |
RFC 3265 | ✅ Complete | Subscription state and expiration |
Refer-To |
RFC 3515 | ✅ Complete | Call transfer target |
Referred-By |
RFC 3892 | ✅ Complete | Transfer initiator identification |
Session-Expires |
RFC 4028 | ✅ Complete | Session refresh interval |
Min-SE |
RFC 4028 | ✅ Complete | Minimum session expiration |
Path |
RFC 3327 | ✅ Complete | Registration path for NAT traversal |
Service-Route |
RFC 3608 | ✅ Complete | Service routing for registrations |
P-Access-Network-Info |
RFC 3455 | ✅ Complete | Access network information |
P-Charging-Vector |
RFC 3455 | ✅ Complete | Charging information |
RSeq |
RFC 3262 | ✅ Complete | Reliable provisional response sequence |
RAck |
RFC 3262 | ✅ Complete | Reliable response acknowledgment |
Feature | Status | Description |
---|---|---|
Custom Header Parsing | ✅ Complete | Unknown headers parsed as raw headers |
Proprietary Extensions | ✅ Complete | Support for vendor-specific headers |
Header Validation | ✅ Complete | Configurable strict/lenient validation |
Case Insensitive | ✅ Complete | Header names case-insensitive per RFC |
Field | Status | Description |
---|---|---|
v= |
✅ Complete | Version (always 0) |
o= |
✅ Complete | Origin with username, session ID, version, network type, and address |
s= |
✅ Complete | Session name |
i= |
✅ Complete | Session information |
u= |
✅ Complete | URI for additional information |
e= |
✅ Complete | Email address |
p= |
✅ Complete | Phone number |
c= |
✅ Complete | Connection data with multicast support |
b= |
✅ Complete | Bandwidth information |
t= |
✅ Complete | Time description |
r= |
✅ Complete | Repeat times |
z= |
✅ Complete | Time zone adjustments |
k= |
✅ Complete | Encryption keys |
a= |
✅ Complete | Attributes (60+ supported) |
m= |
✅ Complete | Media descriptions |
Attribute | Status | Description |
---|---|---|
rtpmap |
✅ Complete | RTP payload type mapping |
fmtp |
✅ Complete | Format-specific parameters |
ptime |
✅ Complete | Preferred packetization time |
maxptime |
✅ Complete | Maximum packetization time |
sendrecv |
✅ Complete | Bidirectional media |
sendonly |
✅ Complete | Send-only media |
recvonly |
✅ Complete | Receive-only media |
inactive |
✅ Complete | Inactive media |
orient |
✅ Complete | Whiteboard orientation |
type |
✅ Complete | Conference type |
charset |
✅ Complete | Character set |
sdplang |
✅ Complete | SDP language |
lang |
✅ Complete | Media language |
Category | Attribute | RFC | Status | Description |
---|---|---|---|---|
ICE | candidate |
RFC 8839 | ✅ Complete | ICE candidate with all types |
ice-ufrag |
RFC 8839 | ✅ Complete | ICE username fragment | |
ice-pwd |
RFC 8839 | ✅ Complete | ICE password | |
ice-options |
RFC 8839 | ✅ Complete | ICE options (trickle, etc.) | |
end-of-candidates |
RFC 8840 | ✅ Complete | End of candidates marker | |
DTLS | fingerprint |
RFC 8122 | ✅ Complete | Certificate fingerprint |
setup |
RFC 4145 | ✅ Complete | DTLS setup role | |
Media | mid |
RFC 8843 | ✅ Complete | Media stream identification |
group |
RFC 5888 | ✅ Complete | Media grouping (BUNDLE) | |
msid |
RFC 8830 | ✅ Complete | Media stream/track ID | |
ssrc |
RFC 5576 | ✅ Complete | Synchronization source | |
RTP | rtcp-fb |
RFC 4585 | ✅ Complete | RTCP feedback parameters |
rtcp-mux |
RFC 5761 | ✅ Complete | RTCP multiplexing | |
extmap |
RFC 8285 | ✅ Complete | RTP header extensions | |
rid |
RFC 8851 | ✅ Complete | RTP stream identifier | |
simulcast |
RFC 8853 | ✅ Complete | Simulcast stream configuration | |
Data | sctp-port |
RFC 8841 | ✅ Complete | SCTP port for data channels |
max-message-size |
RFC 8841 | ✅ Complete | Maximum data channel message size |
Media Type | Status | Formats | Description |
---|---|---|---|
audio |
✅ Complete | All standard codecs | Audio streams |
video |
✅ Complete | All standard codecs | Video streams |
application |
✅ Complete | Data channels | WebRTC data channels |
text |
✅ Complete | Text formats | Text/messaging |
message |
✅ Complete | Message formats | Messaging applications |
Custom types | ✅ Complete | Token validation | Non-standard media types |
Method | Status | Use Case |
---|---|---|
Manual Construction | ✅ Complete | Maximum control and customization |
Builder Pattern | ✅ Complete | Type-safe programmatic generation |
Declarative Macro | ✅ Complete | Concise static definitions |
From String Parsing | ✅ Complete | Parse existing SDP content |
SIP-core provides the protocol foundation for a wide variety of VoIP applications:
The library provides three main message types:
Message
: An enum representing either a SIP request or responseRequest
: Represents a SIP request (INVITE, BYE, etc.)Response
: Represents a SIP response (200 OK, 404 Not Found, etc.)All standard SIP headers are implemented with strong typing:
From
, To
: Address headers with tag parametersVia
: Network routing informationCSeq
: Command sequence numberCall-ID
: Unique identifier for a dialogThe library includes a comprehensive URI implementation:
Uri
: Main URI type with full parameter supportScheme
: SIP URI schemes (sip, sips, tel, etc.)Host
: Host representation (domain name or IP address)For handling multimedia session information:
SdpSession
: Full SDP session representationMediaDescription
: Media type, port, and attributesConnection
: Network connection informationuse rvoip_sip_core::prelude::*;
use rvoip_sip_core::parser::message::ParseMode;
use bytes::Bytes;
let data = Bytes::from("SIP message data...");
// Default parsing is lenient for robustness
let message = parse_message(&data).expect("Valid SIP message");
// Use strict mode for RFC compliance validation
let strict_message = parse_message_with_mode(&data, ParseMode::Strict);
// Use lenient mode explicitly to handle non-compliant messages
let lenient_message = parse_message_with_mode(&data, ParseMode::Lenient);
use rvoip_sip_core::prelude::*;
use bytes::Bytes;
// Create a multipart body
let mut multipart = MultipartBody::new("mixed");
multipart.add_part(MimePart::new(
"application/sdp",
Bytes::from("v=0\r\no=- 123456 789012 IN IP4 192.168.1.1\r\ns=Call\r\nc=IN IP4 192.168.1.1\r\nt=0 0\r\nm=audio 49170 RTP/AVP 0\r\n")
));
multipart.add_part(MimePart::new(
"application/xml",
Bytes::from("<xml>Some XML content</xml>")
));
// Add to a request using the builder
let request = RequestBuilder::new(Method::Invite, "sip:bob@example.com")
.unwrap()
// Add headers...
.body(multipart.to_bytes())
.build();
use rvoip_sip_core::prelude::*;
// Create an Authorization header
let auth = Authorization::new_digest(
"example.com",
"alice",
"password",
"INVITE",
"sip:bob@example.com",
"nonce-value",
"cnonce-value"
);
// Add to a request using the builder
let request = RequestBuilder::new(Method::Invite, "sip:bob@example.com")
.unwrap()
.header(TypedHeader::Authorization(auth))
// Add other headers...
.build();
The library includes comprehensive validation for SIP messages and SDP content:
use rvoip_sip_core::prelude::*;
use rvoip_sip_core::sdp_prelude::*;
// Validate an IP address
let is_valid = is_valid_ipv4("192.168.1.1"); // true
let is_valid = is_valid_ipv4("256.0.0.1"); // false (invalid IPv4)
// Validate an SDP session
let validation_result = sdp_session.validate();
if let Err(errors) = validation_result {
for error in errors {
println!("Validation error: {}", error);
}
}
The library provides convenient prelude modules to import common types:
// For SIP functionality
use rvoip_sip_core::prelude::*;
// For SDP functionality
use rvoip_sip_core::sdp_prelude::*;
lenient_parsing
: Enables more lenient parsing mode for torture tests and handling of non-compliant messages# Parse a SIP message
cargo run --example parse_invite
# Create SIP messages with builders
cargo run --example builder_request
cargo run --example builder_response
# SDP creation and parsing
cargo run --example sdp_builder
cargo run --example sdp_macro
# Authentication examples
cargo run --example digest_auth
# URI manipulation
cargo run --example uri_parsing
Run the comprehensive test suite:
# Run all tests
cargo test -p rvoip-sip-core
# Run parser tests
cargo test -p rvoip-sip-core parser
# Run builder tests
cargo test -p rvoip-sip-core builder
# Run SDP tests
cargo test -p rvoip-sip-core sdp
# Run torture tests
cargo test -p rvoip-sip-core --test torture_tests
# Run with lenient parsing
cargo test -p rvoip-sip-core --features="lenient_parsing"
Test Coverage: Complete protocol validation
The library provides comprehensive error handling with detailed diagnostics:
use rvoip_sip_core::{parse_message, SipError};
match parse_message(&data) {
Ok(message) => {
// Process parsed message
}
Err(err) => match err {
SipError::ParseError { line, column, message } => {
eprintln!("Parse error at {}:{}: {}", line, column, message);
}
SipError::InvalidHeader { name, value, reason } => {
eprintln!("Invalid header {}: {} - {}", name, value, reason);
}
SipError::InvalidUri { uri, reason } => {
eprintln!("Invalid URI {}: {}", uri, reason);
}
SipError::InvalidSdp { line, reason } => {
eprintln!("Invalid SDP at line {}: {}", line, reason);
}
_ => eprintln!("Other error: {}", err),
}
}
Contributions are welcome! Please see the main rvoip contributing guidelines for details.
For sip-core specific contributions:
Development Status: ✅ Production-Ready SIP Protocol Foundation
Production Readiness: ✅ Ready for All VoIP Applications
Current Capabilities: ✅ Complete Protocol Foundation
Current Limitations: ⚠️ Performance Optimizations Planned
Quality Assurance: 🔧 Comprehensive Testing
Integration Status: 📈 Foundation Complete, Higher Layers Ready
This project is licensed under either of
at your option.
Built with ❤️ for the Rust VoIP community - Production-ready SIP protocol implementation made simple