[Home]

Summary:ASTERISK-18232: Broken REGISTER sent to IPv4 server when bindaddr=[::]
Reporter:Jacek (jacek)Labels:
Date Opened:2011-08-07 08:23:43Date Closed:2016-09-27 13:36:02
Priority:MajorRegression?
Status:Closed/CompleteComponents:Channels/chan_sip/IPv6 Channels/chan_sip/Registration
Versions:11.23.1 13.11.2 Frequency of
Occurrence
Constant
Related
Issues:
containsASTERISK-18032 [patch] - IPv6 and IPv4 NAT not working
Environment:Attachments:( 0) changes.patch
Description:h3. CONFIGURATION

h4. DNS:

{noformat}sip.example.com. IN A 81.82.83.84

dynamichost.selfip.com. IN A 90.91.92.93
dynamichost.selfip.com. IN AAAA 2001:db8::{noformat}

h4. ifconfig

{noformat}eth0      Link encap:Ethernet  HWaddr 00:01:02:03:04:05
         inet addr:10.1.1.3  Bcast:10.255.255.255  Mask:255.0.0.0
         inet6 addr: 2001:db8::/48 Scope:Global{noformat}

h4. sip.conf

{noformat}[general]
bindaddr=[::]:5060
domain=dynamichost.selfip.com
fromdomain=dynamichost.selfip.com

localnet=10.0.0.0/8
externhost=dynamichost.selfip.com
externrefresh=60
nat=no

useragent=MySIPclient
sdpsession=MySIPclient

register => 123456789:passw0rd@sip.example.com/123456789{noformat}

h4. Notes:

* 90.91.92.93 is dynamic (dynamichost.selfip.com A record changes respectively)
* 10.1.1.3 is set to be in Demilitarized Zone of NAT (so "almost" no NAT).
* Asterisk 1.8.5.0 built from sources.

----

h3. DESCRIPTION

The registration is not working, because IPv4-only SIP server on sip.example.com is unable to parse Via header with IPv6 address, which Asterisk sends (see Asterisk DEBUG output below). Everything works fine, when I replace bindaddr=[::]:5060 with bindaddr=0.0.0.0:5060

{noformat}Asterisk Ready.
  -- Re-registration for  123456789@sip.example.com                                                                                                              
Splitting 'sip.example.com' into...
...host 'sip.example.com' and port ''.
      > doing dnsmgr_lookup for 'sip.example.com'
Splitting 'sip.example.com' into...
...host 'sip.example.com' and port ''.
Allocating new SIP dialog for 45f67c40284438057bfe2e3c485144e4@dynamichost.selfip.com - REGISTER (No RTP)
OBPROXY: Not applying OBproxy to this call
SIP Registry sip.example.com: refcount now 3
For destination '81.82.83.84', our source address is '10.1.1.3'.
Splitting 'dynamichost.selfip.com' into...
...host 'dynamichost.selfip.com' and port ''.
Multiple addresses, using the first one only
Target address 81.82.83.84:5060 is not local, substituting externaddr
Setting SIP_TRANSPORT_UDP with address [2001:db8::]:5060
SIP Registry sip.example.com: refcount now 4
Scheduled a registration timeout for sip.example.com id  #7
Splitting 'sip.example.com' into...
...host 'sip.example.com' and port ''.
Splitting 'sip.example.com' into...
...host 'sip.example.com' and port ''.
Splitting 'sip.example.com' into...
...host 'sip.example.com' and port ''.
Initializing initreq for method REGISTER - callid 45f67c40284438057bfe2e3c485144e4@dynamichost.selfip.com
Header  0 [ 33]: REGISTER sip:sip.example.com SIP/2.0
Header  1 [ 61]: Via: SIP/2.0/UDP [2001:db8::]:5060;branch=z9hG4bK51847aad
Header  2 [ 16]: Max-Forwards: 20
Header  3 [ 51]: From: <sip:123456789@sip.example.com>;tag=as40fbbb71
Header  4 [ 34]: To: <sip:123456789@sip.example.com>
Header  5 [ 58]: Call-ID: 45f67c40284438057bfe2e3c485144e4@dynamichost.selfip.com
Header  6 [ 18]: CSeq: 102 REGISTER
Header  7 [ 23]: User-Agent: MySIPclient
Header  8 [ 12]: Expires: 300
Header  9 [ 48]: Contact: <sip:123456789@[2001:db8::]:5060>
REGISTER 10 headers, 0 lines
REGISTER attempt 1 to 123456789@sip.example.com
Reliably Transmitting (no NAT) to 81.82.83.84:5060:
REGISTER sip:sip.example.com SIP/2.0
Via: SIP/2.0/UDP [2001:db8::]:5060;branch=z9hG4bK51847aad
Max-Forwards: 20
From: <sip:123456789@sip.example.com>;tag=as40fbbb71
To: <sip:123456789@sip.example.com>
Call-ID: 45f67c40284438057bfe2e3c485144e4@dynamichost.selfip.com
CSeq: 102 REGISTER
User-Agent: MySIPclient
Expires: 300
Contact: <sip:123456789@[2001:db8::]:5060>
Content-Length: 0


---
*** SIP TIMER: Initializing retransmit timer on packet: Id  #8
Trying to put 'REGISTER si' onto UDP socket destined for 81.82.83.84:5060
SIP Registry sip.example.com: refcount now 3

<--- SIP read from UDP:81.82.83.84:5060 --->
SIP/2.0 400 Malformed topmost Via header
Via: SIP/2.0/UDP [2001:db8::]:-1
To: <sip:123456789@sip.example.com>;tag=2753ba73
From: <sip:123456789@sip.example.com>;tag=as40fbbb71
Call-ID: 45f67c40284438057bfe2e3c485144e4@dynamichost.selfip.com
CSeq: 102 REGISTER
Content-Length: 0

<------------->
Header  0 [ 40]: SIP/2.0 400 Malformed topmost Via header
Header  1 [ 36]: Via: SIP/2.0/UDP [2001:db8::]:-1
Header  2 [ 47]: To: <sip:123456789@sip.example.com>;tag=2753ba73
Header  3 [ 51]: From: <sip:123456789@sip.example.com>;tag=as40fbbb71
Header  4 [ 58]: Call-ID: 45f67c40284438057bfe2e3c485144e4@dynamichost.selfip.com
Header  5 [ 18]: CSeq: 102 REGISTER
Header  6 [ 17]: Content-Length: 0
--- (7 headers 0 lines) ---
= Looking for  Call ID: 45f67c40284438057bfe2e3c485144e4@dynamichost.selfip.com (Checking To) --From tag as40fbbb71 --To-tag 2753ba73  
** SIP TIMER: Cancelling retransmit of packet (reply received) Retransid #8
Stopping retransmission on '45f67c40284438057bfe2e3c485144e4@dynamichost.selfip.com' of Request 102: Match Found
   -- Got SIP response 400 "Malformed topmost Via header" back from 81.82.83.84:5060{noformat}
Comments:By: Leif Madsen (lmadsen) 2011-08-30 14:55:24.849-0500

I guess if we're talking to an IPv4 host we should continue to talk to it via IPv4, unless the other end includes some IPv6 address info in the Via headers it responds with?

By: Jacek (jacek) 2012-03-24 16:03:48.034-0500

If you are talking using IPv4 you must continue using it (unless hostname started to resolve to IPv6 address). In my opinion the remote party should not mention any IPv6 addresses in IPv4 packets and vice versa (so there will be no IPv6 addresses in Via header on IPv4 connection).

By: Ale (antifumo) 2014-12-10 05:59:45.082-0600

Same here, using certified Asterisk 11.6-cert8 compiled from sources. Same type of setup: private IPv4 address but in DMZ (no NAT besides address change), public IPv6 address, both registered on the DNS hostname used in externhost. REGISTER requests sent to IPv4-only SIP servers are broken, as they mention the IPv6 address:

{noformat}
REGISTER sip:provider SIP/2.0
Via: SIP/2.0/UDP [2001:1620:f00::XXXXXX]:15062;branch=z9hG4bK5d764d04;rport
Max-Forwards: 70
From: <sip:XXXXXXXXXX@sip.provider.ch>;tag=as072e3c0f
To: <sip:XXXXXXXXXX@sip.provider.ch>
Call-ID: 73d46885736b5d694fdd56f24bbe2911@192.168.1.42
CSeq: 102 REGISTER
User-Agent: Asterisk PBX 11.6-cert8
Expires: 120
Contact: <sip:XXXXXX@[2001:1620:f00::XXXXXX]:15062>
Content-Length: 0
{noformat}

The server of course doesn't like the IPv6 address a all:

{noformat}
SIP/2.0 400 Malformed topmost Via header
Via: SIP/2.0/UDP [2001:1620:f00:XXXXXX]:-1
To: <sip:XXXXXXXXXX@sip.provider.ch>;tag=728d9f53
From: <sip:XXXXXXXXXX@sip.provider.ch>;tag=as072e3c0f
Call-ID: 73d46885736b5d694fdd56f24bbe2911@192.168.1.42
CSeq: 102 REGISTER
Content-Length: 0
{noformat}

The issue is serious, as it actually prevents any usage of IPv6 on servers with private IPv4 addresses placed in a DMZ.

By: Ale (antifumo) 2014-12-10 06:38:58.101-0600

Possible workaround (solves the problem for IPv4 peers, as it forces the usage of the IPv4 DNS record of externhost -- for IPv6 peers there should be no need of remapping, but I couldn't test this yet):

{code:title=channels/chan_sip.c|borderStyle=solid}
// line 3829
// if (ast_sockaddr_resolve_first(&externaddr, externhost, 0)) {
// changed to
if (ast_sockaddr_resolve_first_af(&externaddr, externhost, 0, AF_INET)) {
{code}


By: Ale (antifumo) 2014-12-10 17:59:46.672-0600

Actually, there was a second bug in the same function: IPv6 mapped IPv4 addresses were just taken as IPv6 and were thus never going through the rewriting. This was giving seemingly illogical problems, i.e., correct Via: and Contact: headers for packets sent by Asterisk to a static peer (e.g., registration to a SIP provider was ok), but wrong headers for packets send to a connected dynamic (e.g., response to SIP INVITE). Here is the workaround:

{code:title=channels/chan_sip.c|borderStyle=solid}
// line 3813
// if (ast_sockaddr_is_ipv6(&theirs)) {
// changed to
if (ast_sockaddr_is_ipv6(&theirs) && !ast_sockaddr_is_ipv4_mapped(&theirs)) {
{code}

I'll post a proper patch file with the two changes as soon as I get the authorization...

By: Ale (antifumo) 2014-12-11 07:55:28.815-0600

Here is the patch file, tested on 11.6-cert8. Changes work for me and solve the bug, but of course they require additional testing by other people in different configurations...

By: Alexander Traud (traud) 2016-09-23 10:00:28.418-0500

Alessandro, ASTERISK-18032 tackled this issue here. However, that change there used just one part of your patch. The other part – when DNS returns an IPv6 first – was not addressed, yet. Here on Ubuntu 16.04 LTS, I face exactly your issue – not an IPv4 is the first result of {{ast_sockaddr_resolve}} but an IPv6. Consequently, IPv4 peers see the IPv6 address of {{externhost}} on reply of their SIP-INVITE.

I have put that remaining part of your patch into review (with two small changes). You should be able to see the ongoing code review via the tab ‘Gerrit Reviews’.

By: Ale (antifumo) 2016-09-28 04:22:31.131-0500

Glad to see that this issue has been finally solved! Thanks Alexander for the insertion of the patches.