Summary:ASTERISK-26780: res_pjsip: PJSIP Registration Fails when transport=transport-udp6
Reporter:Peter Sokolov (peterdoo)Labels:
Date Opened:2017-02-09 11:20:39.000-0600Date Closed:2020-05-13 06:44:17
Versions:14.2.1 Frequency of
is related toASTERISK-26571 res_pjsip: Resolution incorrect when explicit IPv6 transport configured
Environment:Attachments:( 0) Debug-Log.txt
( 1) pjsip_resolver.c
( 2) pjsip.conf
( 3) sip.log
Description:Probably related to ASTERISK-26309.

When a section "type=registration" in pjsip.conf contains the line
registration fails even though the registrar hostname resolves to both, IPv4 and IPv6 address.

With "transport=transport-udp" registration is successfull to the IPv4 address of the registrar and without the "transport=" line, registration is successfull to the IPv6 address of the registrar.

Debug messages show that with "transport=transport-udp6", Asterisk will only lookup DNS names of type 1 (A), 33 (SRV) and 35 (NAPTR), but not type 28 (AAAA), while in other two cases (transport-udp and without transport=) it will lookup DNS types 1, 33, 28 and 35.

As can be seen in the sip.log it somehow tries to send out a REGISTER request directed to IPv4 address of the registrar, otherwise filled with IPv6 addresses. It looks like this packet does not get sent out however:
Failed to send Request msg REGISTER/cseq=37962 (tdta0x7fb4500607b0)! err=120101 (Network is unreachable)

I have not checked whether the behavior is similar when transport= is used on type=endpoint.
Comments:By: Asterisk Team (asteriskteam) 2017-02-09 11:20:40.526-0600

Thanks for creating a report! The issue has entered the triage process. That means the issue will wait in this status until a Bug Marshal has an opportunity to review the issue. Once the issue has been reviewed you will receive comments regarding the next steps towards resolution.

A good first step is for you to review the [Asterisk Issue Guidelines|https://wiki.asterisk.org/wiki/display/AST/Asterisk+Issue+Guidelines] if you haven't already. The guidelines detail what is expected from an Asterisk issue report.

Then, if you are submitting a patch, please review the [Patch Contribution Process|https://wiki.asterisk.org/wiki/display/AST/Patch+Contribution+Process].

By: Peter Sokolov (peterdoo) 2020-02-05 09:45:28.626-0600

ASTERISK-26571 now makes sure that DNS results that do not correspond to the requested protocol are not used anymore.
However the resolver (tested in Asterisk 16.8.0) still requests wrong DNS records sometimes when IPv6 transport is specified.
In the file res/res_pjsip/pjsip_resolver.c the conditions are wrong, so when IPv6 transport is requested, it will make DNS request for A record instead of requesting AAAA record. AAAA records are only requested when no transport is specified and for names within SRV and NAPTR records (those always generate additional DNS requests without specifying IPv6). So if there is no NAPTR nor SRV record for a SIP host and you specify IPv6 transport for registration or endpoint, it will not work as no AAAA DNS request is made.

I propose to modify res/res_pjsip/pjsip_resolver.c with the following:

Inside the function sip_resolve_callback use the following for IPv6 lookup instead of the current code:
/* If an explicit IPv6 target transport has been requested look for only AAAA records */
if ((target->transport & PJSIP_TRANSPORT_IPV6) &&
 sip_transport_is_available(target->transport)) {
sip_resolve_add(resolve, ast_dns_srv_get_host(record), T_AAAA, C_IN, target->transport,
have_srv = 1;
} else if (!(target->transport & PJSIP_TRANSPORT_IPV6) &&
   sip_transport_is_available(target->transport + PJSIP_TRANSPORT_IPV6)) {
sip_resolve_add(resolve, ast_dns_srv_get_host(record), T_AAAA, C_IN, target->transport + PJSIP_TRANSPORT_IPV6,
have_srv = 1;
Inside the function sip_resolve use the following for IPv4 and IPv6 lookup instead of the current code:
if ((type == PJSIP_TRANSPORT_UNSPECIFIED && sip_transport_is_available(PJSIP_TRANSPORT_UDP6)) ||
((type & PJSIP_TRANSPORT_IPV6) && sip_transport_is_available(type))) {
res |= sip_resolve_add(resolve, host, T_AAAA, C_IN, (type == PJSIP_TRANSPORT_UNSPECIFIED ? PJSIP_TRANSPORT_UDP6 : type), target->addr.port);
} else if (!(type & PJSIP_TRANSPORT_IPV6) && sip_transport_is_available(type + PJSIP_TRANSPORT_IPV6)) {
res |= sip_resolve_add(resolve, host, T_AAAA, C_IN, type + PJSIP_TRANSPORT_IPV6, target->addr.port);

if ((type == PJSIP_TRANSPORT_UNSPECIFIED && sip_transport_is_available(PJSIP_TRANSPORT_UDP)) ||
(!(type & PJSIP_TRANSPORT_IPV6) && sip_transport_is_available(type))) {
res |= sip_resolve_add(resolve, host, T_A, C_IN, (type == PJSIP_TRANSPORT_UNSPECIFIED ? PJSIP_TRANSPORT_UDP : type), target->addr.port);
Rename all pjsip_transport_get_type_name to pjsip_transport_get_type_desc. This makes sure that the log/debug info shows whether the transport is IPv6 or IPv4 which is not the case using pjsip_transport_get_type_name.

I have tested it with the modifications and could then specify IPv6 transport for endpoints and registrations without breaking the functionality. I could see no negative effects on existing functionality.

I am also attaching the complete res/res_pjsip/pjsip_resolver.c with modifications if someone has the possibility to make a patch for Asterisk (16 and 17).

By: Peter Sokolov (peterdoo) 2020-02-05 09:46:51.882-0600

Attaching pjsip_resolver.c that works when IPv6 transport is requested.

By: Friendly Automation (friendly-automation) 2020-05-13 06:44:18.299-0500

Change 14400 merged by Joshua Colp:
pjsip_resolver.c: Ensure AAAA dns requests are made.


By: Friendly Automation (friendly-automation) 2020-05-13 06:44:38.379-0500

Change 14404 merged by Friendly Automation:
pjsip_resolver.c: Ensure AAAA dns requests are made.


By: Friendly Automation (friendly-automation) 2020-05-13 06:44:39.652-0500

Change 14421 merged by Joshua Colp:
pjsip_resolver.c: Ensure AAAA dns requests are made.