-
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.
Each Contact in a REGISTER binds, refreshes and de-registers independently: a
binding honors its own ;expires parameter, a per-Contact ;expires=0 removes
just that one binding (while a full Expires: 0 de-register clears them all), and
the 200 OK enumerates each surviving binding with its own granted expiry rather
than one peer-wide value. sip show peer <name> detail reflects each binding's
live state (AVAILABLE / EXPIRED / IN-CALL). Per-Contact ;expires=0 handling at
channels/chan_sofia.c:8434; per-binding granted expires in the 200 OK at
:10714 (and :10665).
A call to a dynamic peer whose bindings have all expired — no re-REGISTER
before the granted Contact expiry — returns CHANUNAVAIL instead of routing to a
stale binding or the peer aggregate address, so it never half-connects to a
device that is no longer reachable (RFC 3261 §10.3). The tri-state contact
selector distinguishes "no contacts" from "all expired". Guard at
channels/chan_sofia.c:6468-6477.
A connection-oriented binding (WSS / WS / TLS / TCP) is dropped promptly when its
underlying connection closes, instead of lingering until the SIP registration
expires — so a WebSocket browser client that reconnects often (e.g. a page
refresh) never leaves stale bindings behind. The registrar's connection watch
detects the close and removes the binding, always correcting internal routing
state. The per-peer / [general] option flowclose_emit_unregister (default
no) controls whether the external unregister side-effects — AMI PeerStatus,
BLF / hint device-state, and regexten cleanup — fire on a flow close; the
default keeps it silent so a browser refresh does not flap the BLF lamp, while
yes emits an explicit unregister event/state update on each flow close. The
binding is removed (and routing corrected) regardless of the option.
nua_i_media_error flow-close handler at channels/chan_sofia.c:13334; option
parsed in sofia_config_peer / [general].
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.
An out-of-dialog MESSAGE from one registered user to another is delivered
natively (RFC 3428): the sender is authenticated by digest, the target
extension is resolved through the same auto-created hint namespace as BLF, and
the message is fanned out to every registered contact of the target peer
(request-URI per contact, Path and NAT source honored), returning 202 Accepted on relay or 480 when no binding is reachable. Enabled by default
with message_autorelay=yes; set no to route through message_context
dialplan handling only. 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.
A focused SDP and ICE negotiation tracer, off by default and independent of the
general sip set debug. It dumps the generated offer SDP, the WebRTC offer-gate
decision, the incoming answer SDP and the offerer answer-apply path — showing the
signalling of a WSS/TLS session already decrypted, which a wire capture
cannot. Every Sofia: … debug line also carries a [from-user|to-user|callid]
transaction tag so each line is attributable to one SIP transaction. Detail in
Operations.
Every SIP message on any transport (udp / tcp / tls / ws / wss), SDP included, can
be exported already decrypted for diagnostics. sip_capture_address streams
each message as HEP (UDP) to a Homer/sipcapture server — read it with
sngrep -H udp:HOST:PORT — with the HEP version taken from sip_capture_hep
(default 3); sip_capture_file appends the same plain-text stream to a file.
Both have runtime equivalents, sip set debug capture <host:port> and
sip set debug file <path> (each with an off form). Applied through the
transport layer's TPTAG_CAPT / TPTAG_DUMP. channels/chan_sofia.c:15919-15934
and :17113-17142. Detail in Operations.
Two further focused, default-off tracers for WebRTC diagnostics. rtp set debug ice on logs each ICE latch and nomination, DTLS records dropped because their
source is not the latched peer, and receive errors — pure logging, no datapath
change (res/res_rtp_gabpbx.c). sip set debug fork on logs the mixed
UDP+WebSocket fork / binding lifecycle and correlates to the ICE log by the
rtp=%p pointer (channels/chan_sofia.c:258). Detail in Operations.
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. When GABPBX is the offerer, inbound DTLS records that arrive before the
answer's a=fingerprint is installed are deferred (non-fatally) rather than
failing closed; DTLS retransmits and the handshake completes once the fingerprint
is in place (RFC 5763/8842). 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 each integrity-authenticated
connectivity check, and latches the active media tuple on every such check —
not only on the nominated (USE-CANDIDATE) pair. Latching on each authenticated
check keeps the single live tuple pinned to the source the browser is actually
sending from, which eliminates the intermittent one-way / multi-second-gap audio
(and offerer-inbound deaf calls) a nominated-pair-only latch caused; USE-CANDIDATE
additionally marks the pair complete and arms the active DTLS handshake (RFC 8445
§7.3.1 / RFC 7675). ice_handle_stun() at res/res_rtp_gabpbx.c:1699. The responder is armed before the offer leaves the wire so a
browser's first checks are never dropped. When GABPBX is the offerer and the
answering full agent also picks the controlled role (so neither end would
nominate), GABPBX returns 487 Role Conflict to an authenticated
ICE-CONTROLLED check (RFC 8445 §6.1.1/§7.3.1.1/§7.2.5.1) so the browser flips
to controlling and nominates. 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.
GABPBX bridges WebRTC DataChannels back-to-back between two WebRTC legs: an
m=application UDP/DTLS/SCTP webrtc-datachannel is negotiated on the audio
BUNDLE's DTLS, the SCTP association is carried by an optional usrsctp build,
and the DCEP OPEN/ACK plus every message (PPID-preserving) are proxied to
the far leg. GABPBX both accepts an offered DataChannel and offers one to the
bridged leg, so a createDataChannel between two browsers crosses end to end.
Opt-in per peer with datachannel=yes (needs webrtc=yes and a usrsctp build).
channels/sofia/sofia_datachannel.c. Detail in WebRTC.
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. Calls placed to a wss-registered
browser (GABPBX as the SDP offerer) connect with two-way audio too, not only
browser-originated calls. 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.
The per-peer / [general] option webrtc_video_bundle (default no, requires
webrtc=yes) carries video on the same ICE/DTLS transport as audio instead of
a separate one, matching browsers that offer max-bundle: a single a=mid-tagged
transport, one DTLS association, payload-type demux, and an RTP MID header
extension (RFC 8285) to attribute each packet to the audio or video m-line. With
the option off, video keeps its own separate transport (above) and the offer is
byte-identical. peer->webrtc_video_bundle at channels/chan_sofia.c:3564; SDP
emission and demux in channels/sofia/sofia_sdp.c. Detail in WebRTC.
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.
The RTP engine's DTMF property tracks the negotiated mode, not only the
configured one: a separate runtime mode (dtmf_effective) is derived from the
offer/answer and applied as AST_RTP_PROPERTY_DTMF, so telephone-event is
advertised in SDP only for RFC 2833-capable modes, and dtmfmode=auto resolves
to RFC 2833 or inband at SDP-commit. The auto re-resolve reconfigures the DSP
fax-safely — it never frees a DSP under a live owner, preserving fax/CNG
detection. Inbound SIP INFO carrying a numeric Signal= is parsed to the
correct digit, SIPDtmfMode() re-syncs the mode mid-call, and
AST_OPTION_DIGIT_DETECT set/queryoption is honored. pvt->dtmf_effective and
sofia_dtmf_reconfigure() at channels/chan_sofia.c:1977-2035.
Call hold works from any endpoint, WebRTC included. The SDP answer mirrors the
offered per-media direction (RFC 3264 §6.1: sendonly→recvonly,
inactive→inactive) and reproduces every offered m-line in offer order
(RFC 3264 §6, declined streams at port 0) using the current offer/answer
transaction role — so strict JSEP endpoints accept the answer instead of
dropping the call with 488. Direction is staged at parse and committed only
past the reject gates; negotiated video payload types and the SDP stream
identity (cname/msid) persist across renegotiation and fork-winner
handover. sofia_generate_sdp(..., is_answer) / sofia_parse_sdp(..., current_offer) in channels/sofia/sofia_sdp.c.
WebRTC video sections advertise a=rtcp-fb: nack pli and ccm fir; inbound
PSFB PLI (FMT 1) and FIR (FMT 4) — and the legacy PT 192 FUR — become a
video-update indication that is relayed across the bridge, and the far leg
transmits an SRTCP-protected PLI over the ICE-selected RTP tuple to its
browser, targeting the learned remote video SSRC and throttled against
keyframe storms. This is what makes video recover instantly after unhold and
after receiver restarts. Only implemented feedback is advertised; both
directions fail closed without an SRTP context. ast_rtp_video_update() in
res/res_rtp_gabpbx.c, AST_CONTROL_VIDUPDATE in channels/chan_sofia.c.
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 unprotected and interpreted (reports feed statistics; PSFB keyframe
requests surface as video-update indications) 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> (concise summary, or full detail with
the tab-completed detail keyword), 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 show peer <name> prints a short, friendly summary: SIP peer name,
registration state, endpoint (user@host:port via transport), context / source,
accountcode, contact slots used/allowed, media (codecs / dtmf / nat /
directmedia), calls (active/limit, ringing, on-hold) and qualify status —
followed by the full list of contacts, each with its state, TTL, source and
User-Agent. Add the (tab-completed) detail keyword — sip show peer <name> detail — for the complete per-field dump: session timers, identity headers,
network & media, limits & features, fax / T.38, timers & RTP, routing & dialplan,
security & ACL, registration, and contacts. sofia_cli_show_peer() at
channels/sofia/sofia_cli.c:220.
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