PJSIP NAT not working

Hi Everyone,

For some reason, my system lost all audio for inbound calls. I didn’t change anything … hadn’t even logged into the pbx in months. Outbound calls work fine. Sometimes, inbound calls work, but almost all are failing.

In the network traces for failed calls, I see my end reaching out to the RTP server, but no return traffic. Calls that work, I see traffic in both directions.

My provider is Flowroute and they are telling me there is a NAT problem. They see:
Contact: sip:w.x.y.z:5160
where w.x.y.z is my internal IP address. They are telling me that the connect should show the NAT’ed external public address.

Odd thing is, on calls that work and those that fail, the contact line is the same. They tell me NAT problems can cause inconsistent audio issues. Grrrr…

Anyway, in the PBX under Settings -> Asterisk SIP Settings -> Chan SIP Settings, I have it set to Dynamic IP and for Dynamic Host I have specified the hostname of my external address. I have made no specific settings in the PJSIP tab.

Keep in mind, this is the way it’s always been set up and has worked flawlessly for months, and then suddenly it broke.

I have both SIP and PJSIP trunks so I’m a little worried about randomly changing values. If anyone can give me some specifics on where to look, that would be helpful.

It’s just so odd… calls that route to specific RTP IP’s work fine. Calls that route to others fail. I’ve just never seen this behavior before and could use some help.

Thanks to you all in advance!

FreePBX 13.0.197.28 / Asterisk 13.10.0

.

That probably depends on whether or not they implement comedia at their end, to learn the true media address from he media they receive.

1 Like

In Asterisk SIP Settings, General tab, confirm that External Address and Local Networks are correctly set. If you change these, you must restart Asterisk.

I recommend a pjsip trunk for Flowroute; the setup is very simple. The only non-default Advanced setting I have is
From Domain: sip.flowroute.com

If you still have trouble, at the Asterisk command prompt type
pjsip set logger on
and make a failing call. The SIP trace will appear in the Asterisk log, along with the normal entries.

The outgoing INVITE should show your public IP in the Via and Contact headers and (most importantly for your issue) in the c= field of the SDP.

How would I determine if they are using comedia or not?

My trunks are PJSIP for Flowroute. Sorry if that was unclear. I’ve not set External IP Address on the “Chan PJSIP Settings” tab… nothing has been set there before and it was working fine. The external NAT address is only defined on the Chan SIP tab.

The trouble calls are inbound calls only and when I trigger a failed call, I see an inbound INVITE followed by an outbound response INVITE a little later.

The inbound invite shows my internal IP address:
INVITE sip:[email protected]:5160 SIP/2.0

Followed by several Via: SIP lines. The c= field shows the IP address of the server on the other end. Certain IP’s here fail. Others work.

Later in the exchange, I see and outbound response INVITE and there I see my internal address in the Contact field as well as the c= field.

Sure, that’s normal if you are behind a NAT.

That is wrong and almost certainly the immediate cause of your issue.

Please confirm that in Asterisk SIP Settings, General tab, External Address and Local Networks are correctly set, and that you have restarted (not just reloaded) Asterisk after any change.

If you still have the same trouble (c= showing local address), please post the contents of
/etc/asterisk/pjsip.transports.conf
(redact your public IP where it appears, e.g. by replacing the last two octets by xxx)

This will tell us whether the problem is in FreePBX or in Asterisk, and we can troubleshoot further accordingly.

I may have misinterpreted that. When the call is answered, there should be a 200 OK response to the incoming INVITE. If Asterisk is sending an INVITE to Flowroute for the same call, that’s a re-invite and I wouldn’t expect it. On the off chance that Asterisk believes Direct Media is possible (even though it’s not), that could possibly be the issue. Turn off Direct Media in the trunk Advanced settings and retest.

OK, so I went ahead and tinkered with the Chan PJSIP Settings tab item “External IP Address”…

In my Chan SIP tab I have the External host defined as “outside.mydomain.com” which is set to my public IP address in the local host file on the pbx. I have a script that updates it if the outside address changes and as a result, I don’t need to do anything within the pbx… it just picked up the change automatically.

I tried to do the same in the PJSIP tab and the behavior is markedly different. First, I tried adding “outside.mydomain.com” to the “External IP Address” in the PJSIP tab and asterisk did not pick up the change. I had to stop/start freepbx.service for the change to be recognized.

Then, when attempting an inbound call, audio passed for just a second or two and the call was dropped. Looking at the pjsip logs, I could see these values:
Contact:Contact: sip:w.x.y.z:5160
c=IN IP4 outside.mydomain.com

So, for some reason, freepbx resolved the address for the Contact field, but did not resolve it for the c= field. Since outside.mydomain.com isn’t resolvable to the outside world, my guess is the RTP endpoint couldnt return data to me and the call was dropped.

If I change the “External IP Address” pjsip setting to the numeric IP address of my outside interface, both Contact and c= get the correct IP address and calls started working.

This inconsistency between the SIP and PJSIP handling of external IP addresses has proven to be a bit frustrating. Now, it looks like instead of simply updating my /etc/hosts file, I’ll need to also script an update to pjsip.transports.conf and do a hard restart on the entire asterisk/freepbx processes if my external address changes.

I’m new to PJSIP, but is there a better way to handle dynamic external IP addresses?

I also realize I’m a version or two behind the latest-and-greatest. Has this functionality been improved in newer versions?

Now, can someone help me with the mystery of why this suddenly failed? My pbx is one of those servers that typically just runs and I never really have to mess with it. It was running with PJSIP trunks for months without me ever having defined the external address anywhere but in the Chan SIP section. My IP address last changed 36 days ago and my scripts ran, adjusted the outside.mydomain.com entry in /etc/hosts and the pbx never missed a beat, so I don’t think a recent address change caused this outage. I’m just at a loss as to why it would have suddenly failed with no action whatsoever on my part.

Thanks again for your help… your questions helped nudge me in the right direction.

I suspect that Flowroute previously tolerated the incorrect behavior but doesn’t anymore. If you are in an area where Flowroute isn’t the carrier, it’s possible that they moved you from one CLEC to another. Or, if they recently got numbers in your area, from another CLEC to them.

It’s also possible that a system or module update broke something.

I have never used External IP Address or Local network settings on the pjsip tab. IMO, those are advanced settings for folks with multiple NICs or requiring special routing, e.g. for multiple ISPs.
If you leave them blank, what ends up in pjsip.transports.conf ?

Leaving the pjsip external ip empty gives these values in pjsip.transports.conf:
[0.0.0.0-udp]
type=transport
protocol=udp
bind=0.0.0.0:5160
allow_reload=no
local_net=x.x.x.x/255.255.0.0
local_net=y.y.y.y/255.255.255.0

(We have an internal network bridge across firewalls with phones on both sides, that’s why there are two local_net entries.)

Adding an address to the pjsip external ip adds these two lines to the pjsip.transports.conf file:
external_media_address=a.b.c.d
external_signaling_address=a.b.c.d

It definitely no longer works if I leave it blank.

Flowroute claims that nothing changed on their side, but I suspect you’re probably correct in that something seemingly unrelated to the issue changed and their support person didn’t see a connection. I wanted to blame a module update, but I hadn’t updated modules since April.

It’s really a bummer that I have to restart the entire application for an IP change. That means that in order to fix a pjsip problem, all my sip connections will be dropped as well.

Two things seem strange. First, the value you set for External Address in Asterisk SIP Settings → General SIP Settings did not propagate to pjsip.transports.conf. Also, a domain name in external_media_address did not get looked up. If those worked properly and you have dnsmgr enabled, restarting Asterisk should not be necessary. See

A quick test (not thorough) showed this working on my system (the name got looked up and the corresponding address made it to Contact and c=).

Running Asterisk 16.17.0

I didn’t set anything under General SIP Settings… only under Chan SIP, and now Chan PJSIP.

Should I remove the external IP stuff from the Chan PJSIP tab and enter it in the General SIP tab? Any downside to this?

DNS Manager appears to be running:
dnsmgr status
DNS Manager: enabled
Refresh Interval: 300 seconds
Number of entries: 0

Sorry, I don’t know the details. Set up External Address and Local Networks on the General tab, restart Asterisk and see whether it works. If the name doesn’t propagate to pjsip.transports.conf, you may need one or more module updates. If the name propagates but pjsip fails to look it up, you may need a newer Asterisk version. What versions of FreePBX and Asterisk are you running?

Asterisk version 13.10.0 was given in the initial post. This version does not support the dnsmgr behavior or even resolving the configured hostname if I recall.

comedia is a workaround for systems that don’t understand NAT. If you have the external media address correctly set, the workaround isn’t needed. However, the way you would detect it is if c= lines in your outgoing SDP contain an address they can’t use, but they still send to the correct address, but only after you have sent something to them.

However this is at their end, so there is nothing you can do about it. It was just an explanation as to why it sometimes worked.

(Asterisk has a similar option, which is not relevant in this case, and rarely actually needed.)

OK, so what I’m gathering is that for now, because I’m on Asterisk 13, I will need to manually adjust the pjsip.transports.conf file and restart freepbx if my external address changes. Once I upgrade to the latest version of FreePBX & Asterisk, I can simply add the value to the SIP General tab, remove my custom scripts and dnsmgr will handle it from there.

Is that an accurate summary?

1 Like

This topic was automatically closed 31 days after the last reply. New replies are no longer allowed.