Initial scoping: architecture + Asterisk→Rust port plan
Establish rutster — a memory-safe, API-first, security-first telephony platform; spiritual successor to Asterisk for the WebRTC/microservices era. - README: project framing, design pillars, open decisions - docs/ARCHITECTURE.md: three-plane (control/media/app) model - docs/PORT_PLAN.md: every Asterisk subsystem mapped to a disposition (core / WASM-plugin / service / edge-FFI / dropped / replaced) with rationale Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C2bfD7MkqEdfnMXxXBu456
This commit is contained in:
19
.gitignore
vendored
Normal file
19
.gitignore
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
# Rust
|
||||
/target
|
||||
**/target
|
||||
**/*.rs.bk
|
||||
*.pdb
|
||||
|
||||
# Cargo.lock is committed (this is an application workspace, not a library)
|
||||
|
||||
# Env / secrets
|
||||
.env
|
||||
.env.*
|
||||
*.pem
|
||||
*.key
|
||||
|
||||
# Editor / OS
|
||||
.DS_Store
|
||||
*.swp
|
||||
.idea/
|
||||
.vscode/
|
||||
50
README.md
Normal file
50
README.md
Normal file
@@ -0,0 +1,50 @@
|
||||
# Rutster
|
||||
|
||||
A memory-safe, API-first, security-first telephony platform — a spiritual successor
|
||||
to Asterisk for the WebRTC/microservices era, written in Rust.
|
||||
|
||||
> Not a port of Asterisk. A reimagining that keeps the *power* — era-bridging breadth,
|
||||
> "wire anything to anything," a deep feature library — while dropping the legacy
|
||||
> hardware/dead-protocol half and fixing Asterisk's two chronic wounds:
|
||||
> memory-safety CVEs and toll fraud, at the design level.
|
||||
|
||||
## What it is / isn't
|
||||
|
||||
- **Is:** SIP (TLS-only) + WebRTC signaling, a real-time media plane (transcode / mix /
|
||||
DSP), a programmable call model exposed as a REST/gRPC API + event stream, a
|
||||
WASM-sandboxed plugin runtime, and a library of telephony features delivered as
|
||||
isolated services.
|
||||
- **Isn't:** A TDM/PSTN-hardware PBX. No DAHDI, no Sangoma/Digium cards, no ISDN/SS7,
|
||||
no IAX2/H.323/SCCP/MGCP/Unistim. PSTN reach is via SIP trunks / SBC only.
|
||||
|
||||
## Core design pillars
|
||||
|
||||
1. **Memory-safe by construction** — Rust everywhere on the hot path; fuzzed, sans-IO
|
||||
protocol parsers. Eliminates the buffer-overflow/RCE CVE class.
|
||||
2. **Isolation over in-process modules** — extensions run in a **WASM sandbox**, not as
|
||||
`.so` files in the daemon's address space. One bad plugin can't crash the box or
|
||||
read another tenant's media. (The Asterisk `core show locks` era ends here.)
|
||||
3. **Secure & deny-by-default** — mandatory TLS/SRTP, deny-by-default routing,
|
||||
built-in toll-fraud controls, mTLS gRPC admin (no plaintext AMI), hard multi-tenancy.
|
||||
4. **Three planes, scaled independently** — control / media / app. The media datapath
|
||||
stays tight; business logic is microservices and plugins around it.
|
||||
5. **Observable & declarative** — OpenTelemetry call traces across services;
|
||||
config-as-data, not imperative `.conf` files edited on a box.
|
||||
|
||||
## Layout
|
||||
|
||||
- [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) — the three-plane model and pillars.
|
||||
- [`docs/PORT_PLAN.md`](docs/PORT_PLAN.md) — **the spine**: every Asterisk subsystem mapped
|
||||
to a disposition (core / plugin / service / edge-FFI / dropped) with rationale.
|
||||
|
||||
## Status
|
||||
|
||||
Scoping. No code yet — the port plan defines the crate/service boundaries that the
|
||||
workspace will be scaffolded from next.
|
||||
|
||||
## Open decisions
|
||||
|
||||
- **License** — undecided (Asterisk is GPLv2+commercial; rutster's model is TBD).
|
||||
- **SIP stack** — FFI to pjproject vs. front with an SBC (Kamailio/drachtio) vs. a
|
||||
long-term pure-Rust stack. See port plan §1.
|
||||
- **WASM runtime** — `wasmtime` is the presumptive default (component model).
|
||||
54
docs/ARCHITECTURE.md
Normal file
54
docs/ARCHITECTURE.md
Normal file
@@ -0,0 +1,54 @@
|
||||
# Rutster Architecture
|
||||
|
||||
## The reframe
|
||||
|
||||
Asterisk's power was: *one process, load any `.so`, wire anything to anything in the
|
||||
dialplan.* That composability is the thing to match — but it does **not** require a
|
||||
1.2M-LOC monolith. Rutster delivers the same "build anything" through a different
|
||||
substrate:
|
||||
|
||||
- a **small hardened core** (media + signaling glue + call model),
|
||||
- a **WASM plugin runtime** for safe, third-party-extensible logic,
|
||||
- **declarative routing** as data for the common path,
|
||||
- a **programmable API** (REST/gRPC + event stream) modeled on Asterisk's ARI.
|
||||
|
||||
More extensible than Asterisk, because extensions are safe to run from people you
|
||||
don't fully trust.
|
||||
|
||||
## Three planes
|
||||
|
||||
### Control plane (stateless-ish, horizontally scalable)
|
||||
The ARI-style resource API (channels / bridges / endpoints / recordings / playbacks)
|
||||
over REST + gRPC + a WebSocket/SSE event stream. Registrar, routing, auth. This is
|
||||
where "the dialplan" disappears — replaced by declarative routing + external services
|
||||
reacting to call events (the Twilio / ARI-Stasis model). Asterisk's
|
||||
`rest-api/api-docs/*.json` is a reusable spec for the resource model.
|
||||
|
||||
### Media plane (stateful, latency-pinned, scaled separately)
|
||||
RTP/SRTP termination, mixing/bridging (softmix), transcoding, record/playback. A
|
||||
controllable media node driven over gRPC by the control plane. Built on the Rust
|
||||
WebRTC media ecosystem (`str0m` sans-IO design, `webrtc-rs`). **The media datapath
|
||||
stays tight** — do not over-decompose it across service hops; latency and failure
|
||||
modes compound.
|
||||
|
||||
### App plane (your services + plugins, outside the core)
|
||||
IVR, queues, voicemail, dialers, custom routing — driven via the API, deployed
|
||||
independently. WASM plugins for in-call logic that needs to run close to the core;
|
||||
microservices for stateful/business/billing logic.
|
||||
|
||||
## Cross-cutting
|
||||
|
||||
- **Event bus** (NATS / Redis Streams / Kafka) replaces Asterisk's internal Stasis bus
|
||||
for cross-service events; a lightweight in-core dispatcher handles intra-core.
|
||||
- **State store** replaces `astdb` + realtime/sorcery.
|
||||
- **Security is load-bearing, not a row:** memory-safe fuzzed parsers, TLS/SRTP
|
||||
mandatory, deny-by-default routing + toll-fraud engine, mTLS gRPC admin (no AMI),
|
||||
WASM tenant isolation, SBOM + KMS/Vault for secrets.
|
||||
- **Observability:** OpenTelemetry traces that follow a single call across
|
||||
signaling → media → app services.
|
||||
|
||||
## Biggest technical risk
|
||||
|
||||
The **SIP stack**. No mature pure-Rust option exists → FFI pjproject or front the edge
|
||||
with a battle-tested SBC initially; treat a pure-Rust stack as a long-term goal, not a
|
||||
v1 dependency. Everything else builds on the existing Rust media ecosystem.
|
||||
211
docs/PORT_PLAN.md
Normal file
211
docs/PORT_PLAN.md
Normal file
@@ -0,0 +1,211 @@
|
||||
# Rutster — Asterisk → Rust Capability Port Plan
|
||||
|
||||
This is the spine of the project. It walks the Asterisk subsystem surface and assigns
|
||||
every capability a **disposition** in the rutster architecture, with a one-line
|
||||
rationale. The crate/service boundaries fall out of the "Core / Service" rows; the
|
||||
threat model hangs off the "attack surface" of each row.
|
||||
|
||||
Grounded against the Asterisk 22.10.1 tree (~1.18M LOC C/H).
|
||||
|
||||
## Disposition legend
|
||||
|
||||
| | Disposition | Meaning |
|
||||
|---|---|---|
|
||||
| 🦀 | **Core** | In the hardened, memory-safe Rust core. Reserved for the hot media path, call model, and signaling glue — fast, always-present, trusted. |
|
||||
| 🧩 | **Plugin (WASM)** | Sandboxed extension. Logic that benefits from isolation and third-party extensibility. Cannot crash the core or cross tenant boundaries. |
|
||||
| ☁️ | **Service** | Independent microservice. Stateful, independently-scaled, or business/billing logic. Talks over API + event bus. |
|
||||
| 🔌 | **Edge / FFI** | Wrap mature external C (pjproject/spandsp) or front with an SBC. Used where a pure-Rust rewrite is a tar pit. |
|
||||
| ⛔ | **Drop** | Legacy hardware or dead protocol. Gone. |
|
||||
| 🔁 | **Replace** | Capability survives but the mechanism is entirely redesigned (no 1:1 mapping). |
|
||||
|
||||
## Design rules (the heuristics behind every row)
|
||||
|
||||
1. Hot media path & the call model → **Core**. Trusted, fast, always-on.
|
||||
2. Anything that benefits from isolation or third-party extension → **Plugin**.
|
||||
3. Stateful, independently-scaled, or business/billing logic → **Service**.
|
||||
4. Mature C that's a tar pit to rewrite (SIP) → **Edge/FFI**, with a pure-Rust ambition.
|
||||
5. Legacy hardware / dead protocols → **Drop**.
|
||||
6. Security & multi-tenancy are cross-cutting — never a row, always a property.
|
||||
|
||||
---
|
||||
|
||||
## 1. Signaling & channel drivers (`channels/`, `res/res_pjsip*`)
|
||||
|
||||
| Asterisk subsystem | Module(s) | Disp. | Rationale |
|
||||
|---|---|---|---|
|
||||
| SIP signaling | `chan_pjsip` + `res_pjsip*` (48 mods) | 🔌 Edge/FFI | No mature pure-Rust SIP stack. FFI pjproject or front an SBC; pure-Rust long-term. The single biggest risk item. |
|
||||
| ↳ registration (in/out) | `res_pjsip_registrar`, `_outbound_registration` | 🦀 Core | Registrar state is core control-plane; back it with the state store. |
|
||||
| ↳ SDP / media negotiation | `res_pjsip_session`, `_sdp_rtp` | 🦀 Core | Offer/answer drives the media plane directly. |
|
||||
| ↳ auth | `res_pjsip_outbound_authenticator_digest`, etc. | 🦀 Core | Digest + token auth, deny-by-default, rate-limited. Security-critical. |
|
||||
| ↳ NAT / ICE / rtcp | `res_pjsip_nat`, `res_rtp_asterisk` ICE | 🦀 Core | ICE/STUN/TURN via `str0m`/`webrtc-rs`. |
|
||||
| ↳ pub/sub (presence, MWI, BLF) | `res_pjsip_pubsub`, `_exten_state`, `_mwi` | 🦀 Core + ☁️ | Signaling in core; presence/MWI state aggregation as a service. |
|
||||
| ↳ T.38 fax | `res_pjsip_t38` | ☁️ Service | Isolate fax entirely (see §5). |
|
||||
| WebRTC signaling | `chan_websocket`, `res_http_websocket` | 🦀 Core | First-class ingress. WSS + DTLS-SRTP via the media stack. |
|
||||
| External media | `chan_audiosocket` | 🦀 Core | Modern, relevant pattern (stream media to an external process); keep as a media tap/source API. |
|
||||
| Local console audio | `chan_console` | 🧩 Plugin | Dev/testing convenience; not core. |
|
||||
| RTP-only pseudo-channel | `chan_rtp`, `chan_bridge_media` | 🦀 Core | Media-plane primitives. |
|
||||
| IAX2 | `chan_iax2` | ⛔ Drop | Dead inter-Asterisk protocol. SIP trunks instead. |
|
||||
| TDM / analog / ISDN | `chan_dahdi`, `sig_analog`, `sig_pri`, `sig_ss7` | ⛔ Drop | No hardware era. PSTN via SIP trunk / SBC. |
|
||||
| H.323 | `addons/chan_ooh323` | ⛔ Drop | Dead protocol. |
|
||||
| SCCP / Skinny, MGCP | (Skinny/MGCP) | ⛔ Drop | Dead protocols. |
|
||||
| Unistim | `chan_unistim` | ⛔ Drop | Dead vendor protocol. |
|
||||
| XMPP / Jingle | `chan_motif`, `res_xmpp` | ⛔ Drop | Dead path. |
|
||||
|
||||
---
|
||||
|
||||
## 2. Media plane (`main/rtp_engine.c`, `res_rtp_asterisk`, `bridges/`, `main/dsp.c`)
|
||||
|
||||
| Asterisk subsystem | Module(s) | Disp. | Rationale |
|
||||
|---|---|---|---|
|
||||
| RTP / RTCP engine | `rtp_engine.c`, `res_rtp_asterisk` | 🦀 Core | **Crown jewel.** Built on `str0m`/`webrtc-rs`, sans-IO, dedicated timing (not the shared tokio pool). |
|
||||
| SRTP / DTLS | `res_srtp` | 🦀 Core | Mandatory-by-default encryption. |
|
||||
| Bridging framework | `main/bridge.c` | 🦀 Core | The 2-party + N-party call topology engine. |
|
||||
| ↳ softmix conference mixer | `bridges/bridge_softmix` | 🦀 Core | N-party mixing on the hot path. |
|
||||
| ↳ simple / native-RTP bridge | `bridge_simple`, `bridge_native_rtp` | 🦀 Core | Direct media flow (re-INVITE peers together) when no mixing needed. |
|
||||
| ↳ holding bridge | `bridge_holding` | 🦀 Core | Parking/hold media state. |
|
||||
| ↳ native DAHDI bridge | `bridge_native_dahdi` | ⛔ Drop | Hardware. |
|
||||
| DSP (DTMF/MF detect, silence, tone) | `main/dsp.c` | 🦀 Core | Media-plane primitive; exposed to plugins as events. |
|
||||
| Echo cancellation | (hardware / sw) | 🔌 Edge/FFI | No mature pure-Rust EC; FFI speexdsp / WebRTC APM. |
|
||||
| Audio hooks (tap/inject/volume) | `main/audiohook.c` | 🦀 Core | Primitive behind recording, ChanSpy, whisper/barge. |
|
||||
| Music on hold | `res_musiconhold` | 🦀 Core | Just a media source; small, keep in core (asset from object storage). |
|
||||
| Jitter buffer | `func_jitterbuffer`, abstract jb | 🦀 Core | Quality-critical; part of the RTP path. |
|
||||
|
||||
---
|
||||
|
||||
## 3. Call model & PBX core (`main/`)
|
||||
|
||||
| Asterisk subsystem | Module(s) | Disp. | Rationale |
|
||||
|---|---|---|---|
|
||||
| Channel abstraction | `main/channel.c` (`ast_channel`) | 🦀 Core | The unifying "leg" object (signaling + media state). Reimagined as a `Channel`/leg. |
|
||||
| PBX / dialplan engine | `main/pbx.c` | 🔁 Replace | → declarative routing (data) + event-driven apps. No `extensions.conf`. |
|
||||
| Call features (transfer/park/pickup) | `res_features`, `res_parking` | 🦀 Core | Call-control primitives, exposed via the API. |
|
||||
| Scheduler / taskprocessor / threadpool | `main/sched.c`, `taskprocessor.c`, `threadpool.c` | 🦀 Core | tokio for control; dedicated timing threads + timer wheel for the 20ms media loop. |
|
||||
| Internal message bus (Stasis) | `main/stasis*.c` | 🔁 Replace | In-core dispatcher for intra-core; external event bus (NATS/Kafka) for cross-service. |
|
||||
| Module loader | `main/loader.c` | 🔁 Replace | → WASM host + service registry. No in-process `.so`. |
|
||||
| ACL / named ACL | `main/acl.c`, `res_named_acl` | 🦀 Core | Security primitive; policy-driven. |
|
||||
| astdb (internal KV) | `main/db.c` | 🔁 Replace | → state store (embedded KV or external). |
|
||||
|
||||
---
|
||||
|
||||
## 4. Dialplan & programmability (`pbx/`, `res_agi`, `res_ari`, `manager`)
|
||||
|
||||
| Asterisk subsystem | Module(s) | Disp. | Rationale |
|
||||
|---|---|---|---|
|
||||
| `extensions.conf` dialplan | `pbx_config` | 🔁 Replace | Declarative routing as data (GitOps) for the 90% case. |
|
||||
| AEL / Lua dialplan | `pbx_ael`, `pbx_lua` | ⛔ Drop | Replaced by WASM call-flow + routing config. |
|
||||
| Realtime dialplan | `pbx_realtime` | 🔁 Replace | Routing in the config/state layer. |
|
||||
| Call files / spool | `pbx_spool` | 🔁 Replace | → originate via API. |
|
||||
| Macro / Gosub / Stack | `app_stack`, `app_macro` | 🔁 Replace | → WASM call-flow logic. |
|
||||
| AGI / FastAGI | `res_agi` | 🔁 Replace | → WASM plugins + gRPC. Same "external program controls a call," sandboxed and typed. |
|
||||
| ARI (REST + stasis apps) | `res_ari*`, `res_stasis*` | 🦀 Core | **Becomes THE API** — the control-plane resource model. `api-docs/*.json` is the reusable spec. |
|
||||
| AMI (manager) | `main/manager*.c` | 🔁 Replace | Drop the plaintext TCP protocol → mTLS gRPC + RBAC + audit log. |
|
||||
| CLI | `main/cli.c` | 🔁 Replace | Thin CLI that's an API client, not an in-process console. |
|
||||
| DUNDi (distributed routing) | `pbx_dundi` | ⛔ Drop | Dead/niche. |
|
||||
| ENUM lookup | `func_enum` | 🧩 Plugin | Routing-time lookup; pluggable. |
|
||||
|
||||
---
|
||||
|
||||
## 5. Applications (`apps/`)
|
||||
|
||||
| Asterisk app | Module | Disp. | Rationale |
|
||||
|---|---|---|---|
|
||||
| Dial / originate | `app_dial`, `app_originate` | 🦀 Core | Core call origination, exposed via the API. |
|
||||
| Queues / ACD | `app_queue` | ☁️ Service | Stateful, independently scaled, business logic. |
|
||||
| Voicemail | `app_voicemail` | ☁️ Service | Stateful storage + business logic; isolate it. |
|
||||
| Conferencing | `app_confbridge` | 🦀 Core + ☁️ | Mixing in core (softmix); orchestration/features as a service. |
|
||||
| MeetMe | `app_meetme` | ⛔ Drop | DAHDI-timing legacy; ConfBridge supersedes. |
|
||||
| Recording | `app_mixmonitor`, `app_monitor` | 🦀 Core + ☁️ | Audiohook tap in core; storage/lifecycle as a recording service. |
|
||||
| ChanSpy / whisper / barge | `app_chanspy` | 🦀 Core | Audiohook primitive; gated by RBAC. |
|
||||
| Answering-machine detect | `app_amd` | 🦀 Core + 🧩 | DSP primitive in core; policy/thresholds as a plugin. |
|
||||
| IVR primitives (playback/read/say) | `app_playback`, `app_read`, `app_sayunixtime`, `app_directory` | 🦀 Core | Media primitives (play/collect-digits/say) exposed to WASM apps. |
|
||||
| Echo / test | `app_echo`, `app_milliwatt` | 🦀 Core | Trivial diagnostics. |
|
||||
| FollowMe | `app_followme` | 🧩 Plugin | Routing policy → WASM/service. |
|
||||
| Speech recognition | `app_speech_utils`, `res_speech` | ☁️ Service | Modern ASR is external; expose as a service integration. |
|
||||
| Fax | `res_fax`, `res_fax_spandsp` (T.38) | ☁️ Service (FFI) | Niche, isolate fully; spandsp via FFI. Optional. |
|
||||
|
||||
---
|
||||
|
||||
## 6. Telephony features / subscriptions
|
||||
|
||||
| Asterisk subsystem | Module(s) | Disp. | Rationale |
|
||||
|---|---|---|---|
|
||||
| Presence / BLF | `res_pjsip_pubsub`, `res_pjsip_exten_state` | 🦀 Core + ☁️ | Signaling in core; state aggregation service. |
|
||||
| MWI (message-waiting) | `res_mwi_external`, `app_voicemail` MWI | ☁️ Service | Tied to the voicemail service. |
|
||||
| STIR/SHAKEN (attestation) | `res_stir_shaken` | ☁️ Service | **Keep — modern, anti-robocall/fraud.** Core to the security story. |
|
||||
| Call recording lifecycle | `app_mixmonitor` + storage | ☁️ Service | Object-storage backed, retention policy, tenant-scoped. |
|
||||
| CDR (call detail records) | `cdr/`, `cdr_*` | ☁️ Service | Event stream → billing/analytics pipeline. |
|
||||
| CEL (channel event logging) | `cel/`, `cel_*` | ☁️ Service | Folded into the unified event bus + analytics. |
|
||||
|
||||
---
|
||||
|
||||
## 7. Codecs & formats (`codecs/`, `formats/`)
|
||||
|
||||
| Codec / format | Module | Disp. | Rationale |
|
||||
|---|---|---|---|
|
||||
| G.711 a-law / µ-law | `codec_alaw`, `codec_ulaw`, `codec_a_mu` | 🦀 Core | Trivial, ubiquitous. Native Rust. |
|
||||
| G.722 (HD) | `codec_g722` | 🦀 Core | Common wideband. Native Rust. |
|
||||
| Opus | (external `codec_opus`) | 🦀 Core (FFI) | WebRTC default; libopus via FFI. |
|
||||
| Sample-rate resample | `codec_resample` | 🦀 Core | Needed for any transcoding/mixing. |
|
||||
| GSM | `codec_gsm` | 🧩 Plugin (FFI) | Optional; FFI libgsm. |
|
||||
| G.726 / G.729 | `codec_g726` / (external) | 🧩 Plugin (FFI) | Optional; G.729 now patent-free. |
|
||||
| Speex / iLBC / LPC10 / ADPCM / codec2 | `codec_speex`, `codec_ilbc`, … | ⛔ Drop | Obsolete; drop or community plugin. |
|
||||
| Hardware transcode | `codec_dahdi` | ⛔ Drop | Hardware. |
|
||||
| File formats (wav/sln/ogg-opus) | `format_wav`, `format_sln`, … | 🦀 Core | Small set for prompts/recordings in core; rest as plugins. |
|
||||
| Legacy file formats (gsm/g729/g726 files) | `format_*` | 🧩 Plugin | Optional. |
|
||||
|
||||
---
|
||||
|
||||
## 8. Config, state & data (`res_config_*`, `res_sorcery*`)
|
||||
|
||||
| Asterisk subsystem | Module(s) | Disp. | Rationale |
|
||||
|---|---|---|---|
|
||||
| `.conf` files | `main/config.c` | 🔁 Replace | Config-as-data (declarative, validated, GitOps). |
|
||||
| Sorcery (object config abstraction) | `res_sorcery*` | 🔁 Replace | Typed config + state-store layer. |
|
||||
| Realtime backends (ODBC/PgSQL/SQLite/cURL/LDAP) | `res_config_*` | 🔁 Replace | One config/state service with pluggable backends. |
|
||||
| HTTP media cache | `res_http_media_cache` | 🦀 Core | Prompt/asset fetch → object storage + cache. |
|
||||
| Security event logging | `res_security_log` | 🦀 Core | Structured audit log; security-critical. |
|
||||
|
||||
---
|
||||
|
||||
## 9. Management & APIs
|
||||
|
||||
| Asterisk surface | Module(s) | Disp. | Rationale |
|
||||
|---|---|---|---|
|
||||
| ARI (REST resource model + event WS) | `res_ari*` | 🦀 Core | The control-plane API. Reuse the resource model. |
|
||||
| AMI (plaintext TCP admin) | `manager*.c` | 🔁 Replace | → mTLS gRPC + RBAC + audit. No plaintext admin channel. |
|
||||
| HTTP server | `res_http*` | 🦀 Core | TLS-only; axum/hyper. |
|
||||
| CLI | `cli.c` | 🔁 Replace | API-client CLI. |
|
||||
|
||||
---
|
||||
|
||||
## 10. New subsystems (no Asterisk equivalent)
|
||||
|
||||
These are the "modern" deltas — load-bearing, not optional polish.
|
||||
|
||||
| Subsystem | Disp. | Purpose |
|
||||
|---|---|---|
|
||||
| WASM plugin host | 🦀 Core | Sandboxed runtime (`wasmtime`) for extensions. The isolation boundary. |
|
||||
| Multi-tenancy / isolation | 🦀 Core | Per-tenant keys, quotas, media separation, RBAC. |
|
||||
| Toll-fraud / anomaly engine | ☁️ Service | Deny-by-default routing, spend caps, rate limits, pattern detection. The #1 real-world Asterisk wound. |
|
||||
| Secrets / KMS | 🦀 Core | Vault/KMS integration; no plaintext credentials in config. |
|
||||
| Observability (OTel) | 🦀 Core | Distributed traces that follow a single call across services. |
|
||||
| Event bus | ☁️ Service | NATS/Kafka/Redis Streams; replaces cross-service Stasis. |
|
||||
| SBOM / supply chain | — | cargo-deny, SBOM generation, reproducible builds. |
|
||||
| Fuzzing harness | — | Continuous fuzzing of every wire parser (SIP/SDP/RTP). |
|
||||
|
||||
---
|
||||
|
||||
## Phasing (maps to the roadmap)
|
||||
|
||||
- **Phase 0 — Media core.** RTP/SRTP endpoint, G.711+Opus, 2-party bridge, record+playback. (§2, §7). The riskiest/most valuable proof.
|
||||
- **Phase 1 — Control plane + API.** ARI-modeled REST/gRPC + event stream, auth, event bus, multi-tenancy. (§4, §9, §10).
|
||||
- **Phase 2 — Signaling.** WebRTC ingress first, then SIP via FFI/SBC. (§1).
|
||||
- **Phase 3 — Conferencing + DSP + IVR primitives.** Softmix, transcoding matrix, DTMF/IVR. (§2, §5).
|
||||
- **Phase 4 — Feature services.** Registrar, presence/MWI, queues, voicemail, recording, CDR, STIR/SHAKEN — as services/plugins. (§5, §6).
|
||||
|
||||
## Open decisions
|
||||
|
||||
- **SIP:** FFI pjproject vs. SBC front (Kamailio/drachtio) vs. pure-Rust (`ezk-sip`). Affects §1 heavily.
|
||||
- **WASM runtime:** `wasmtime` component model (presumptive).
|
||||
- **Event bus:** NATS vs. Kafka vs. Redis Streams.
|
||||
- **License** (see README).
|
||||
Reference in New Issue
Block a user