This is a brief tale about an upgrade from Debian 8 / Asterisk 11 / FreePBX 13 using exclusively chan_sip to Debian 10 / Asterisk 16 / FreePBX 15 using exclusively chan_pjsip.
The old PBX was running happily but I decided it was time to bring it to a more modern state. While I could have easily loaded chan_sip and brought all that cruft over I decided to start fresh and remake the dozen extensions and three trunks (not a big PBX) with pjsip, leaving chan_sip out altogether. I wasn’t sure where I’d run into challenges. Here were the ones I encountered.
Extensions
TLS: The FreePBX-generated config points to the wrong cert file, at least in my scenario where I am using Letsencrypt. (Bug [FREEPBX-20610] PJSIP TLS transport points to wrong certificate file - Sangoma Issue Tracker) Also, old endpoints seem to have a really hard time negotiating with modern TLS and even though I worked at it for a long time, I couldn’t come up with a TLS configuration on FreePBX that was acceptable to an Obi 110. Globally, in Asterisk SIP Settings / pjsip, I had to turn off verify_client because otherwise endpoints that don’t present a client certificate are rejected.
IPv6: Not configurable in FreePBX yet for pjsip. I used the custom_post.conf files to add IPv6 transports, for example (in pjsip.transports_custom_post.conf):
To allow my extensions to use IPv6 I had to add settings for them not available in the GUI: (in pjsip.endpoint_custom_post.conf) (Not needed with current Asterisk 16)
[1102](+) rtp_ipv6=yes
You don’t need to tell extensions to use the ipv6 transport; Asterisk figures this out when they initially register over IPv6.
NAT: for endpoints behind NAT you choose from these options, which look a little different from the old chan_sip NAT options:
IPv6: To use the IPv6 transport here I had to put in an override in the pjsip.endpoint_custom_post.conf file:
[Callwithus](+)
transport=ipv6-udp
Registration, authentication, etc.: This is all easier with FreePBX’s pjsip trunk screen than the chan_sip trunk screen, in my opinion. Just fill in the blanks. I have a Vitelity trunk where I register to one server and send outbound calls to a different one. No problem but you have to know which fields to use:
Other than dealing with IPv6 and TLS, which many people won’t use, I didn’t really find anything difficult about moving from chan_sip to chan_pjsip. I don’t know how long it’s been the case, but I am happy that by default the extensions are set up for NAT handling. Just wanted to share my experience and “I survived!” even though folks often post about their troubles using the newer SIP driver.
Did you confirm you need “rtp_ipv6”? Recent versions of Asterisk should use the signalling transport IP protocol version to then choose RTP automatically. I worked on it at SIPit ages ago after talking to various other vendors on what they do and how the industry does it.
Ah, so you can configure one trunk that works for in and outbound even though the IP addresses of the in and outbound servers are different. Didn’t know that.
Can the same thing be done when using IP authentication and not registration?
Sorry if this is obvious question. I have been using chan_SIP trunk with my chan_SIP extensions. Can I use chan_PJSIP with chan_SIP trunk or do I need to make a chan_PJSIP trunk?
My other question is, I have one DID account with my SIP provider. Can I use that account to build two trunks (chan_SIP and chan_PJSIP)?
Yes. There is nothing preventing you from having both chan_sip and pjsip trunks and extensions in any combination.
Probably not. If you are registering trunks, you must use different credentials for each trunk. If your provider allows you to create sub-accounts, you could probably do this, but I can’t think of any benefit to doing so.
For those relying on the Match field for pjsip trunks, know that the Firewall module does not whitelist these IPs automatically as is done for the SIP Server. I have an open feature request for this: https://issues.freepbx.org/browse/FREEPBX-18741
Oh, I’d also check whether you actually do need to specify the transport on the endpoint. Asterisk 16 DNS resolution prefers IPv6, so the resolution should result in AAAA records being used and thus the IPv6 transport chosen. If that’s not happening then I can take a gander and see why.
In FreePBX you have to choose a transport for trunk endpoints. Sounds like another feature request: an “auto” choice that omits the transport= line from the endpoint definition.
Ah, yeah, in Asterisk it’s not required unless you have multiple competing transports and want to force it. For most people it’ll choose the right one based on the target of the SIP message.
Today I found that the WebRTC phone doesn’t work over IPv6, but does work over IPv4. Investigating. I’m mentioning it in this thread because the error generated is:
[2019-10-04 10:01:46] ERROR[29983]: res_pjsip.c:3662 ast_sip_create_dialog_uas: Could not create dialog with endpoint 991101. Invalid URI (PJSIP_EINVALIDURI)
That should be okay. That logic is updating the received Contact to enforce connection reuse, and due to the way things work internally being "ws’ is pefectly fine. If it were “wss” it wouldn’t actually work. The spec also states that the transport parameter should be “ws” for URIs[1]. WSS is only valid in the Via header.