Question: Prevent PJSIP from using another IP on qualify or re-register

Hello Asterisk experts and enthusiasts,

I’m currently having a problem with asterisk that I can’t figure out how to solve: After using chan_sip for many years without issues I decided to migrate to pjsip. I’m using Asterisk 17.3.0 on Linux.

After some getting used to (and some more gray hairs) I’ve almost a working setup again. Almost because there is this last problem:

My SIP provider has a nice NAPTR record that looks like the following (redacted):

phone.provider.example.     4074    IN      NAPTR   60 50 "S" "SIP+D2T" "" _sip._tcp.phone.provider.example.
phone.provider.example.     4074    IN      NAPTR   50 50 "S" "SIP+D2U" "" _sip._udp.phone.provider.example.

The SRV record for UDP looks like this:

_sip._udp.phone.provider.example.   5452    IN      SRV     10 1 5060 phone-a.provider.example.
_sip._udp.phone.provider.example.   5452    IN      SRV     10 1 5060 phone-b.provider.example.

And that’s where the problem starts. I’ve got two servers with the same weight. So my asterisk setup is registering my phone numbers (every number needs its own registration) to one of the two servers (redacted and shortened):

[Apr 10 11:50:18] VERBOSE[27575] res_pjsip_logger.c: <--- Transmitting SIP request (870 bytes) to UDP:[XXXX:7::10]:5060 --->
REGISTER sip:phone.provider.example SIP/2.0
Via: SIP/2.0/UDP [XXXX::1]:5060;rport;branch=z9hG4bKPj6a4d2d2b-a2cc-41f3-bfa9-6a35fa81b2a3
From: <sip:+1234567890@phone.provider.example>;tag=bb650b57-ce50-4a18-aff3-150769eb3792
To: <sip:+1234567890@phone.provider.example>
CSeq: 57942 REGISTER
Contact: <sip:+1234567890@[XXXX::1]:5060;line=zzpjnyi>


[Apr 10 11:50:18] VERBOSE[5364] res_pjsip_logger.c: <--- Received SIP response (521 bytes) from UDP:[XXXX:7::10]:5060 --->
SIP/2.0 200 OK
CSeq: 14789 REGISTER
From: <sip:+499118109600@phone.provider.example>;tag=9910ad30-e188-4393-9717-41bddcb390fd
To: <sip:+499118109600@phone.provider.example>;tag=sip+6+a41c0014+8bcbaf4f
Via: SIP/2.0/UDP [XXXX::1]:5060;received=XXXX::1;rport=5060;branch=z9hG4bKPjb11a4c90-694c-49da-bb22-4afc86b15d9b
Contact: <sip:+499118109600@[XXXX::1]:5060;line=wkuwevp>;Expires=1200

After some time a qualify OPTIONS request is send. Mostly it hits the same IP address as the registration was send to. But sometimes it is send to the second IP address (XXXX:8::10 not XXXX:7::10):

[Apr 10 12:14:36] VERBOSE[28695] res_pjsip_logger.c: <--- Transmitting SIP request (500 bytes) to UDP:[XXXX:8::10]:5060 --->
OPTIONS sip:+1234567890@phone.provider.example;user=phone SIP/2.0
Via: SIP/2.0/UDP [XXXX::1]:5060;rport;branch=z9hG4bKPj22a438fd-440b-4f7c-95c5-6de4ef865505
From: <sip:+1234567890@phone.provider.example>;tag=d8d25981-06c7-471c-9fa3-bd226128ded4
To: <sip:+1234567890@phone.provider.example>
Contact: <sip:+1234567890@[XXXX::1]:5060>
CSeq: 17677 OPTIONS


[Apr 10 12:14:36] VERBOSE[28231] res_pjsip_logger.c: <--- Received SIP response (537 bytes) from UDP:[XXXX:8::10]:5060 --->
SIP/2.0 403 Forbidden
Call-ID: e7afd196-19dc-4f15-8c81-46f91f0acdfd
CSeq: 17677 OPTIONS
From: <sip:+1234567890@phone.provider.example>;tag=d8d25981-06c7-471c-9fa3-bd226128ded4
To: <sip:+1234567890@phone.provider.example>;tag=sip+2+1556000d+4ed19625
Via: SIP/2.0/UDP [XXXX::1]:5060;received=XXXX::1;rport=5060;branch=z9hG4bKPj22a438fd-440b-4f7c-95c5-6de4ef865505
Contact: <sip:+1234567890@[XXXX::1]:5060>

In this case, the SIP server sends a 403 Forbidden back. If that happens with a REGISTER SIP message (re-registration) the registration is done on a different server. This leads to all calls currently active on the re-registered SIP-Address on the old server being terminated.

The calling or called parties think I’m rude and hung up on them :frowning:

Does someone know a solution to force pjsip to stick to one server after registering to it?

Thank you in advance for any hint or help on this topic.

Here is an excerpt of my pjsip.conf containing my SIP configuration for the external connection:

[global]
max_initial_qualify_time=120

;== Transports
[udp6]
type=transport
protocol=udp
bind=[::]
tos=cs3
cos=3

[endpoint-provider](!)
type=endpoint
context=extern
rewrite_contact=yes
dtmf_mode=rfc4733
send_connected_line=no
disallow=all
allow=g722
allow=alaw
allow=ulaw
direct_media=no
send_rpid=yes
user_eq_phone=yes
timers=no
rtp_ipv6=no
from_domain=phone.provider.example
tos_audio=ef
tos_video=af41
cos_audio=5
cos_video=4
tone_zone=de
language=de

[aor-provider](!)
type=aor
authenticate_qualify=yes
qualify_frequency=300
minimum_expiration=60
default_expiration=1200
maximum_expiration=3600
max_contacts=1
remove_existing=yes

[registration-provider](!)
transport=udp6
expiration=1200
line=yes

;== Credentials
[auth-provider1234567]
;XXXXXX

;== Outbound registrations

;=== First
[ext1234567](aor-provider)
type=aor
contact=sip:+1234567890@phone.provider.example

[ext1234567]
type=identify
endpoint=ext1234567
srv_lookups=no
match_header=To: <sip:+1234567890@phone.provider.example>

[ext1234567](endpoint-provider)
type=endpoint
from_user=+1234567890
outbound_auth=auth-provider1234567
aors=ext1234567

[ext1234567](registration-provider)
type=registration
server_uri=sip:phone.provider.example
client_uri=sip:+1234567890@phone.provider.example
outbound_auth=auth-provider1234567
contact_user=+1234567890
endpoint=ext1234567

;=== Second
; 
; more registrations
; for different numbers.

There is no functionality or option to force this behavior, it would need to be done externally through something like a local DNS server. This is because the SRV records are configured in a load balancing scenario, so using the same target would defeat that.

Hello jcolp,

thank you for your fast response. For the initial registration I completely understand your argument. But for the re-registration and qualify requests I think it should be possible to keep them to the same IP address (at which the registration was done).

For my SIP provider, the two DNS-Names within their SRV-Record seem to reference different locations for their two computing centers. So I think my chances, for a request for synchronizing the registrations between the SIP servers at the two locations, to succeed are minimal.

My two options are therefore:

  1. Back to chan_sip :frowning:
  2. “fake” SRV records that have different priorities to retain high availability :face_with_raised_eyebrow:
  3. Convince my provider to change their SIP setup :rofl:
  4. Open a feature request on the asterisk bug tracker

Are there any other options? Does Option 4 have any chance to succeed?

Hello jcolp,

I’ve done a little RFC digging in the meanwhile and now I don’t think that the behavior of asterisk is correct. Maybe I’m misinterpreting this (or have overlooked an update to this RFC), but RFC 3261 (SIP: Session Initiation Protocol) states in Section 10.2.4 (Refreshing Bindings) that “[…]Registration refreshes SHOULD be sent to the same network address as the original registration, unless redirected.”.

This would eliminate my problem. Because my re-registrations (Registration refresh) are sometimes sent to a different IP address and terminates my calls.

I know, there is as “SHOULD” here, so the RFC allows a different implementation if there “[…] exist valid reasons in particular circumstances to ignore a particular item.”. So in my option there should be an option to opt for the RFC compliant behavior in asterisk.

Should I open a bug report for this or do have have misunderstood something?

OPTIONS, calls, and outbound registrations are separate. It could be done for registrations, but having the rest use the same would require some major reworking, and would need to be behind an option.

Hello jcolp,

ok, I understand. Should I open a ticket at the bug-tracker for implementing the behavior RFC 3261 describes for registration refresh on outbound registrations?

I think registrations are the most pressing issue for me. OPTIONS are secondary. I can still just disable qualify. I think outgoing calls should work regardless to which server they are sent, because the INVITE is authenticated anyway. But I’m currently not sure about that.

You can, just quote the RFC and such.

I will do that. Thank you for your support.

For everyone interested: This issue is filed on the asterisk bugtracker as ASTERISK-28823.

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