Trunks
A trunk is a SIP interconnect: a carrier, an upstream provider, a peer switch, or a customer’s PBX. The trunk entry itself carries the peer’s concrete identity — its source IPs, the URIs you dial to reach it, and its authorized caller IDs — while the shared behavior (translation contexts, caller-ID policy, codecs, timers) lives in its trunk profile.
trunks: customer-pbx: trunk-profile: customer-pbx-profile ips: - 198.51.100.10 uris: - 198.51.100.10:5060 allowed-caller-ids: - "_+1415555XXXX" primary-caller-id: "+14155551000" max-concurrent: 30Field reference
Section titled “Field reference”| Field | Required | Meaning |
|---|---|---|
trunk-profile |
yes | The trunk profile governing this trunk’s behavior. |
ips |
for inbound | Source IPs authorized to send you calls as this trunk (below). |
uris |
for outbound | Destinations dialed, in order, when sending calls out this trunk (below). |
Every trunk must have at least one of ips or uris — one-way trunks are
fully supported. A trunk with only ips is inbound-only (origination); a
trunk with only uris is outbound-only (termination). Using an inbound-only
trunk as a dial target anywhere (a route destination, a translation target,
an alias-trunk line, a ring-group fallback) is rejected at validation.
| allowed-caller-ids | no | Caller IDs the peer may assert on inbound calls (below). Empty = no restriction. |
| primary-caller-id | when profile mode is fixed | The trunk’s own number: the fixed-mode caller ID, and the identity asserted on 911 calls from this trunk. Must be a valid number when required. |
| max-concurrent | no | Concurrent-call cap for this trunk, overriding the profile’s template. Zero/absent falls back to the profile; nothing anywhere = unlimited. |
Inbound: IP authentication
Section titled “Inbound: IP authentication”Inbound trunk calls are authenticated by source IP: a call arriving at
your anycast IP from an address in a trunk’s ips list is classified as
that trunk, which selects the profile (and therefore the inbound translation
context and caller-ID policy) for the call.
- IP authentication requires your namespace’s
edge-proxyto be set — the binding is to the pair (source IP, your anycast IP). Two tenants on different anycast IPs can legitimately share a source IP (two customers behind one carrier SBC); the same source IP on the same anycast IP can only belong to one namespace. A configuration claiming an IP already owned by another namespace on your edge IP is rejected at validation with the owning namespace identified. - Traffic from an authorized source IP aimed at a different tenant’s anycast IP is rejected at the edge — relevant when you move numbers or equipment between your own tenants; update the trunk entry in the namespace that should own the traffic.
- A trunk with no
ipscan still be dialed outbound (delivery-only, e.g. a provider you only terminate to), but nothing can arrive as it. - Each
ipsentry must be a single IP address — CIDR ranges and hostnames are rejected at validation, because inbound classification is an exact source-IP match and a range would silently never match.
Outbound: dial URIs
Section titled “Outbound: dial URIs”uris lists where the trunk is dialed, as host[:port] targets — your
carrier’s SBCs, or the customer PBX’s address. Omit it entirely for an
inbound-only trunk.
- The profile’s
uri-selectionpicks the order:sequential(listed order, primary/backup) orrandom(per-call shuffle, load spread). - Each URI rings for the profile’s
ring-for(default 90 seconds). - Busy-level and transient failures retry the next URI of the same trunk; carrier-level failures escalate out of the trunk entirely (to the next destination when the dial came from a route).
Inbound caller-ID screening: allowed-caller-ids
Section titled “Inbound caller-ID screening: allowed-caller-ids”allowed-caller-ids is the set of caller IDs the peer is authorized to
assert on calls it sends you. Entries are exact numbers or Asterisk-style
patterns (leading _), so a DID block is one entry:
allowed-caller-ids: - "+14155551000" # main BTN - "_+1415555XXXX" # their full DID rangeScreening applies at ingress, against the caller ID after the profile’s
caller-ID mode has run (a modify rewrite happens first, so the list
validates the final value). A caller ID outside the list rejects the call
with the invalid-caller-id treatment — the anti-spoofing backstop that
keeps a compromised or misconfigured PBX from originating traffic as
numbers it doesn’t own, and from having those numbers signed under your
STIR/SHAKEN identity.
- An empty list means no restriction — appropriate for carrier ingress trunks, where the whole PSTN’s numbers legitimately arrive.
- With profile mode
fixed, the list is not consulted: the asserted value is discarded and replaced withprimary-caller-id, so there is nothing to screen.
Capacity
Section titled “Capacity”max-concurrent caps simultaneous calls on this trunk (both directions
count). It overrides the profile’s template value. Over-cap calls receive
the all-circuits-busy treatment. Capacity is always tracked per
individual trunk — profiles never pool capacity across trunks.
This is the knob that models purchased channel counts: sell a customer a
30-channel trunk group by setting max-concurrent: 30 on their trunk.
Worked examples
Section titled “Worked examples”Trunk-served customer PBX
Section titled “Trunk-served customer PBX”trunk-profiles: customer-pbx-profile: inbound-translation-context: from-customers outbound-translation-context: to-customers caller-id-mode: provided attestation-mode: A ring-for: 30 codecs: [ulaw, g722]
trunks: acme-pbx: trunk-profile: customer-pbx-profile ips: [198.51.100.10] uris: [198.51.100.10:5060] allowed-caller-ids: ["_+1415555XXXX"] primary-caller-id: "+14155551000" max-concurrent: 30Full attestation (A) is appropriate here because allowed-caller-ids
pins the customer to numbers you assigned them.
Carrier termination with redundant gateways
Section titled “Carrier termination with redundant gateways”trunks: carrier-a: trunk-profile: carrier-egress uris: - sbc1.carrier-a.example:5060 - sbc2.carrier-a.example:5060 max-concurrent: 500No ips (this direction is outbound-only; the carrier’s inbound side is a
separate trunk), two SBCs tried per the profile’s uri-selection.
Carrier origination (inbound DIDs)
Section titled “Carrier origination (inbound DIDs)”trunks: carrier-a-origination: trunk-profile: carrier-ingress ips: - 203.0.113.20 - 203.0.113.21Any caller ID is accepted (allowed-caller-ids omitted — this is the
PSTN), and the profile’s inbound context delivers DIDs. No uris — this
is a one-way, inbound-only trunk; the carrier’s termination side is the
separate carrier-a trunk above.