Skip to content

DIDs & Inbound Routing

7 min readUpdated: Sep 26, 2026
View as Markdown
  1. Overview & Architecture
  2. Business & Operational Significance
  3. 🎯 User Roles & Key Capabilities
  4. Visual Interface & Form Layout
  5. Field & Configuration Reference
  6. Kamailio Inbound Resolution Engine & Dialplan Logic
  7. Security Best Practices & Operational Hardening
  8. Troubleshooting & Verification
  9. Glossary

In Ring2All SBC, the DIDs module (public.dids) manages Direct Inward Dialing telephone numbers provisioned from wholesale telecom carriers. It provides high-speed E.164 number normalization, ownership validation, tenant domain mapping, and flexible destination routing into customer SIP Accounts, Ring2All PBX tenant domains, or downstream enterprise SIP endpoints.

When an inbound call reaches the perimeter SBC from a carrier gateway, Kamailio extracts the dialed number from the Request-URI user portion ($rU), strips country codes or carrier prefixes as necessary, and performs an in-memory hash table lookup against the DID catalog.

┌─────────────────────────────────────────┐
│ Incoming SIP Request (INVITE) │
│ INVITE sip:+17865551234 │
└────────────────────┬────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ Kamailio Request-URI Sanitization │
│ • Strip '+' or tech prefixes │
│ • Standardize to E.164 string │
└────────────────────┬────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ In-Memory Hash Table Lookup │
│ $sht(dids=>$var(e164)) │
└────────────────────┬────────────────────┘
│
Match Found & Status = 'active'
│
┌──────────────────────────────┴──────────────────────────────┐
▼ ▼
┌───────────────────────────────┐ ┌───────────────────────────────┐
│ Mapped SIP Account │ │ Custom Destination URI │
│ • Account Channel Caps │ │ • Forward to External IP │
│ • Apply Tech Prefix │ │ • Outbound Carrier Gateway │
│ • Relay to Customer PBX │ │ • Inter-Switch Routing │
└───────────────────────────────┘ └───────────────────────────────┘

  • Centralized Number Inventory: Provides carrier-grade tracking of all telephone numbers across multiple carrier vendors, provisioning channels, and tenant domains.
  • Carrier Portability & Failover: Decouples physical carrier trunks from internal PBX destinations. If a carrier experiences an outage, DIDs can be instantaneously repointed without modifying customer PBX configurations.
  • Granular DID Lifecycle Management: Supports administrative states (active, reserved, disabled) to support number aging, quarantine periods, and prepaid billing reservation windows.
  • Seamless API Provisioning: Supports both manual administrator entry and automated REST API ingestion (source: api) from automated number inventory providers (Bandwidth, Telnyx, Twilio, Sinch).

Role Primary Use Case Key Capabilities
SBC Administrator Carrier DID Provisioning & Routing Add, update, and reassign DIDs; link numbers to customer SIP Accounts or custom SIP URIs; toggle activation states.
Carrier NOC Engineer Inbound Call Flow Diagnostics Trace inbound calls matching specific dialed numbers, verify normalization rules, and inspect carrier ingress headers.
Wholesale Reseller Tenant Number Management Audit allocated numbers, inspect assigned destinations, and reserve inventory for pending tenant onboardings.

The list view displays all inventory numbers, friendly descriptions, assigned customer SIP accounts, routing destinations, provisioning source, and operational status.

DIDs List View

The configuration form is organized into two primary sections: DID Information and Routing Settings.

DID Configuration Form


Field Type Constraints / Format Description
DID Number * Text Valid E.164 digits (e.g. +17865550199 or 17865550199) The unique dialed telephone number as received from the upstream carrier gateway.
Description / Name Text Max 128 characters Friendly descriptive label (e.g., Headquarters Main IVR, Support Hotline).
Status * Dropdown active, reserved, disabled Operational state. active routes calls; reserved holds number without accepting calls; disabled rejects with SIP 404.
Provisioning Source Dropdown manual, api Indicates whether the number was manually created via the portal or synchronized via carrier API automation.
Operational Notes Textarea Max 255 characters Free-form administrative notes, carrier purchase order ID, or client billing account number.
Field Type Constraints / Format Description
SIP Account Searchable Select Active SIP Accounts The customer SIP Account assigned to receive calls placed to this DID. Applies account channel caps.
Custom Destination Text SIP URI (e.g., sip:reception@customer-pbx.com) Optional explicit SIP destination override. If populated, takes precedence over the default account destination.

6. Kamailio Inbound Resolution Engine & Dialplan Logic

Section titled “6. Kamailio Inbound Resolution Engine & Dialplan Logic”
-- DIDs table in ss_telephony database
CREATE TABLE public.dids (
id SERIAL PRIMARY KEY,
number VARCHAR(32) NOT NULL UNIQUE,
name VARCHAR(128),
sip_account_id INT REFERENCES public.sip_accounts(id) ON DELETE SET NULL,
carrier_id INT REFERENCES public.carriers(id) ON DELETE SET NULL,
source VARCHAR(20) NOT NULL DEFAULT 'manual', -- manual, api
destination VARCHAR(255),
status VARCHAR(20) NOT NULL DEFAULT 'active', -- active, reserved, disabled
notes TEXT,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
-- B-tree index for instantaneous dialed number lookup
CREATE INDEX idx_dids_number ON public.dids(number);
CREATE INDEX idx_dids_sip_account_id ON public.dids(sip_account_id);

When an inbound INVITE arrives at Kamailio:

route[DID_INBOUND_ROUTING] {
# 1. Normalize Request-URI user to E.164
$var(did) = $rU;
if ($var(did) =~ "^\+[0-9]+$") {
$var(did) = $(var(did){s.substr,1,0}); # Strip leading +
}
# 2. In-memory hash table lookup for low-latency routing
if (!sht_iterator_start("dids", "dids_iter")) {
# Fallback to database lookup if cache miss
sql_query("telephony", "SELECT destination, sip_account_id, status FROM public.dids WHERE number = '$var(did)'", "ra");
}
# 3. Check status
if ($dbr(ra=>[0,2]) != "active") {
sl_send_reply("404", "Number Not in Service");
exit;
}
# 4. Rewrite Request-URI to configured destination
if ($dbr(ra=>[0,0]) != $null && $dbr(ra=>[0,0]) != "") {
$ru = $dbr(ra=>[0,0]);
} else {
# Route to associated SIP Account endpoint
route(RELAY_TO_SIP_ACCOUNT);
}
}

7. Security Best Practices & Operational Hardening

Section titled “7. Security Best Practices & Operational Hardening”
  • Carrier Ingress Validation: Never accept DIDs unconditionally from any IP. Ensure incoming calls for assigned DIDs arrive strictly from authorized Carrier IPs or peering interconnects.
  • Quarantine Periods for Released DIDs: When a customer cancels service, transition the DID to reserved for 30–60 days before releasing it to prevent the next subscriber from receiving unwanted legacy calls.
  • Malicious Dialed User Sanitization: Sanitize $rU to prevent SQL injection or memory buffer vulnerabilities by enforcing regex constraints (^[0-9+]+$) before processing.
  • E.164 Consistency: Normalize all numbers into uniform E.164 formatting upon ingestion to avoid duplicate entries for international numbers with or without leading zeros or plus signs.

Terminal window
# Query active DIDs and assigned routing targets
psql -U softswitch -d ss_telephony -c "
SELECT d.id, d.number, d.name, d.status, s.name AS sip_account, d.destination
FROM public.dids d
LEFT JOIN public.sip_accounts s ON d.sip_account_id = s.id
ORDER BY d.number ASC;"
Terminal window
# Filter live inbound SIP signaling for a specific DID
sngrep "INVITE.*17865550199"
Terminal window
# Verify Kamailio htable memory usage for DID table
kamcmd htable.dump dids

  • DID (Direct Inward Dialing): A telephone number that routes directly to an extension, PBX, or SIP account without going through an auto-attendant or operator.
  • E.164: The international public telecommunication numbering plan that defines the format of telephone numbers (country code + national destination code + subscriber number, up to 15 digits).
  • Request-URI ($rU): The SIP header component identifying the intended recipient or destination of a SIP request.
  • Number Aging / Quarantine: The operational holding period during which a disconnected telephone number remains dormant before reassignment.