--- title: "DIDs & Inbound Routing" description: "Documentation for DIDs & Inbound Routing" --- ## Table of Contents 1. [Overview & Architecture](#1-overview--architecture) 2. [Business & Operational Significance](#2-business--operational-significance) 3. [🎯 User Roles & Key Capabilities](#3--user-roles--key-capabilities) 4. [Visual Interface & Form Layout](#4-visual-interface--form-layout) 5. [Field & Configuration Reference](#5-field--configuration-reference) 6. [Kamailio Inbound Resolution Engine & Dialplan Logic](#6-kamailio-inbound-resolution-engine--dialplan-logic) 7. [Security Best Practices & Operational Hardening](#7-security-best-practices--operational-hardening) 8. [Troubleshooting & Verification](#8-troubleshooting--verification) 9. [Glossary](#9-glossary) --- ## 1. Overview & Architecture 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 │ └───────────────────────────────┘ └───────────────────────────────┘ ``` --- ## 2. Business & Operational Significance * **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). --- ## 3. 🎯 User Roles & Key Capabilities | 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. | --- ## 4. Visual Interface & Form Layout ### DIDs List View The list view displays all inventory numbers, friendly descriptions, assigned customer SIP accounts, routing destinations, provisioning source, and operational status. ![DIDs List View](/screenshots/sbc/routing/dids/dids-list.png) ### DID Configuration Form The configuration form is organized into two primary sections: **DID Information** and **Routing Settings**. ![DID Configuration Form](/screenshots/sbc/routing/dids/dids-form.png) --- ## 5. Field & Configuration Reference ### Box 1: DID Information | 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. | ### Box 2: Routing Settings | 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 ### Database Schema & Storage ```sql -- 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); ``` ### Kamailio Routing Mechanics When an inbound `INVITE` arrives at Kamailio: ```c 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 * **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. --- ## 8. Troubleshooting & Verification ### Inspect DID Catalog via PostgreSQL ```bash # 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;" ``` ### Trace Inbound Calls by Dialed Number ```bash # Filter live inbound SIP signaling for a specific DID sngrep "INVITE.*17865550199" ``` ### Inspect Kamailio In-Memory Cache ```bash # Verify Kamailio htable memory usage for DID table kamcmd htable.dump dids ``` --- ## 9. Glossary * **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.