PJSIP transport selection logic

Hi all,
I am running Asterisk 13.18.3 with PJSIP channel driver on a multi-homed server. Some enpoints are roaming between external and internal network, and they need to be operational regardless of the network they currently reside. However, it is not clear how to implement this scenario.

  1. If I specify transport in pjsip.conf, endpoints are operational from one network only (this is expected).
  2. If I omit transport, registration initially succeeds, but then Asterisk sends OPTIONS and INVITEs to the endpoint from a different IP, not respecting the IP recevied in the initial REGISTER message.
  3. If I specify transport as ‘0.0.0.0-udp’ binding IP address 0.0.0.0, I end up with the following error:
    Unable to retrieve PJSIP transport '0.0.0.0-udp'

My suggestion is that if transport is not specified, it should be selected based on the IP of an endpoint. However, it is not the case as you can see.

So, I have the following questions:

  1. What is the correct way to get SIP endpoints operational in a multi-homed environment?
  2. What is the transport selection logic if transport is not set explicitly? From here (3a), it is not clear how hashing mechanism works.
  3. What does transport 0.0.0.0 mean (it is provided in sample configs and available in FreePBX) and why it is not working?
    Thanks.

The transport option takes the name of the transport, if it’s not found then there is no transport by that name. You haven’t provided explicit configuration so I can’t say what it should be.

If 0.0.0.0 is used then it is up to the underlying operating system to route accordingly, and we ask the operating system what interface the packet will go out on and update the message accordingly.

How things should be configured and used very much depends on the specific network layout and what it is like.

Transports in pjsip.conf:

[192.168.44.9-udp]
type=transport
protocol=udp
bind=192.168.44.9:5060
external_media_address=XXX.XXX.XX.26
external_signaling_address=XXX.XXX.XX.26
allow_reload=yes
local_net=192.168.44.0/24
local_net=10.34.238.0/24

[10.34.238.10-udp]
type=transport
protocol=udp
bind=10.34.238.10
external_media_address=XXX.XXX.XX.26
external_signaling_address=XXX.XXX.XX.26
allow_reload=yes
local_net=192.168.44.0/24
local_net=10.34.238.0/24

10.34.238.0/24 - tunnel
192.168.44.0/24 - LAN

Endpoints are roaming between LAN and tunnel.
If an endpoint is registered from LAN (192.168.44.112) and transport IS NOT specified, subsequent OPTIONS message is sent from 10.34.238.10 (which is strange).

Hostname> pjsip show transports

Transport:  10.34.238.10-udp          udp      0      0  10.34.238.10:5060
Transport:  192.168.44.9-udp          udp      0      0  192.168.44.9:5060

I’d suggest also providing actual traffic too showing the messages.




192.168.44.112 - endpoint
192.168.44.9 - Asterisk LAN IP
10.34.238.10 - Asterisk tunnel IP

Transport config is provided above

Hostname> pjsip show endpoint 3202

 transport                          :  <empty>

Transport is not specified (set to Auto in FreePBX, provisioned to Asterisk correctly)

And if you use a wildcard 0.0.0.0?

No, I mean create a single transport bound to 0.0.0.0

You can’t specify “0.0.0.0-udp” because that means “use a transport section named 0.0.0.0-udp” and if you don’t have one nothing will happen.

Do you mean creating ONE transport only bound to 0.0.0.0 and disabling all the other transports?

Yes, instead of creating individually bound ones.

Changed configuration as you advised:

[root@hostname]# asterisk -rx "pjsip show transports"
Transport:  0.0.0.0-udp               udp      0      0  0.0.0.0:5060
Objects found: 1
[root@hostname]# netstat -anp | grep 5060
udp        0      0 0.0.0.0:5060            0.0.0.0:*                           15372/asterisk
[root@hostname]# asterisk -rx "pjsip show endpoint 3208" | grep -e 'transport'
 media_use_received_transport       : false
 transport                          : 0.0.0.0-udp

Looks like the behaviour is correct now:

Continuing to monitor the behaviour

The above scenario works.

However, it is often needed to use a combination of static and dynamic endpoints.
For example, trunks should be bound to a particular interface, whereas clients should be dynamic due to the roaming between networks.

How to implement this scenario in PJSIP?

I don’t know if anyone has fully scoped out those scenarios, fixed any bugs that may exist, and figured out how it should be done so I can’t answer on specific configuration as to what to use that is known to work.

@jcolp,

May be it is worth raising a ticket in JIRA with detailed explanation of the issue?
At least, the observed behavior in case when no transport is explicitly specified is obviously a bug.

You can do so, but I have no time frame on when such a thing would get looked into.