Setup guide · Dispatcher
Connect a SIP trunk to Kamailio
Kamailio is a SIP proxy, not a PBX. Here it sits in front of your media servers and sends outbound traffic to SIPTrunkHub with the dispatcher module, failing over to a second destination on timeouts and 5xx responses.
Before you start
What you need
- Kamailio 5.6+ with the dispatcher, tm and sl modules
- A static public IP for the proxy (we whitelist it)
- rtpengine if your media servers are behind NAT
- Your SIPTrunkHub account details: SIP server, tech prefix if any
IP auth or register auth?
IP authentication
RecommendedRecommended for proxies. We whitelist the proxy’s public IP and no credentials are needed.
Register (digest) authentication
Possible with the uac module (uac_auth on 401/407 in the failure route), but adds complexity. Ask the NOC for IP auth instead.
Step by step
Configure Kamailio
sip.example-host.net and 203.0.113.10 are documentation placeholders. Replace them, and the username, password and tech prefix, with the values from your account.
- 01
Define the destinations
Set 1 holds the trunk destinations. Higher priority is tried first with algorithm 8.
/etc/kamailio/dispatcher.list # setid destination flags priority attrs 1 sip:sip.example-host.net:5060 0 10 duid=sth-primary 1 sip:sip2.example-host.net:5060 0 5 duid=sth-secondary - 02
Load and configure the dispatcher
Enable probing so dead destinations are taken out of rotation automatically.
/etc/kamailio/kamailio.cfg loadmodule "dispatcher.so" modparam("dispatcher", "list_file", "/etc/kamailio/dispatcher.list") modparam("dispatcher", "flags", 2) modparam("dispatcher", "ds_ping_interval", 30) modparam("dispatcher", "ds_probing_mode", 1) modparam("dispatcher", "ds_ping_from", "sip:[email protected]") - 03
Route outbound calls with failover
Call route(TO_CARRIER) from your request route for INVITEs that should leave via the trunk. On 408 or any 5xx, the failure route tries the next destination.
/etc/kamailio/kamailio.cfg route[TO_CARRIER] { # optional tech prefix: prefix("1234#"); if (!ds_select_dst("1", "8")) { send_reply("503", "No carrier available"); exit; } t_on_failure("CARRIER_FAILOVER"); route(RELAY); exit; } failure_route[CARRIER_FAILOVER] { if (t_is_canceled()) exit; if (t_check_status("408|5[0-9][0-9]") && ds_next_dst()) { t_on_failure("CARRIER_FAILOVER"); route(RELAY); exit; } } - 04
Accept inbound calls from us
Identify our traffic by source IP and send it to your media servers. Do not challenge it.
/etc/kamailio/kamailio.cfg if ($si == "203.0.113.10" && is_method("INVITE")) { # route DIDs to your PBX / media server set ds_select_dst("2", "4"); route(RELAY); exit; } - 05
Reload
Reload the dispatcher list without restarting Kamailio, then check destination state.
Shell kamcmd dispatcher.reload kamcmd dispatcher.list
Media
Codec order
- Kamailio does not touch codecs. Negotiation happens between your media server and our network.
- Make sure your media servers offer G.711 first and G.729 second.
- If you run rtpengine, it passes codecs through unchanged unless you configure transcoding.
NAT notes
- Use fix_nated_contact() and fix_nated_sdp() or, better, rtpengine_manage() for media servers behind NAT.
- Set advertise on the listen line when Kamailio itself is behind 1:1 NAT: listen=udp:10.0.0.5:5060 advertise 198.51.100.20:5060.
- Record-Route so in-dialog requests (BYE, re-INVITE) pass through the proxy.
Verify
Test the trunk
kamcmd dispatcher.list shows each destination with flags AP (active, probing) or IP (inactive). Use sngrep to watch a test call go out and fail over.
kamcmd dispatcher.list
sngrep -d any port 5060
sipsak -s sip:sip.example-host.net -vv # manual OPTIONS pingTroubleshooting
Common SIP errors
What each response means and what to check first on Kamailio. If you still need help, send the Call-ID and timestamp to the NOC.
| Code | Meaning | Likely cause | Fix on Kamailio |
|---|---|---|---|
| 401 | Unauthorized | We challenged the INVITE or REGISTER and the credentials were wrong or missing. With IP auth it usually means the call arrived from an IP we have not whitelisted. | Check the username, password and auth realm. For IP auth, confirm the public IP your PBX actually sends from matches the one on your account. |
| 403 | Forbidden | Authenticated, but not allowed: wrong or missing tech prefix, zero prepaid balance, destination blocked on your account, or an invalid caller ID. | The proxy’s source IP is not the one we whitelisted. Check which interface Kamailio sends from (force_send_socket). |
| 404 | Not Found | The dialled number is not in a format we can route: missing country code, an extra 00 or +, or a local trunk prefix left in. | Send E.164 digits without the + (for example 442079460000). Strip national 0 and international 00 in your dial rules. |
| 408 | Request Timeout | No response came back. Usually a firewall, wrong port or transport, a DNS failure, or SIP ALG on the router eating packets. | With ds_probing_mode 1 the destination will be marked inactive. Check the firewall and kamcmd dispatcher.list. |
| 480 | Temporarily Unavailable | The far end could not be reached: handset off, out of coverage, or the route for that prefix is temporarily down. | Retry later or route to another trunk. If it hits one prefix repeatedly, send examples to the NOC. |
| 486 | Busy Here | The called party is busy, or you reached the concurrent-channel limit on your account. | Treat as a normal busy. If every call returns 486, check your active channel count against your limit. |
| 503 | Service Unavailable | Capacity limit hit (calls per second or channels), or every route for that destination failed. | If Kamailio generated it, every destination in set 1 is inactive. Otherwise it came from us: check CPS and channels. |
Seeing one-way audio instead of an error? Read One-Way Audio on VoIP Calls.
FAQ
Kamailio questions
Which dispatcher algorithm should I use?
8 (priority order) gives clean primary/secondary failover. 4 (round robin) spreads load but sends calls to both destinations evenly.
Can Kamailio enforce my CPS limit?
Yes, with the pike or pipelimit module. Keeping your traffic under the agreed CPS avoids 503s from our side.
Do I need rtpengine?
Only if media servers are behind NAT or you need to anchor media. Otherwise media flows directly between your servers and ours.
Popular destinations
SIP Trunk United States+1
SIP Trunk United Kingdom+44
SIP Trunk Germany+49
SIP Trunk United Arab Emirates+971
SIP Trunk Philippines+63
SIP Trunk Australia+61
Stuck on a step?