Round robin trunking with PJSIP

Hello,

I’m working on trunking with a provider, with the following requirements:

  • my end is using Asterisk 16 on Debian
  • the other end is using Oracle SBC
  • I must load balance calls between two fixed IP (ie I must alternatively dialout to IP1 and IP2)
  • I must use the same FQDN in SIP URI, for both fixed IP boxes
  • provider doesn’t provide any DNS resolution (I must map myself this FQDN to these two fixed IP adresses)
  • no requirement on fail over (if box with IP1 ever fails, calls should still be sent to IP1)
  1. I was thinking of using a single PJSIP endpoint with a round robin DNS.
    What would you suggest ?

  2. How would you implement such round robin DNS ?
    The Debian host on which Asterisk is installed is not running any DNS server and I would prefer to keep it not offering any name resolution service to any other box over the network

Regards

In regards to the actual round robin selection, Asterisk does not have any built-in functionality to handle outbound round robin.

However, you can use the RAND() function to randomly select a Trunk.

exten => _1NXXNXXXXXX,1,Dial(PJSIP/${EXTEN}@Trunk${RAND(1,2)})

If you want real round robin, you can use the DB() function to read/update the last used Trunk

exten => _1NXXNXXXXXX,1,Set(DB(outbound/roundrobin)=${IF($["${DB(outbound/roundrobin)}" = "Trunk1"]?Trunk2:Trunk1)})
exten => _1NXXNXXXXXX,n,Dial(PJSIP/${EXTEN}@${DB(outbound/roundrobin)})

Asterisk caches DNS in a way that means this won’t work.

@david551
Reading [1], would you say DNS SRV entries allow (some kind of) load balancing ?

[1] Asterisk 14: Coming with improved PJSIP DNS Support! ⋆ Asterisk

@PitzKey
If I’m not mistaken, your solution works if Trunk1 and Trunk2 both use IP addresses.
If you are required to use domain names, you must somehow map those domain names to IP addresses.
In my case, both IP addresses must be mapped to the same domain name and I don’t how to alternatively use each IP.

If PJSIP had some sort of Dialing allowing to define, call by call, this domain to IP mapping, that would be perfect.

Alternatively, if I could set in PJSIP aor settings, something:
[foo1]
type=aor
dns_override_domain=example.com
dns_override_ip=1.2.3.4
server_uri=sip:example.com

[foo2]
type=aor
dns_override_domain=example.com
dns_override_ip=1.2.3.5
server_uri=sip:example.com

then, when Asterisk has to send anything to foo1 or foo2, before querying DNS services, it would just resolve any instance of example.com withe either 1.2.3.4 or 1.2.3.5, depending on which contact is dialed to.

It works with FQDNs as well.

Just set up SRV records to both IPs with the same priority and weight for each IP.

@PitzKey
I edited [1] as my attempts to use DNS SRV failed miserably.

[1] Cannot trunk with domain names with PJSIP

Please keep everything in one thread.

I am not sure I am following… You will need one FQDN sip.example.com that has two SRV records, one record for each IP. Once the records are in place, confirm that you actually see them, using dig.

Then, create one PJSIP “Trunk” and use the FQDN.

@PitzKey
Sorry for using another thread.

Thinking back to my requirements, I forgot to mention I would appreciate to send OPTIONS to both SBC instances (the one I’m trunking with).

This leads me to configure PJSIP with one single endpoint and two AOR: one per SBC.
This way, Asterisk would continuously send OPTIONS to both instances and I could use PJSIP_CONTACT to select the SBC I would like to send calls to.

With this goal in mind, everything would be OK, if I was not required to use the same foobar.example.com domain name for both AORs as for AOR1, I would like my target foobar.example.com to resolve to IP1 and for AOR2, I would like my target foobar.example.com to resolve to IP2.

If I had a way to tell Asterisk to use a specific resolver for anything related to a specific AOR …

Thoughts ?

Reading my above message, I would to clarify it a bit further.

The provider I’m trunking wants to receive either on IP1 or IP2, INVITEs with a domain name in Request-URI:
INVITE: sip:411@foobar.example.com;user=phone SIP/2.0

Incoming INVITE with IP address instead of domain name are treated correctly but the provider insists these are not compliant with its rules.

This could also be achieved by using an outbound_proxy. For example with an endpoint of:

[bob]
type=endpoint
disallow=all
allow=ulaw
outbound_proxy=sip:192.168.2.100\;lr\;hide

SIP traffic will be sent to 192.168.2.100, with a requested URI kept in tact. Dialing:

PJSIP/bob/sip:1000@community.asterisk.org

Results in:

<--- Transmitting SIP request (945 bytes) to UDP:192.168.2.100:5060 --->
INVITE sip:1000@community.asterisk.org SIP/2.0
Via: SIP/2.0/UDP 192.168.2.19:5060;rport;branch=z9hG4bKPjbbf221e9-c282-4fb6-8d8c-432f3eec2fcb
From: "Anonymous" <sip:anonymous@anonymous.invalid>;tag=47db5f34-c020-4da5-b370-3d7026fc2c07
To: <sip:1000@community.asterisk.org>
Contact: <sip:asterisk@192.168.2.19:5060>
Call-ID: ddde64f2-f9f0-4376-a681-e18182e35165
CSeq: 28498 INVITE
Allow: OPTIONS, REGISTER, SUBSCRIBE, NOTIFY, PUBLISH, INVITE, ACK, BYE, CANCEL, UPDATE, PRACK, MESSAGE, REFER
Supported: 100rel, timer, replaces, norefersub, histinfo
Session-Expires: 1800
Min-SE: 90
Max-Forwards: 70
User-Agent: Asterisk PBX GIT-18-07a850c6dd
Content-Type: application/sdp
Content-Length:   237

v=0
o=- 1304151938 1304151938 IN IP4 192.168.2.19
s=Asterisk
c=IN IP4 192.168.2.19
t=0 0
m=audio 16808 RTP/AVP 0 101
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20
a=maxptime:150
a=sendrecv

The round robin would still be up to you.

That’s a nice idea that removes messing with DNS !
I’m gonna try it immediately and report here.

I should also add that AORs support specifying an outbound_proxy as well.

I upgraded to Debian Bookworm’s Asterisk 20 and configured two AORs for the same Endpoint.

How do you dial through a specific AOR then and still use domain name in INVITE Request-URI ?
I used something like but Dial(PJSIP/othertestbed/sip:0123456789@192.168.4.73) but domain is lost in the process.

I’m sure using two endpoints, each with a single AOR would work around the issue but for the sake of completeness, I prefer to ask.

PJSIP/0123456789@othertestbed will dial the "othertestbed’ endpoint, using the AOR, and place the dialed number in the request URI user portion.

Otherwise you’d need to actually show configuration.

If an endpoint has two AOR, which one will be dialed though PJSIP/0123456789@othertestbed ? Both ? The first one ? A random one (if I could choose, the would be my favorite) ?

Probably the first one. There’s no defined behavior for that.