[asterisk-bugs] [JIRA] (ASTERISK-26780) res_pjsip: PJSIP Registration Fails when transport=transport-udp6
Peter Sokolov (JIRA)
noreply at issues.asterisk.org
Mon Feb 10 05:03:25 CST 2020
[ https://issues.asterisk.org/jira/browse/ASTERISK-26780?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=249668#comment-249668 ]
Peter Sokolov edited comment on ASTERISK-26780 at 2/10/20 5:03 AM:
-------------------------------------------------------------------
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:
1.
Inside the function sip_resolve_callback use the following for IPv6 lookup instead of the current code:
{noformat}
/* 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,
ast_dns_srv_get_port(record));
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,
ast_dns_srv_get_port(record));
have_srv = 1;
}
{noformat}
2.
Inside the function sip_resolve use the following for IPv4 and IPv6 lookup instead of the current code:
{noformat}
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);
}
{noformat}
3.
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).
was (Author: peterdoo):
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:
1.
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,
ast_dns_srv_get_port(record));
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,
ast_dns_srv_get_port(record));
have_srv = 1;
}
2.
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);
}
3.
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).
> res_pjsip: PJSIP Registration Fails when transport=transport-udp6
> -----------------------------------------------------------------
>
> Key: ASTERISK-26780
> URL: https://issues.asterisk.org/jira/browse/ASTERISK-26780
> Project: Asterisk
> Issue Type: Bug
> Security Level: None
> Components: Resources/res_pjsip
> Affects Versions: 14.2.1
> Reporter: Peter Sokolov
> Severity: Trivial
> Attachments: Debug-Log.txt, pjsip.conf, pjsip_resolver.c, sip.log
>
>
> Probably related to ASTERISK-26309.
> When a section "type=registration" in pjsip.conf contains the line
> transport=transport-udp6
> 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.
--
This message was sent by Atlassian JIRA
(v6.2#6252)
More information about the asterisk-bugs
mailing list