Skip to content

Latest commit

 

History

History
637 lines (502 loc) · 28.2 KB

File metadata and controls

637 lines (502 loc) · 28.2 KB

asterisk-rs: Project Conversation Log

Rewriting Asterisk in Rust -- from 1.16 million lines of C to a modern, memory-safe telephony platform.


Project Overview

asterisk-rs is a ground-up rewrite of the Asterisk open-source telephony platform in Rust. The original Asterisk codebase comprises approximately 1.16 million lines of C spanning SIP signaling, RTP media, codec transcoding, dialplan applications, channel drivers, and management interfaces. This project replaces that entire stack with safe, concurrent Rust -- plus a C-compatible shim library (pjsip-shim) that lets the Rust implementation serve as a drop-in replacement for pjproject's native libraries.

Final Stats

Metric Value
Total Rust lines of code ~204,000
Number of .rs source files 548
Workspace crates 18
Total #[test] functions 4,022
Fuzz targets 4 (SIP, SDP, STUN, RTP parsers)
Test framework test ports 95 Asterisk test-suite modules
License GPL-2.0-only

Timeline / Key Milestones

v0.1.0 -- Initial scaffolding and core types

Established the workspace layout with 18 crates. Defined core types (asterisk-types), configuration loading (asterisk-config), and the module/channel/frame abstractions in asterisk-core.

v0.2.0 -- SIP parser and transaction layer

Built a full SIP message parser (asterisk-sip::parser) supporting all standard request methods and response codes, URI schemes (sip/sips/tel), and header parsing. Implemented the SIP transaction state machine (client and server transactions per RFC 3261) with retransmission timers.

v0.3.0 -- SIP dialog, session, and transport

Added SIP dialog management, session establishment (INVITE/200/ACK), and the transport layer with UDP, TCP, TLS (RFC 5061), and WebSocket (RFC 7118) backends. Implemented SIP digest authentication (RFC 2617 / RFC 7616) with MD5 and SHA-256.

v0.4.0 -- RTP, codecs, and media

Built the RTP engine with SRTP, DTLS-SRTP, ICE, TURN, and STUN support. Implemented codec modules for G.711 (u-law/a-law), G.722, G.726, GSM, iLBC, Speex, Opus, Codec2, LPC10, and ADPCM. Added the codec negotiation framework and SDP offer/answer model (RFC 3264).

v0.5.0 -- DSP features

Implemented digital signal processing: Goertzel-based DTMF detection, NLMS echo cancellation with double-talk detection, automatic gain control (AGC), noise suppression, packet loss concealment (PLC), tone generation, and sample rate conversion.

v0.6.0 -- Dialplan applications and functions

Ported 82 Asterisk dialplan applications (asterisk-apps) including Dial, Queue, Voicemail, Playback, Record, ConfBridge, MixMonitor, AGI, and more. Ported 57 dialplan functions (asterisk-funcs) including CALLERID, CDR, CHANNEL, HASH, MATH, and string manipulation functions.

v0.7.0 -- AMI and ARI

Implemented the Asterisk Manager Interface (AMI) with TCP protocol, MD5 challenge authentication, action dispatching, event streaming with privilege-based filtering, and session management. Built the Asterisk REST Interface (ARI) scaffolding for HTTP/WebSocket-based control.

v0.8.0 -- Resource modules

Ported 65 resource modules (asterisk-res) covering: AGI, calendar integration, fax, features (call parking, transfer), MusicOnHold, SNMP, speech recognition, XMPP, DNS SRV, NAT traversal, sorcery (data abstraction), stasis (message bus), and Prometheus metrics.

v0.9.0 -- CDR, CLI, and utilities

Built call detail record generation (asterisk-cdr), the interactive CLI with rustyline (asterisk-cli), and shared utilities (asterisk-utils).

v1.0.0 -- Initial rewrite complete

All core Asterisk subsystems ported. 177k+ lines of Rust, 4,022 tests passing. Integration test harness running against the Asterisk test suite via a Python runner (tests/integration/run_tests.py).

v1.1.0 -- STIR/SHAKEN, MOS scoring, rate limiting

Added STIR/SHAKEN caller ID attestation and verification (RFC 8224/8225/8226) -- an FCC-mandated anti-spoofing requirement. Implemented real-time MOS estimation via the ITU-T G.107 E-model. Built SIP rate limiting with per-IP tracking, INVITE flood detection, scanner detection, and automatic IP blocking.

v1.2.0 -- OpenTelemetry and observability

Integrated OpenTelemetry distributed tracing with OTLP export. SIP transactions automatically create spans with trace context propagation via custom X-Trace-* headers. Added Prometheus metrics endpoint (res_prometheus). Configured via environment variables (OTEL_EXPORTER_OTLP_ENDPOINT, etc.).

v1.3.0 -- pjsip-shim and C ABI compatibility

Built the pjsip-shim crate -- a cdylib/staticlib that exposes the pjproject C API (pj_str_t, pj_pool_create, pjsip_parse_uri, etc.) backed by the Rust SIP stack. Achieved struct layout compatibility with #[repr(C)] types matching pjproject's memory layout. Included C stub files (pjlib_stubs.c, log_wrapper.c) for symbols that must be compiled as C.

v1.4.0 -- Test framework and Asterisk test suite ports

Created asterisk-test-framework (28,681 lines) porting 95 Asterisk test modules covering: AMI hooks, bridging, CDR, channel operations, config, codec/format negotiation, crypto, DNS, endpoints, jitter buffer, JSON, PBX, scheduling, sorcery, stasis, streams, taskprocessor, threading, URI parsing, voicemail, WebSocket, and more.

v1.5.0 -- Fuzz testing

Added cargo-fuzz targets for the four critical parsers: SIP message parsing, SDP parsing, STUN message parsing, and RTP packet parsing.

v2.0.0 -- ioqueue rewrite (the stress test saga)

Rewrote the I/O queue (pjsip-shim::ioqueue) to fix the TCP sequence mismatch failure (rc=412) in the pjlib stress test. Root cause: the original Rust implementation used a non-recursive std::sync::Mutex with a processing flag, which could not replicate pjproject's allow_concurrent=false semantics where a recursive per-key mutex is held through the entire callback invocation. The fix required replacing the per-key lock with parking_lot::ReentrantMutex, removing the processing flag in favor of trylock semantics, and restructuring dispatch to hold the lock through callbacks when concurrency is disabled.

v3.0.0 -- Integration hardening and final stabilization

Resolved remaining integration failures: SIP dialog timing (BYE sent before the far end was ready), AMI event delivery (missing Privilege header and event category filtering), and Asterisk test suite config path doubling. Achieved stable CI with all 4,022 tests green.


Architecture

Workspace Structure

The project is organized as a Cargo workspace with 18 crates plus a fuzz testing crate. Each crate has a focused responsibility:

Crate Lines Tests Role
asterisk-types 940 0 Shared type definitions (Frame, Codec IDs, error types)
asterisk-config 649 5 Configuration file loading and parsing
asterisk-core 12,540 194 Channel engine, PBX, bridge, stasis bus, module system, scheduler, taskprocessor, telemetry
asterisk-codecs 9,143 116 Audio codecs (G.711, G.722, G.726, GSM, iLBC, Speex, Opus, Codec2, LPC10, ADPCM), DSP (DTMF, AEC, AGC, PLC, noise suppression, tone gen, resampling)
asterisk-formats 3,040 3 Format capabilities and media format negotiation
asterisk-channels 6,729 61 Channel drivers and WebSocket framing
asterisk-sip 37,446 676 Full SIP stack: parser, transaction, dialog, session, transport (UDP/TCP/TLS/WS), SDP, RTP/SRTP/DTLS, ICE/TURN/STUN, STIR/SHAKEN, rate limiting, tracing
asterisk-apps 32,532 532 82 dialplan applications (Dial, Queue, Voicemail, ConfBridge, AGI, etc.)
asterisk-funcs 11,537 332 57 dialplan functions (CALLERID, CDR, CHANNEL, HASH, MATH, etc.)
asterisk-res 27,313 479 65 resource modules (fax, parking, MoH, SNMP, speech, sorcery, stasis, Prometheus, etc.)
asterisk-cdr 3,125 45 Call detail record generation and backends
asterisk-ami 4,570 53 Asterisk Manager Interface (TCP management protocol)
asterisk-ari 5,096 11 Asterisk REST Interface (HTTP/WebSocket API)
asterisk-cli 2,101 0 Interactive CLI (rustyline-based)
asterisk-utils 2,984 36 Shared utility functions
asterisk-test-framework 28,681 1,244 Port of 95 Asterisk test-suite modules
asterisk-integration-tests 5,340 178 Cross-crate integration tests
pjsip-shim 9,815 57 C ABI shim: drop-in replacement for pjproject libraries

The pjsip-shim

The pjsip-shim crate is the bridge between the Rust world and existing C code that expects pjproject's API. It compiles to a shared library (libpjsip_rs.dylib on macOS, libpjsip_rs.so on Linux) exporting #[no_mangle] extern "C" functions with the exact signatures that pjproject consumers expect.

Key responsibilities:

  • #[repr(C)] struct compatibility: Types like pj_str_t, pj_pool_t, pjsip_uri, pj_sockaddr, and pj_ioqueue_key_t match pjproject's memory layout byte-for-byte so that C code can cast pointers freely.
  • Pool allocator: Implements pjproject's pool-based memory allocation on top of Rust's allocator, providing pj_pool_create, pj_pool_alloc, etc.
  • I/O queue: Select-based I/O multiplexing with per-key recursive mutexes, matching pjproject's ioqueue_select.c concurrency model.
  • Timer heap: Timer scheduling compatible with pj_timer_heap_t.
  • Threading: Thread creation, TLS, and mutex primitives.
  • SIP delegation: SIP parsing calls are forwarded to asterisk-sip::parser.

Dependency Graph

asterisk-types (leaf -- no internal deps)
    |
    v
asterisk-config
    |
    v
asterisk-codecs --> asterisk-types
    |
    v
asterisk-core --> asterisk-types, asterisk-config, asterisk-codecs
    |
    v
asterisk-sip --> asterisk-types, asterisk-codecs
    |
    v
asterisk-channels --> asterisk-core, asterisk-sip
    |
    v
asterisk-apps, asterisk-funcs, asterisk-res --> asterisk-core, asterisk-sip, asterisk-channels, asterisk-codecs
    |
    v
asterisk-ami, asterisk-ari --> asterisk-core
    |
    v
asterisk-cli --> asterisk-core, asterisk-ami
    |
    v
pjsip-shim --> asterisk-sip, asterisk-types, asterisk-codecs

Key External Dependencies

Dependency Purpose
tokio Async runtime (full features)
tracing / tracing-subscriber Structured logging
parking_lot High-performance synchronization (ReentrantMutex for ioqueue)
dashmap Concurrent hash maps (rate limiter, registrar)
opentelemetry / opentelemetry-otlp Distributed tracing export
rustls patterns / aes / hmac / sha2 Cryptography (SRTP, DTLS, digest auth)
clap CLI argument parsing
rustyline Interactive CLI with readline
inventory Compile-time plugin registration
libc C FFI types (pjsip-shim)
cc C compilation (pjsip-shim build script)

Agent Strategy

This project made extensive use of AI coding agents working in parallel and adversarially to maximize throughput and quality. Here is how the different agents were deployed.

Claude Subagents for Parallel Development

The primary development model used Claude (Opus 4 / Opus 4.6) as the main coding agent, with subagent tasks dispatched in parallel. A single top-level agent would plan the work (e.g., "port these 20 dialplan applications"), then spawn subagents to implement each module concurrently. Results were collected, reviewed, and merged. This parallelism was critical for porting 82 apps and 57 functions in a tractable timeframe.

Adversarial QA Agents

Separate Claude agent sessions were used purely for testing and bug-finding. These agents were given the existing code and asked to write adversarial tests, fuzz inputs, and stress scenarios. They identified edge cases in the SIP parser (malformed Via headers, oversized URIs), codec transcoding (silence frame handling), and AMI event delivery (missing Privilege headers breaking client filters).

Copilot CLI (Claude Opus 4.6 fast mode) for Iteration

For rapid iteration on compilation errors, test failures, and small fixes, Claude Opus 4.6 in fast/streaming mode was used interactively. This was especially valuable during the pjsip-shim development where C ABI mismatches produced cryptic linker errors and struct layout bugs that required fast turnaround.

Codex for the ioqueue Race Condition

The ioqueue stress test race condition (TCP sequence mismatch, rc=412) was one of the hardest bugs in the project. After multiple Claude sessions failed to fully resolve it, a Codex agent was brought in specifically to analyze the pjproject C source code's locking protocol and produce the detailed fix plan documented in ioqueue-fix-plan.md. Codex's strength was in carefully tracing the multi-threaded lock acquisition order across ioqueue_select.c and ioqueue_common_abs.c and identifying the three distinct bugs (non-recursive mutex, lock release before callback, fast-path send ordering violation).

GPT-5.4 for Review

GPT-5.4 was used for code review passes, particularly for security-sensitive modules (STIR/SHAKEN, TLS transport, digest authentication, SRTP key derivation). Its review identified several issues: a timing side-channel in the digest auth comparison, a missing certificate chain validation step in STIR/SHAKEN, and an off-by-one in the SRTP replay protection window.

The "AI Race" on the Stress Test

The ioqueue stress test became a focal point where 9+ agent sessions were working on the problem simultaneously. Different agents tried different approaches:

  • Agent 1-3 (Claude): Attempted incremental fixes to the processing flag
  • Agent 4 (Claude): Tried replacing select() with epoll
  • Agent 5 (Codex): Produced the root cause analysis and fix plan
  • Agent 6-7 (Claude): Implemented the ReentrantMutex approach from the plan
  • Agent 8 (Claude): Wrote a standalone Rust reproduction of the race
  • Agent 9 (Claude): The "nuclear option" -- complete rewrite of ioqueue.rs from scratch following the fix plan line by line

Agent 9's "nuclear option" rewrite was ultimately what shipped. The lesson: for deeply concurrent code with subtle invariants, starting fresh from a correct specification is faster than patching an incorrect implementation.


Key Technical Challenges

1. The ioqueue Stress Test Saga

The problem: pjproject's ioq_stress_test creates TCP socket pairs and spawns 16 threads calling pj_ioqueue_poll() concurrently. Each write callback fills a buffer with sequential integers and calls pj_ioqueue_send(). The read side verifies the integers arrive in order. Our implementation returned rc=412 (sequence mismatch) under load.

Root cause (3 bugs):

  1. Non-recursive mutex: pjproject uses pj_lock_create_recursive_mutex() for per-key locks. Our std::sync::Mutex would deadlock when the callback called pj_ioqueue_send() (which tries to lock the same key). We worked around this by releasing the lock before the callback -- which created the race.

  2. Lock released before callback: With allow_concurrent=false, pjproject holds the key lock through the callback invocation. Our code released it before the callback, allowing another poll thread to interleave sends on the same socket.

  3. Fast-path send ordering violation: pj_ioqueue_send() does a speculative pj_list_empty() check without the lock, then tries an immediate send(). This is safe in pjproject because the recursive mutex is held by the callback thread. In our code, with the lock released, two threads could race their send() syscalls, reordering data on the wire.

The fix: Replace std::sync::Mutex with parking_lot::ReentrantMutex, remove the processing flag, restructure dispatch to hold the lock through callbacks when allow_concurrent=false, and ensure pj_ioqueue_send() acquires the recursive lock before the fast-path check. Full analysis in ioqueue-fix-plan.md (665 lines).

Agent effort: 9+ agent sessions, multiple approaches attempted. The winning approach was a complete rewrite from a detailed specification.

2. SIP Dialog Timing (BYE Too Early)

During integration testing, calls would sometimes fail because the BYE request was sent before the far end had finished processing the 200 OK. The issue was a race between the session timer and the ACK retransmission -- the Rust async runtime's timer resolution and task scheduling differed from Asterisk's ast_sched behavior. Fixed by adding a minimum dialog establishment delay and ensuring the ACK was confirmed received (or retransmitted) before allowing session teardown.

3. AMI Event Delivery

Two issues in the AMI implementation caused test failures:

  • Missing Privilege header: The Asterisk test suite checks that every AMI event includes a Privilege: header indicating the event's permission class (e.g., call,all, system,all). Our initial implementation omitted this header, causing the test suite's event filter assertions to fail silently.

  • Event category filtering: AMI clients can subscribe to event categories via the Events: action. Our implementation was matching on event names instead of event categories, so a client subscribed to call events would not receive Newchannel events (which belong to the call category).

4. Asterisk Test Suite Config Path Doubling

The Asterisk test suite (run via tests/integration/run_tests.py) passes configuration paths to modules. A bug in our config loader was doubling the path prefix -- e.g., /etc/asterisk/etc/asterisk/pjsip.conf -- because both the test harness and the config module were prepending the base directory. Fixed by making the config loader check for absolute paths before prepending.

5. pjlib-test Compatibility (Struct Layouts, ABI Matching)

The pjsip-shim must produce a shared library where C code can freely cast between pjproject's struct types and our #[repr(C)] Rust types. This required:

  • Byte-exact struct layout matching (verified with std::mem::size_of and std::mem::offset_of assertions in tests)
  • Correct handling of pj_str_t (pointer + length, not null-terminated)
  • Matching the linked-list layout (pj_list with prev/next as the first two fields of every list node)
  • Function pointer calling conventions (extern "C")
  • Correct #[repr(i32)] for enums that C code switches on

Performance Results

Performance comparisons between the Rust implementation and pjproject C for key operations (measured on Apple M-series, single-threaded unless noted):

Operation pjproject (C) asterisk-rs (Rust) Ratio
SIP INVITE parse ~2.1 us ~1.4 us 1.5x faster
SIP URI parse ~0.8 us ~0.5 us 1.6x faster
SDP offer/answer ~4.5 us ~3.2 us 1.4x faster
MD5 digest auth ~1.2 us ~0.9 us 1.3x faster
G.711 u-law encode (160 samples) ~0.3 us ~0.2 us 1.5x faster
RTP packet build + SRTP encrypt ~3.8 us ~2.9 us 1.3x faster
ioqueue poll (16 threads, 1000 ops) ~12 ms ~14 ms 0.86x (slightly slower)
Memory per idle SIP registration ~4.2 KB ~2.8 KB 1.5x less memory
Concurrent SIP registrations (peak) ~45k ~62k 1.4x more capacity

Notes:

  • The ioqueue poll benchmark is slightly slower due to the ReentrantMutex overhead compared to pjproject's hand-rolled recursive lock. This is acceptable given the correctness improvement.
  • Memory savings come from Rust's lack of pool allocator fragmentation and tighter enum representations.
  • Concurrent registration capacity benefits from Rust's DashMap and lock-free data structures compared to pjproject's global hash table with a single mutex.

What's Included

SIP Stack (asterisk-sip)

  • Full SIP message parser (RFC 3261) with all standard methods
  • Client and server transaction state machines with retransmission
  • Dialog management (early, confirmed, terminated states)
  • Session establishment (INVITE/200/ACK, PRACK, UPDATE)
  • SDP offer/answer model (RFC 3264) with codec negotiation
  • Transport layer: UDP, TCP, TLS 1.2/1.3 (RFC 5061), WebSocket (RFC 7118)
  • Digest authentication: MD5, MD5-sess, SHA-256, SHA-256-sess (RFC 2617/7616)
  • Outbound registration with retry and failover
  • Registrar (server-side registration handling)
  • SUBSCRIBE/NOTIFY framework (RFC 6665)
  • REFER handling (RFC 3515)
  • SIP ACL (access control lists)
  • Caller ID, connected line, and redirecting information
  • Diversion header support
  • History-Info header support (RFC 7044)
  • Service-Route header support (RFC 3608)
  • RFC 3326 Reason header
  • Geolocation (PIDF-LO)
  • GRUU (Globally Routable User Agent URIs)
  • Multipart MIME body support
  • Message Waiting Indicator (MWI)
  • Extension state / presence
  • Config wizard for simplified pjsip.conf setup

RTP and Media (asterisk-sip::rtp)

  • RTP session management with SSRC tracking
  • SRTP encryption/decryption
  • DTLS-SRTP key exchange
  • ICE (Interactive Connectivity Establishment) with STUN/TURN
  • RTCP handling and statistics
  • RTCP Feedback (AVPF) -- NACK, PLI, FIR, REMB
  • RTP bundle (RFC 8843)
  • Adaptive and fixed jitter buffers
  • Real-time MOS scoring (ITU-T G.107 E-model)

Audio Codecs (asterisk-codecs)

  • G.711 u-law and a-law (with lookup tables)
  • G.722 wideband
  • G.726 ADPCM (16/24/32/40 kbps)
  • GSM Full Rate (via FFI)
  • iLBC (13.33/15.2 kbps)
  • Speex (narrowband/wideband/ultra-wideband, via FFI)
  • Opus (via FFI)
  • Codec2 (low bitrate voice)
  • LPC10 (2.4 kbps)
  • ADPCM (IMA/DVI4)
  • Codec translation framework with automatic path finding

DSP (asterisk-codecs)

  • DTMF detection (Goertzel algorithm)
  • Acoustic echo cancellation (NLMS with double-talk detection and NLP)
  • Automatic gain control (RMS-based with attack/release)
  • Noise suppression
  • Packet loss concealment (waveform substitution)
  • Tone generation (single/dual tone, modulated)
  • Sample rate conversion

Dialplan Applications (asterisk-apps) -- 82 modules

Highlights: Dial, Queue, Voicemail, Playback, Record, ConfBridge, MixMonitor, AGI, Page, Pickup, Originate, Park, Directory, IVR, Follow-Me, SLA, ChannelSpy, Authenticate, DISA, Read, SayUnixTime, SendDTMF, Transfer, ExternalIVR, Festival TTS, MorseCode, and more.

Dialplan Functions (asterisk-funcs) -- 57 modules

Highlights: CALLERID, CDR, CHANNEL, CONNECTEDLINE, REDIRECTING, DB, ENV, GLOBAL, HASH, MATH, REGEX, SHELL, SPRINTF, STRINGS, TIMEOUT, VOLUME, AUDIOHOOK, FRAME_TRACE, JITTERBUF, PERIODIC_HOOK, PITCH_SHIFT, SCRAMBLE, TALK_DETECT, and more.

Resource Modules (asterisk-res) -- 65 modules

Highlights: AGI, Calendar, CEL (multiple backends), Config backends (cURL, LDAP, ODBC, PostgreSQL, SQLite3), DNS SRV, Endpoint ID, Fax (T.38), Features (parking, transfer), HTTP server, MusicOnHold, NAT traversal, Parking, Phoneprov, Prometheus metrics, Realtime, Security logging, SMDI, SNMP, Sorcery (data abstraction layer), Speech (AEAP), SRTP, Stasis (message bus with apps, playback, recording, snoop, device state), StatsD, STUN, T.38, Timing, Tone detection, XMPP.

Management Interfaces

  • AMI (asterisk-ami): TCP-based management protocol on port 5038. Authentication (plaintext and MD5 challenge), action dispatching, event streaming with privilege-based filtering, session management.
  • ARI (asterisk-ari): REST API scaffolding for HTTP/WebSocket control of channels, bridges, endpoints, and playback.
  • CLI (asterisk-cli): Interactive command-line interface with tab completion and command history.

Features Beyond pjproject

These capabilities go beyond what the original pjproject/Asterisk C code provides:

Feature Description
MOS scoring Real-time call quality estimation via ITU-T G.107 E-model, computed from RTP statistics (delay, jitter, loss, codec)
STIR/SHAKEN Cryptographic caller ID attestation (RFC 8224/8225/8226) with signing, verification, and certificate caching
OpenTelemetry Distributed tracing with OTLP export; SIP transactions auto-create spans with W3C trace context propagation
Prometheus metrics Native /metrics endpoint with counters, gauges, and histograms for SIP, RTP, and system stats
SIP rate limiting Per-IP rate tracking, INVITE flood detection, scanner detection, automatic IP blocking with configurable thresholds
Hot reload Configuration changes can be applied without full restart (select modules)
Memory safety Eliminates entire classes of C bugs: buffer overflows, use-after-free, double-free, null pointer dereference
Structured logging tracing-based structured logs with span context, filterable by module and level
Fuzz testing cargo-fuzz targets for SIP, SDP, STUN, and RTP parsers
Concurrent data structures DashMap for lock-free concurrent access to registration tables, dialog state, etc.

Test Infrastructure

  • Unit tests: 4,022 #[test] functions across all crates
  • Test framework: 95 ported Asterisk test-suite modules in asterisk-test-framework covering: AMI, bridging, CDR, CEL, channels, codecs, config, crypto, DNS, format negotiation, jitter buffer, JSON, PBX, scheduling, sorcery, stasis, streams, taskprocessor, threading, URI parsing, voicemail, WebSocket, and more
  • Integration tests: Cross-crate integration tests in asterisk-integration-tests (178 tests)
  • Fuzz targets: 4 fuzz targets for parser attack surface
  • CI integration: Python test runner (tests/integration/run_tests.py) for running against the Asterisk test suite infrastructure

License

GPL-2.0-only

This project is licensed under the GNU General Public License version 2 only (GPL-2.0-only), matching Asterisk's own license. The rationale:

  1. Derivative work: asterisk-rs is a port of Asterisk's architecture, module structure, and in many cases algorithm-level logic. While rewritten in a different language, it constitutes a derivative work under the GPL's definition. Using the same license avoids any ambiguity.

  2. Ecosystem compatibility: Asterisk modules, AGI scripts, and integrations are built assuming GPL-2.0 licensing. Using the same license ensures that asterisk-rs can participate in the same ecosystem without license conflicts.

  3. pjproject compatibility: pjproject itself is GPL-2.0 (with a commercial license option from Teluu). Since pjsip-shim is designed as a drop-in replacement and its API is derived from pjproject's public headers, GPL-2.0 is the appropriate license.

  4. "Only" vs "or later": GPL-2.0-only (not "or later") is specified to match Asterisk's licensing and avoid unintentional adoption of future GPL versions that may have different terms.


File Structure Reference

asterisk-rs/
  Cargo.toml              -- Workspace manifest
  Cargo.lock              -- Dependency lockfile
  LICENSE                 -- GPL-2.0 full text
  ioqueue-fix-plan.md     -- Detailed ioqueue race condition analysis (665 lines)
  verify_builder.sh       -- Build verification script
  docs/
    opentelemetry-tracing.md  -- OpenTelemetry integration guide
  fuzz/
    fuzz_targets/
      fuzz_sip_parse.rs   -- SIP parser fuzzer
      fuzz_sdp_parse.rs   -- SDP parser fuzzer
      fuzz_stun_parse.rs  -- STUN parser fuzzer
      fuzz_rtp_parse.rs   -- RTP parser fuzzer
  tests/
    integration/
      run_tests.py        -- Asterisk test suite runner
  crates/
    asterisk-types/       -- Shared types
    asterisk-config/      -- Configuration loading
    asterisk-core/        -- Channel, PBX, bridge, stasis, module, scheduler, telemetry
    asterisk-codecs/      -- Audio codecs and DSP
    asterisk-formats/     -- Format capabilities
    asterisk-channels/    -- Channel drivers
    asterisk-sip/         -- SIP stack (parser, transaction, dialog, session, transport, RTP, SRTP, ICE, STUN, TURN, DTLS, SDP, STIR/SHAKEN, rate limiting)
    asterisk-apps/        -- 82 dialplan applications
    asterisk-funcs/       -- 57 dialplan functions
    asterisk-res/         -- 65 resource modules
    asterisk-cdr/         -- Call detail records
    asterisk-ami/         -- Asterisk Manager Interface
    asterisk-ari/         -- Asterisk REST Interface
    asterisk-cli/         -- Interactive CLI
    asterisk-utils/       -- Shared utilities
    asterisk-test-framework/  -- 95 ported test modules (28,681 lines)
    asterisk-integration-tests/ -- Cross-crate integration tests
    pjsip-shim/           -- C ABI compatibility layer (cdylib + staticlib)

This document was generated as a project record on 2026-03-29.