vicigeeksimple guides
Browse
All guides

Carriers & SIP · SBC architecture

OpenSIPS in front of VICIdial: choose registration and dialog ownership

Use a version-pinned ownership worksheet and call-lifecycle matrix before adding a SIP proxy. OpenSIPS 3.6 ordinary Record-Route handling and topology-hiding matching are separate designs; neither is a complete drop-in configuration here.

Reader setup

Before you evaluate

  1. A documented direct signaling/media path and an approved isolated evaluation environment.
  2. OpenSIPS 3.6 module documentation matching the proposed build; use that installed version’s references if it differs.
  3. An owner for registration, transaction handling, dialog routing, media and rollback.
Expected result
A completed ownership record, selected dialog-routing design and a test matrix that distinguishes call cleanup from persistent registration.
Before making changes
This is a design and acceptance guide, not an opensips.cfg deployment recipe. No SBC, carrier or production route was changed for this article.

Choose one owner for each registration relationship

Draw each registration relationship separately: phone-to-registrar, and any provider registration used by the trunk. If a trunk uses IP/digest authentication without REGISTER, record “not used” for that relationship. Do not require a Registered state for a non-registering trunk.

For each relationship that does register, name one responsible component and its credential, contact-refresh and failure-handling owner. Adding a proxy does not make duplicate registrations intentional.

You should seeEvery relationship has an explicit owner or “not used”, rather than one ambiguous global REGISTER checkbox.

Trace path · read left to right
01Carrier02OpenSIPS dialog owner03VICIdial Asterisk

Draw the ownership map before configuration

Use role names in the public worksheet and keep actual addresses/credentials in protected configuration records. Record the inbound/outbound next hops, transaction handling, chosen dialog-routing mechanism and the media relay/direct path separately.

OpenSIPS signaling proxying does not itself prove that RTP traverses a relay. If a media relay is required, give it an explicit owner, health check and failure test.

Before you use it
Complete this before writing the version-specific routing configuration. This is a design record, not code to run.
Version-pinned ownership worksheet
OpenSIPS version: 3.6.x (record exact build)Phone registration owner: selected registrar or not usedProvider registration owner: selected component or not usedInbound next hop: reviewed Asterisk roleOutbound next hop: reviewed provider roleDialog route: ordinary rr OR topology_hiding (choose one per path)Transaction handling: reviewed initial/ACK/CANCEL/retransmission policyMedia: direct OR named relay, with separate health checkRollback: prior next hops and registration relationships
Not executed · worksheet or reference text

This sample is a template or reading aid, not a terminal command. There is no output to show.

Success looks like
Each relationship and stateful responsibility has one documented owner; the route and rollback are unambiguous.
Stop if
Stop if the design mixes ordinary loose_route assumptions with topology-hiding requests or silently introduces a media relay.

Download the ownership and lifecycle worksheet

Choose the OpenSIPS 3.6 dialog-routing mechanism

In an ordinary Record-Route design, rr adds the proxy to the route set and loose_route() processes Route-bearing sequential requests. Authentication, transaction handling and non-dialog requests still need a reviewed routing script.

For a topology-hiding path, topology_hiding() strips/restores Via/Record-Route/Route and rewrites Contact. The 3.6 documentation says later requests on that path lack the ordinary Route headers and require topology_hiding_match() to match and repair the request. Do not make a successful loose_route() check the only gate for those requests.

Use the installed module’s full documentation and dependencies when implementing either design. The comparison below is not a complete opensips.cfg and must not be pasted as one.

Before you use it
Run both on the VICIdial/Asterisk host, whichever side of the SBC decision you are validating from this end.
Read-only Asterisk-side transport check
asterisk -rx 'pjsip show transports'ss -lnup | grep asterisk
Evidence · ViciBox 12 demo capture

Captured demo response · 2026-09-24 22:25 UTC. Any filtering, hidden values or test-only data are identified in the capture label. Select Replay transcript to read the recorded output.

Command output line: asterisk -rx 'pjsip show transports'
Transport: <TransportId........> <Type> <cos> <tos> <BindAddress....................>
==========================================================================================
Transport: transport-udp udp 0 96 0.0.0.0:5061
Transport: transport-wss wss 0 0 0.0.0.0:5060
Objects found: 2
Command output line: ss -lnup | grep asterisk
UNCONN 0 0 0.0.0.0:4520 0.0.0.0:* users:(("asterisk",pid=3019,fd=20))
UNCONN 0 0 0.0.0.0:4569 0.0.0.0:* users:(("asterisk",pid=3019,fd=17))
UNCONN 0 0 0.0.0.0:5060 0.0.0.0:* users:(("asterisk",pid=3019,fd=16))
UNCONN 0 0 0.0.0.0:5061 0.0.0.0:* users:(("asterisk",pid=3019,fd=13))
UNCONN 0 0 0.0.0.0:2069 0.0.0.0:* users:(("asterisk",pid=3019,fd=11))
UNCONN 0 0 [[address]]:23043 [[address]]:* users:(("asterisk",pid=3019,fd=12))
Success looks like
The commands identify the local Asterisk transport/listener starting point. They do not validate either OpenSIPS dialog-routing mechanism.
Stop if
Stop if another process holds a listener you expected Asterisk to own, or if the two commands disagree about which ports are actually bound — resolve that before placing an SBC in front of either one.
Two mechanisms with different follow-up checksScroll sideways to compare columns
Chosen designInitial dialog requestSequential requests and evidence
Ordinary rrReviewed record_route() handling for dialog-forming requestsloose_route() on the intended route set; verify ACK, re-INVITE and BYE reach the expected peer.
topology_hidingReviewed topology_hiding() path and required module statetopology_hiding_match() for the appropriate in-dialog requests; verify restored routing and identities.
Sources for this section

Test transactions, dialogs and registrations separately

Use controlled endpoints in both directions and correlate the selected synthetic transaction/dialog across the two hops. A successful registration or OPTIONS response is not a completed call test.

A rejected INVITE and a pre-answer CANCEL must complete their transaction paths without a lingering test call. An established dialog needs the correct BYE and cleanup. A valid persistent registration normally remains until expiry, refresh or an explicit registration change; call rejection or hangup does not require deleting it.

Acceptance cases for the selected designScroll sideways to compare columns
CaseRequired observationKeep separate
Answer then hangup from either sideACK/BYE follow the selected mechanism; test dialog/media allocations endRegistration may remain valid.
Reject before answerFinal response and corresponding transaction handling completeNo accepted call is claimed.
Cancel before answerCANCEL and resulting INVITE transaction complete under the reviewed policyDo not demand deletion of a valid registration.
Hold/resume and transfer if supportedExpected re-INVITE/transfer routing and audio behaviorRegistration status is not media proof.
Longer-than-refresh testRefresh/retransmission behavior and deliberate hangup succeedOne short call cannot establish this case.
Registration loss or expiryExpected refresh/failure/recovery behavior for that relationshipTest separately from call-dialog cleanup.
  • Run the cases in both intended directions and record actual results.
  • Preserve only sanitized call IDs/timings and the first failed boundary for handoff.
  • Do not mark an unperformed transfer, refresh or media case as passed.

Reverse the route without leaving two owners

Stop expansion on incorrect next hops, identity rewriting, missing sequential requests or failed media. End only the controlled test calls, restore the captured prior next-hop and registration-owner settings, and verify the selected state on both components.

After reversal, repeat the relevant direct-path acceptance cases. Preserve the synthetic history and failure evidence. Avoid deleting unrelated registrations or trying to clear all dialogs to make a test look clean.

You should seeThe rollback result names the state restored and the cases actually repeated.

  • The prior route and each registration relationship have their documented owner.
  • No synthetic dialog is left on the withdrawn test route.
  • The prior path passes the selected answer, reject/cancel and hangup cases.

Checks and sources

What was checked

  • OpenSIPS 3.6 rr and topology_hiding documentation was reviewed November 6, 2026. The mechanisms are described separately; no working OpenSIPS/VICIdial deployment is asserted.
  • Asterisk transport commands are read-only observations of the PBX side. They do not establish SBC routing, registration ownership, media relay operation or a completed call lifecycle.
  • This comparison pins the maintained OpenSIPS 3.6 LTS documentation, checked November 6, 2026. The installed minor version and loaded modules still need to be recorded in the acceptance worksheet.

Primary references

Sources

  1. OpenSIPS 3.6 RR moduleOpenSIPS · accessed November 6, 2026
  2. OpenSIPS 3.6 topology_hiding moduleOpenSIPS · accessed November 6, 2026
  3. VICIdial PJSIP SupportVICIdial · accessed November 6, 2026
  4. OpenSIPS supported versionsOpenSIPS · accessed November 6, 2026

Follow without guesswork

Get the next article

RSS is live now. Email delivery below is an explicit local preview and sends nothing.Open the RSS feed
Email preview only. The address stays in this browser and is never transmitted.