-
Notifications
You must be signed in to change notification settings - Fork 2
Features
This page lists every chan_sofia capability one by one. Each entry names what
it does and where it lives in the tree, so the source stays authoritative. The
companion deep dive is Chan-Sofia; WebRTC has its own page
(WebRTC); the security posture is Security.
chan_sofia registers the SIP channel type and the sippeers realtime
family, so it is mutually exclusive with chan_sip — load one or the other.
Phones and softphones register their location so the PBX knows where to send
their calls, with credential checks, per-peer source ACLs, and unknown-peer
rejection. sofia_process_register() at channels/chan_sofia.c:7747; per-peer
ACL and unknown-peer challenge in the same path.
Minimum and maximum registration lifetimes are enforced; a too-short refresh
gets a 423 Interval Too Brief with Min-Expires, which blunts
registration-flood abuse. sofia_check_register_expiry() at
channels/chan_sofia.c:2325.
Each phone's reachable Contact is stored under peer->lock, and a Contact-less
REGISTER is answered as a pure "where am I registered?" query without changing
state. sofia_update_peer_contacts() and sofia_respond_register_query() in
channels/chan_sofia.c.
register => lines register the PBX to upstream providers so inbound carrier
calls reach you, with scheduled re-registration. sofia_do_register() issuing
nua_register at channels/chan_sofia.c:13985.
A provider's answer (success, expiry, learned GRUU / Service-Route / Path /
outbound state) is consumed and surfaced as an AMI Registry event.
nua_r_register case at channels/chan_sofia.c:10809.
The PBX periodically pings registered phones with SIP OPTIONS to confirm
reachability and measure round-trip time, marking dead peers unreachable.
sofia_qualify_peer() at channels/chan_sofia.c:10495; periodic driver and
on-demand async probe in the same area.
Optional tiny periodic media packets keep NAT/firewall pinholes open during a
call or on hold. ast_rtp_instance_set_keepalive() driven by
peer->rtpkeepalive at channels/chan_sofia.c:1483.
The call-setup engine: incoming calls into the dialplan, outgoing calls to
peers and trunks. sofia_process_invite() and sofia_process_reinvite(),
dispatched from nua_i_invite at channels/chan_sofia.c:10750.
Incoming calls can be challenged for a password so only authenticated users
place calls, with toll-fraud guards for unknown and guest callers.
sofia_verify_digest_auth() at channels/chan_sofia.c:5464; alwaysauthreject
challenge and allowguest=no 403 in the same path.
Passwords are verified with classic MD5 or the stronger SHA-256, selectable per
deployment, with anti-downgrade so the server accepts only an algorithm it
offered. SOFIA_DIGEST_MD5/SHA256 and auth_algorithms enum in
channels/chan_sofia.c:6713-6796 and
channels/sofia/include/chan_sofia_internal.h:91-93.
Each challenge uses a fresh 128-bit nonce from /dev/urandom with a
configurable lifetime; an expired-nonce client is re-challenged (stale)
rather than rejected. sofia_secure_nonce_gen() at
channels/chan_sofia.c:6681.
The PBX advertises exactly the algorithms the operator enabled (MD5 first for
legacy phones, SHA-256, or both). sofia_emit_auth_challenge() at
channels/chan_sofia.c:6811.
Reliable provisional responses, so "ringing" and other early call-progress
messages are acknowledged and never lost on a lossy link. Outbound gating and
inbound sofia_process_prack() at channels/chan_sofia.c:5411 and :10441;
per-peer rel100.
In-dialog media renegotiation — hold, codec swap, session-timer refresh —
without disrupting the dialog. sofia_process_update() at
channels/chan_sofia.c:10768.
Long calls are periodically refreshed so a crashed phone or dropped network
cannot leave a zombie call billing forever; per-trunk
originate/accept/refuse. sofia_session_timer_values() at
channels/chan_sofia.c:3205.
Internal hangup reasons map to standardized telephony cause codes on outbound
BYE/CANCEL and parse back inbound. sofia_reason_build() /
sofia_reason_parse_cause() in channels/sofia/sofia_reason.c; gated by
use_q850_reason.
The PBX transfers a connected call to a third party, blind or attended (with
Replaces), via the .transfer tech callback and a SofiaTransfer()
application. channels/sofia/sofia_transfer.c:13.
When a phone asks the PBX to transfer (REFER), the PBX honors it, including
attended transfers via Replaces and the RFC 5589 transferer-leg BYE deferral.
sofia_process_refer() at channels/chan_sofia.c:10156.
Sends and receives SIP instant messages independent of a call; inbound routes
to a message_context, outbound from the dialplan or AMI.
channels/sofia/sofia_message.c.
Accepts event-package subscriptions and routes each to the right handler —
message-summary to MWI, dialog/dialog-info/presence to presence — rejecting
unsupported packages with 489 Bad Event. sofia_process_subscribe() at
channels/chan_sofia.c:9655.
Drives speed-dial lamps showing whether a monitored colleague is idle, ringing
or on a call, in dialog-info+xml, pidf+xml or xpidf+xml.
channels/sofia/sofia_presence.c.
Lights the message-waiting indicator, delivering the voicemail count solicited
or unsolicited. Body builder and transmit_mwi_notify_for_peer() around
channels/chan_sofia.c:8989.
The PBX subscribes to a provider's voicemail-status notifications and re-lights
local phones, with retry/backoff on a failed initial subscribe.
channels/sofia/sofia_subscribe.c; per-peer mwi_subscribe=.
Subscribes a trunk to any event package and surfaces each notification as a
SofiaEventNotify AMI event, without interpreting the body.
channels/sofia/sofia_eventsub.c; per-peer subscribe_event=.
Publishes a local extension's presence/state to an upstream server, refreshing
with SIP-If-Match/ETag. channels/sofia/sofia_publish.c.
Carries key-press digits inside SIP signaling both ways, separate from inband
or RFC 2833. sofia_process_info() at channels/chan_sofia.c:10350.
Answers SIP OPTIONS pings with a 200 OK advertising every supported method plus
Accept: application/sdp. sofia_process_options() at
channels/chan_sofia.c:5706.
Advertises a stable per-device instance ID on registration and learns the
routable address the registrar mints. channels/sofia/sofia_gruu.c; per-peer
gruu=.
As a registrar, records and honors the route a phone registered through (edge
proxy), rejecting forged Path with 420 Bad Extension.
channels/sofia/sofia_route.c; per-peer path=.
On outbound registration, remembers the route the provider mandates and
pre-loads it on outgoing calls. sofia_service_route_store() at
channels/sofia/sofia_route.c:83; per-peer service_route=.
Advertises outbound support and a registration ID and honors the provider's
flow-keepalive timer, for reliable connectivity behind firewalls. Require: outbound / Flow-Timer learned from the 2xx at channels/chan_sofia.c:10876;
per-peer sip_outbound=.
Carries forwarding/redirection history outbound and parses it inbound into the
channel's redirecting info, with a per-trunk forced-Diversion override.
sofia_add_diversion() / sofia_change_redirecting_info() at
channels/chan_sofia.c:1766.
A per-call timeline of every SIP request and response for diagnostics, viewable
while a call is being traced. Central hook around channels/chan_sofia.c:10740;
implementation channels/sofia/sofia_history.c.
Counts and bans abusive source IPs (failed-auth probes, malformed requests,
unknown-peer REGISTERs) to blunt brute-force and scanning.
channels/sofia/sofia_blacklist.c; checked on every inbound request at
channels/chan_sofia.c:10701.
RFC 3550 RTP/RTCP with symmetric-RTP NAT traversal, jitter handling, RED and
sender/receiver reports. One forked engine — gabpbx_rtp_engine,
.name="gabpbx" at res/res_rtp_gabpbx.c:1408 — handles plain calls and
WebRTC alike, so non-WebRTC RTP is unchanged. There is no separate
res_rtp_asterisk in the tree.
Encrypted media via SDP a=crypto — AES-CM 128/192/256 with HMAC-SHA1 80/32
and two GCM suites. Offers/answers are validated in full and staged, then
committed only past every reject gate, so a bad a=crypto never silently
downgrades a live call to plaintext. channels/sofia/sdp_crypto.c:37;
process/stage/commit in channels/sofia/sofia_sdp.c.
WebRTC-grade keying: keys derive from a DTLS handshake over the media path (not
the SDP), with SHA-256 fingerprints, ephemeral self-signed certs and a=setup
role negotiation so the two sides never both try to be the DTLS client. A
dedicated scheduler honors DTLS backoff; a fingerprint mismatch fails the call
closed. gabpbx_dtls engine at res/res_rtp_gabpbx.c:1001. Detail in
WebRTC.
A dependency-free ICE-lite agent — no pjproject, no libnice. GABPBX is
permanently the controlled lite agent: it answers STUN binding checks, learns
the peer from the authenticated check, and latches the nominated pair on
USE-CANDIDATE. The responder is armed before the offer leaves the wire so a
browser's first checks are never dropped. ICE-lite block at
res/res_rtp_gabpbx.c:1265. Detail in WebRTC.
rtcp-mux: RTP and RTCP share one socket on WebRTC legs (browsers require it),
with exactly one DTLS association per media stream. Emit at
channels/sofia/sofia_sdp.c:268 (audio) and :443 (video).
Session-level a=group:BUNDLE and per-m-line a=mid are emitted so browsers
accept the SDP; audio is the tagged transport. Unsupported offered m-lines are
reflected back as port-0 rejections in order, rather than refusing the whole
session with a 488. channels/sofia/sofia_sdp.c:359-362.
Browsers register and call over SIP-over-WSS (and plain WS). GABPBX listens on
dedicated WS/WSS URLs, auto-aliases the WSS cert/ca-bundle files, and routes
in-dialog ACK/BYE back over the exact accepted WebSocket connection (a browser's
Contact host is a placeholder), so calls set up, tear down and survive NAT.
channels/chan_sofia.c:11568-11660; transport append and placeholder-Contact
routing at :501-589.
A real two-way audio call between two WSS browsers, with DTLS-SRTP + ICE-lite +
rtcp-mux + BUNDLE wired into the SDP. Opt-in per peer with webrtc=yes
(inherited from [general]); a webrtc=yes peer fails the call rather than
ever falling back to insecure media. Direct media is force-disabled on any
DTLS/SRTP leg. Peer flag at channels/chan_sofia.c:2591/:13173; outbound
offer sofia_webrtc_provision_offer() at channels/sofia/sofia_sdp.c:822.
Real two-way browser-to-browser video on top of audio: GABPBX both accepts a
browser's offered video and offers video itself, negotiating VP8 or H.264 with
its own DTLS/ICE/fingerprint. Video runs on its own separate transport
(non-BUNDLE) — a distinct mid, port and DTLS association from the audio.
Non-BUNDLE m=video block at channels/sofia/sofia_sdp.c:386-491; offerer
provision and answerer accept in the same file.
Opus (RFC 7587, 48 kHz, stereo, useinbandfec) is offered and answered, and a
both-Opus call relays with no transcoding. Three core gaps that garbled
browser-to-browser Opus were fixed: codec selection now knows Opus, the format
rate returns 48 kHz so the RTP TX timestamp clocks +960 per 20 ms (not +160),
and the RTP smoother no longer re-chunks Opus's variable-size frames. Opus
rtpmap/fmtp at channels/sofia/sofia_sdp.c:172-174; smoother exemption at
res/res_rtp_gabpbx.c:2840-2845.
Real-time T.38 over UDPTL with a 4-state negotiation machine, re-INVITE
handling, far-max-IFP signaling and a 5-second abort timeout. T.38 is
correctly suppressed inside WebRTC SDP (a plain m=image there would 488 the
session). sofia_change_t38_state() at channels/sofia/sofia_t38.c:34.
directmedia (alias canreinvite) lets two endpoints exchange RTP directly
when safe; it is gated conservatively — any SRTP/DTLS leg, any NAT'd peer, or a
cross-leg ACL mismatch forces local relay, so encryption is never bridged to a
non-secure peer. get_rtp_peer glue at channels/chan_sofia.c:3119-3168.
Codecs are emitted in configured preference order, the answer is intersected
with local capability, and a no-common-audio offer is cleanly rejected with
488 (logged to SIP history). preferred_codec_only narrows the answer to the
single best codec; per-codec fmtp for G.729 (annexb=no), Opus and iLBC
(mode=20). channels/sofia/sofia_sdp.c:143-222 and :1276-1311.
All standard modes per peer: rfc2833 (default, telephone-event), info,
inband (DSP), auto. The telephone-event payload type avoids colliding with a
negotiated codec's PT, relaxdtmf loosens detection on poor lines, and
SIPDtmfMode switches mode mid-call. dtmfmode config at
channels/chan_sofia.c:2551-2555.
On a WebRTC leg the one muxed socket carries STUN, DTLS and (S)RTP/RTCP
interleaved. GABPBX demuxes by first byte per RFC 7983 — STUN to the ICE
responder, DTLS records to the handshake, RTP to SRTP-unprotect — with muxed
SRTCP dropped and a flood guard. The whole demux is dormant unless DTLS is
active, so plain calls are untouched. __rtp_recvfrom at
res/res_rtp_gabpbx.c:1732-1786.
One nua_create() spins up every SIP transport from [general] bind ports,
each enabled only when its bind port is non-zero, passed as separate
NUTAG_URL/SIPS_URL/WS_URL/WSS_URL tags.
channels/chan_sofia.c:11568-11660.
[general] exposes bindaddr/bindport, tlsbindaddr/tlsbindport,
wsbindaddr/wsbindport, wssbindaddr/wssbindport, plus the udpbindaddr
host:port alias. Each listener URL is IPv6-aware (bracket-wrapped per RFC
3261 §19.1.2). These are baked in at module load; sip reload aborts if a
listener-level value changed.
Opt-in TLS security on the TLS listener: tlsverify, tlsverifyclient (mutual
TLS), tls_min_version, tls_ciphers, tls_verify_depth, and TLS verify-date.
Closes the accept-any-cert MITM hole sofia-sip leaves open by default.
channels/chan_sofia.c:11647-11681.
sip show peers, sip show peer <name> (full detail, tab-completed),
sip show settings, sip show registry, sip show channels /
show channel / show channelstats, sip show inuse, all in chan_sip's
column layout, snapshotting under peer->lock before the blocking write.
channels/sofia/sofia_cli.c.
sip reload (alias for module reload chan_sofia.so, aborts on a listener-only
change), sip set debug [on|off|peer|ip], sip qualify peer, sip unregister,
sip prune realtime, sip notify, plus sip show/set/clear history and the
blacklist family. channels/sofia/sofia_cli.c.
SIPpeers/SIPshowpeer, SIPqualifypeer, SIPshowregistry, SIPnotify, and
SofiaMessageSend, each mirroring chan_sip's field set (Transport extended to
ws/wss). channels/sofia/sofia_ami.c; registered in channels/chan_sofia.c.
On a cache miss a peer is loaded from the sippeers realtime table, with
optional dual-load of registration state from sipregs auto-detected via
ast_check_realtime('sipregs'); cache lookup is atomic to avoid duplicate
links on concurrent miss. sofia_find_peer_realtime() at
channels/chan_sofia.c:2921-2961. See PostgreSQL-Realtime-Cache.
For realtime peers with rtupdate=yes, the binding is written back via
ast_update_realtime on REGISTER and cleared on unregister, optionally stamping
rtsave_sysname. A bounded background pool can offload the blocking DB write
off sofia_thread. channels/chan_sofia.c:7466-7500.
${SIPPEER()}, ${SIP_HEADER()}, ${SIPCHANINFO()}, ${CHECKSIPDOMAIN()} —
chan_sip-parity verbatim. The channel registers tech type SIP, so
${CHANNEL(...)}, AMI and CDR all see SIP/<peer> exactly as before.
channels/chan_sofia.c:5789-6128.
The peer parser accepts the full chan_sip per-peer vocabulary —
host/context/secret/transport/allow/disallow/nat/directmedia
(=canreinvite)/qualify/callgroup/mohinterpret/mohsuggest/session
timers/insecure/permit/deny and more — so existing sip.conf-style peer
blocks load unchanged. sofia_config_peer at
channels/chan_sofia.c:2556-2910.
nat=force_rport,comedia; three independent ACL chains (source permit/deny,
contactpermit/contactdeny, directmediapermit/directmediadeny) plus a
global localha; per-peer mohinterpret/mohsuggest; qualify with RTT and
PeerStatus AMI transitions. See Chan-Sofia for the per-knob detail.
SIP — chan_sofia
Subsystems
Realtime & data
Operations