Rewriting Asterisk in Rust -- from 1.16 million lines of C to a modern, memory-safe telephony platform.
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.
| 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 |
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.
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.
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.
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).
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.
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.
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.
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.
Built call detail record generation (asterisk-cdr), the interactive CLI with
rustyline (asterisk-cli), and shared utilities (asterisk-utils).
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).
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.
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.).
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.
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.
Added cargo-fuzz targets for the four critical parsers: SIP message parsing,
SDP parsing, STUN message parsing, and RTP packet parsing.
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.
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.
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 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 likepj_str_t,pj_pool_t,pjsip_uri,pj_sockaddr, andpj_ioqueue_key_tmatch 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.cconcurrency 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.
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
| 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) |
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.
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.
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).
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.
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 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 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.
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):
-
Non-recursive mutex: pjproject uses
pj_lock_create_recursive_mutex()for per-key locks. Ourstd::sync::Mutexwould deadlock when the callback calledpj_ioqueue_send()(which tries to lock the same key). We worked around this by releasing the lock before the callback -- which created the race. -
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. -
Fast-path send ordering violation:
pj_ioqueue_send()does a speculativepj_list_empty()check without the lock, then tries an immediatesend(). 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 theirsend()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.
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.
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 tocallevents would not receiveNewchannelevents (which belong to thecallcategory).
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.
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_ofandstd::mem::offset_ofassertions in tests) - Correct handling of
pj_str_t(pointer + length, not null-terminated) - Matching the linked-list layout (
pj_listwithprev/nextas 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 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
DashMapand lock-free data structures compared to pjproject's global hash table with a single mutex.
- 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 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)
- 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
- 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
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.
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.
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.
- 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.
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. |
- Unit tests: 4,022
#[test]functions across all crates - Test framework: 95 ported Asterisk test-suite modules in
asterisk-test-frameworkcovering: 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
This project is licensed under the GNU General Public License version 2 only (GPL-2.0-only), matching Asterisk's own license. The rationale:
-
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.
-
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.
-
pjproject compatibility: pjproject itself is GPL-2.0 (with a commercial license option from Teluu). Since
pjsip-shimis designed as a drop-in replacement and its API is derived from pjproject's public headers, GPL-2.0 is the appropriate license. -
"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.
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.