Please assign global scope to RFC 1918 addresses in getaddrinfo()

Bug #555210 reported by Tore Anderson on 2010-04-04
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
GLibC
Fix Released
Medium
eglibc (Debian)
Fix Released
Unknown
eglibc (Ubuntu)
Medium
Unassigned
Lucid
Medium
Unassigned

Bug Description

Currently, glibc's getaddrinfo()-implementation will prefer transitional IPv6 connectivity (e.g. 6to4) above RFC 1918/NAT-based IPv4. Unfortunately, unnecessary use of transitional IPv6 connectivity (which quite often does not work properly) is the single largest reason for client loss (end users being unable to connect) when dual-stacking web sites. See for example my measurements that are posted at <http://thread.gmane.org/gmane.org.operators.ipv6/3248>. This behaviour is holding back the entire IPv6 rollout for web site operators, as deploying it will currently cut of access to the site for a not insignificant amount of users.

The problem is that RFC 3484 did not take into account the existence of IPv4 NAT, assuming that RFC 1918-based IPv4 addresses is unable to communicate with hosts on the global internet. As we all know, this is usually not the case - most home broadband deployments involve a CPE device that does NAT, and the end users' devices are usually numbered using RFC 1918-based addresses.

Rémi Denis-Courmount has written about the underlying problems at length here:

http://tools.ietf.org/html/draft-denis-v6ops-nat-addrsel-00

There is also a current draft that attempts to fix the issue properly:

http://tools.ietf.org/html/draft-arifumi-6man-rfc3484-revise-02

Quoting from this document:

> 2.7. To change private IPv4 address scope
>
> As detailed in Remi's draft [I-D.denis-v6ops-nat-addrsel], when a
> host is in NATed site, and has a private IPv4 address and
> transitional addresses like 6to4 and Teredo, the host chooses
> transitional IPv6 address to access most of the dual-stack servers.
>
> This is because private IPv4 address is defined to be site-local
> scope, and as in RFC 3484, the scope matching rules (Rule 2) set
> lower priority for private IPv4 address.
>
> By changing the address scope of private IPv4 address to global, this
> problem can be solved.

In fact, both FreeBSD and Microsoft has already made this change. It is quite telling that it was Microsoft who authored RFC 3484 to begin with, so I regard that a clear admission that the RFC has problems in this regard.

I have requested that the upstream glibc make the change:

http://sourceware.org/bugzilla/show_bug.cgi?id=11438

However, the feedback I got from Ulrich Drepper was basically that while he agrees with me that there is a real problem here, he is reluctant to make the change before the standardisation process has finished. However, he do go on to suggest that the distributions could work around the problem in the meanwhile.

I request that Ubuntu do exactly that. Time is of the essence; some predict that we're running out of IPv4 addresses within a year (cf. http://ipv4depletion.com) and so we need to get the IPv6 rollout going as soon as possible. To do that, though, we first need to fix the operational issues that holds it back - and this is one of them.

Thanks for considering!

Tore

Related branches

Download full text (5.1 KiB)

Back in 2003, the sorting algorithm used by getaddrinfo() was defined in RFC
3484. However, this document did not take into account (or foresee) the
ubiquity of IPv4 NAT on today's internet. This in turn causes some real
operational problems that's hindering the deployment of IPv6 for content
providers.

The problem scenario is the following:

An end user is located in a network numbered with private (RFC 1918) IPv4
addresses and transitional 6to4 (RFC 3056) IPv6 addresses. The network is
connected to the internet by a CPE/SOHO device implementing NAT for IPv4 and
anycasted 6to4 (RFC 3068) for IPv6.

When the user attempts to connect to a server whose hostname has both IPv4 and
IPv6 addresses published in DNS, an IPv6 connection using the transitional 6to4
service will be preferred. This happens because the scope comparsion fails for
IPv4, the RFC 1918 addresses are assumed to have site-local scope, which is
smaller than the global scope of the server's IPv4 address. For IPv6, both the
server's and the client's (6to4) address have global scope.

Unfortunately, the operational reality is that a transitional technique such as
6to4 is much less reliable than IPv4. The relay routers might be located far
away from the optimal IPv4 path, and thus cause a significant latency increase,
or they might not even work optimally (they're usually operated by voulenteering
third parties on a best-effort basis), and finally some ISPs simply filter away
all proto-41 traffic. Transitional techniques are useful to give end users with
IPv4-only service a real shot at accessing IPv6-only content, but it should
never be preferred over IPv4 service when accessing dual-stacked content.

RFC 3484 even acknowledges this, by saying to «avoid the use of transitional
addresses when native addresses are available».

An IETF draft document which describes the problem in a much more detailed
manner than I have is available here:

http://tools.ietf.org/html/draft-denis-v6ops-nat-addrsel-00

There's also an IETF draft that aims to revise RFC 3484 in order to fix this
problem (amongst others):

http://tools.ietf.org/html/draft-arifumi-6man-rfc3484-revise-02

Quoting from this document:

> 2.7. To change private IPv4 address scope
>
> As detailed in Remi's draft [I-D.denis-v6ops-nat-addrsel], when a
> host is in NATed site, and has a private IPv4 address and
> transitional addresses like 6to4 and Teredo, the host chooses
> transitional IPv6 address to access most of the dual-stack servers.
>
> This is because private IPv4 address is defined to be site-local
> scope, and as in RFC 3484, the scope matching rules (Rule 2) set
> lower priority for private IPv4 address.
>
> By changing the address scope of private IPv4 address to global, this
> problem can be solved.

A few other getaddrinfo() implementations have already made this change, for
instance FreeBSD (cf. http://lists.freebsd.org/pipermail/cvs-all/2004-
May/066752.html) and Microsoft. Considering that RFC 3484 was written by
Microsoft, I think this is an admission that this is a real problem with the
original specification.

The glibc maintainers has shown willin...

Read more...

Created attachment 4685
Suggested patch (untested but obvious)

I don't want to make changes which haven't been decided. Yes, there is a
problem. I've documented the necessary changes in the gai.conf file. It's easy
enough to install a file like that. Distributions can do that.

I'm suspending the bug. Change the state when any of the proposals are accepted.

Tore Anderson (toreanderson) wrote :

Just a little update here: Fedora has commited the change and it'll be part of F13. See <https://bugzilla.redhat.com/show_bug.cgi?id=577626>. I have tested their patch (attached) and it works as expected.

It would really be fantastic if this could be commited to Ubuntu as well, hopefully it's not too late for inclusion in the LTS due soon...

Best regards,
Tore

Matthias Klose (doko) on 2010-04-15
Changed in eglibc (Ubuntu):
milestone: none → ubuntu-10.04
status: New → Fix Committed
Changed in eglibc (Ubuntu Lucid):
milestone: none → ubuntu-10.04
status: New → Fix Committed
Matthias Klose (doko) wrote :

a test package is available at

  deb http://ppa.launchpad.net/ubuntu-toolchain/ppa/ubuntu lucid main

please could you check for the fix?

Tore Anderson (toreanderson) wrote :

The functionality appears to work exactly as expected, thanks!

However the comment to the gai.conf file didn't get correctly added, I think. I think the Fedora people patched a newer version of the upstream file, so the additional comment about this being the default in Fedora/Ubuntu should have been added below a recently added upstream comment about the RFC1918/3484 problems. If you understand what I mean. :-)

Anyway - the relevant parts of the gai.conf file in Fedora now looks like this:

----
# scopev4 <mask> <value>
# Add another rule to the RFC 3484 scope table for IPv4 addresses.
# By default the scope IDs described in section 3.2 in RFC 3484 are
# used. Changing these defaults should hardly ever be necessary.
# The definitions in RFC 1918 are equivalent to:
#
#scopev4 ::ffff:169.254.0.0/112 2
#scopev4 ::ffff:127.0.0.0/104 2
#scopev4 ::ffff:10.0.0.0/104 5
#scopev4 ::ffff:172.16.0.0/108 5
#scopev4 ::ffff:192.168.0.0/112 5
#scopev4 ::ffff:0.0.0.0/96 14
#
# For sites which use site-local IPv4 addresses behind NAT there is
# the problem that even if IPv4 addresses are preferred they do not
# have the same scope and are therefore not sorted first. To change
# this use only these rules:
#
#scopev4 ::ffff:169.254.0.0/112 2
#scopev4 ::ffff:127.0.0.0/104 2
#scopev4 ::ffff:0.0.0.0/96 14
#
# This is what the Red Hat setting currently uses.
----

This is more accurate, except that the comment "The definitions in RFC 1918 are equivalent to:" is a thinko, it should instead read "The definitions in RFC 3484 are equivalent to:".

Tore

Tore Anderson (toreanderson) wrote :

Also, come to think of it, it's a bit confusing that the first comment still says:

# By default the scope IDs described in section 3.2 in RFC 3484 are
# used. Changing these defaults should hardly ever be necessary.

...when changing those defaults is exactly what's being done by the patch to getaddrinfo.c. So perhaps they should simply be removed.

Tore

Hi Ulrich, and thanks for your feedback. I've brought the problem up with a
couple of major distributions (Fedora and Ubuntu), and they've both applied the
change, so it will be part of both Fedora 13 and Ubuntu 10.04 LTS.

I've also just realised that the current practise of assigning non-global scope
to rfc1918-addreses is more broken than what I first thought - if a host has
only link-local IPv6 addresses in addition to (NAT-ed) RFC1918 IPv4 addresses,
the link-local IPv6 address will be preferred for the outbound connection to a
dual-stacked server with (both IPv6 and IPv4 addresses globally scoped). I had
to read rule 2 in RFC3484 many times before actually believing this is the RFC-
mandated behaviour. But even if it is, it is obivously not the right thing to
do.

So I'm hoping that in light of this you might reconsider making the change prior
to the completion of the IETF standardisation process. I could attempt to
persuade all the distributors to carry the change locally, but given the
multitude of distributions out there I think it would be much more efficient to
simply fix it in glibc centrally.

Thanks for your time!

Best regards,
Tore Anderson

Tore Anderson (toreanderson) wrote :

Hi, as requested, here's a diff to the gai.conf file in your ppa .deb that makes the comments a bit more correct.

Steve Langasek (vorlon) on 2010-04-16
Changed in eglibc (Ubuntu Lucid):
importance: Undecided → Medium

(In reply to comment #3)
> So I'm hoping that in light of this you might reconsider making the change prior
> to the completion of the IETF standardisation process.

No, I won't. I won't change something just to change it to something else if
the official decisions come out differently.

Changed in glibc:
status: Unknown → Incomplete
Changed in eglibc (Debian):
status: Unknown → Confirmed
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package eglibc - 2.11.1-0ubuntu6

---------------
eglibc (2.11.1-0ubuntu6) lucid; urgency=low

  [ Kees Cook ]
  * [BZ #11333], Handle unnecessary padding in getdents64. LP: #392501.

  [ Matthias Klose ]
  * Apply from the 2.11-x86 branch:
    - Fix bugs in strcmp-sse4.S and strcmp-ssse3.S (H.J. Lu). LP: #563291.
    - Fix bugs in memcpy-ssse3. LP: #560135.
  * Assign global scope to RFC 1918 addresses in getaddrinfo(). Thanks
    Tore Anderson. LP: #555210.
  * Re-enable the local-ipv6-lookup patch. Addresses #417757.
 -- Matthias Klose <email address hidden> Sun, 18 Apr 2010 00:05:05 +0200

Changed in eglibc (Ubuntu Lucid):
status: Fix Committed → Fix Released
Changed in eglibc (Debian):
status: Confirmed → Fix Released
Gro-Tsen (david-madore) wrote :

How can I revert to the previous (pre-Lucid) behavior? (I have much better connectivity through IPv6 than through a painfully NATed IPv4. I assume this is fairly typical, in fact.) Is it just a matter of uncommenting the following lines in /etc/gai.conf or will this have undesired side effects?

scopev4 ::ffff:169.254.0.0/112 2
scopev4 ::ffff:127.0.0.0/104 2
scopev4 ::ffff:10.0.0.0/104 5
scopev4 ::ffff:172.16.0.0/108 5
scopev4 ::ffff:192.168.0.0/112 5
scopev4 ::ffff:0.0.0.0/96 14

Tore Anderson (toreanderson) wrote :

Gro-Tsen,

native IPv6 is still preferred over native IPv4 in Lucid, as it always has. What changed in Lucid is that non-native IPv6 (6to4 and Teredo), is now always less preferred than native IPv4 (even when behind a NAT). I can assure you that having better and more reliable connectivity through 6to4/Teredo than through IPv4 is not typical

Your suggested change is correct, uncommenting those lines in /etc/gai.conf will revert back to the pre-Lucid behaviour where non-native IPv6 will be preferred over IPv4. It should not have any other consequences, no. You can confirm how the getaddrinfo() algorithm sorts the available addresses by using e.g. "getent ahosts www.ripe.net" - the address first listed will be the preferred one.

Tore

Jeremy Visser (jeremy-visser) wrote :

I agree with Gro-Tsen. I have better IPv6 connectivity than IPv4, and while IPv6 is preferred for most connections, if they are hosted on a 6to4 (2002::/16) host, then IPv4 is used. Some applications can force IPv6 (i.e. ssh -6, or telnet -6), but others cannot (i.e. Firefox or Chromium).

Strange thing is that even though I'm *not* on a 6to4 connection, and even if the *destination* host has 6to4, then IPv4 is preferred. That logic doesn't sound right to me. If *I* had a 6to4 connection as the source IP, then maybe preferring IPv4 to 6to4 would make sense, but not for the destination.

Tore Anderson (toreanderson) wrote :

Jeremy,

RFC 3484 specifies the following priorities («IPv6» here implies non-6to4) - it does not matter which is the source and which is the destination:

1) IPv6 <-> IPv6
2) 6to4 <-> 6to4
3) IPv4 <-> IPv4
4) 6to4 <-> IPv6

These haven't changed. However, if you want #4 to be sorted above #3, you can easily accomplish that by disabling the special casing of 2002::/16 by adding the following lines to gai.conf:

label ::1/128 0
label ::/0 1
#label 2002::/16 2
label ::/96 3
label ::ffff:0:0/96 4
label fec0::/10 5
label fc00::/7 6
label 2001:0::/32 7

precedence ::1/128 50
precedence ::/0 40
#precedence 2002::/16 30
precedence ::/96 20
precedence ::ffff:0:0/96 10

If you also want Teredo-based connectivity to be preferred above IPv4, comment out the line with 2001:0::/32 as well.

Tore

Changed in glibc:
importance: Unknown → Medium

(In reply to comment #2)

> I'm suspending the bug. Change the state when any of the proposals are accepted.

Hi Ulrich,

RFC 6724 has just been published, obsoleting RFC 3484. It assigns global scope to RFC 1918 addresess.

As requested, I'm therefore changing the state of the bug.

Tore

There is a commit http://sourceware.org/git/?p=glibc.git;a=commitdiff;h=fedora/glibc-2.11.90-16-79-g1080954 in fedora branch that addresses this issue.
It is a part of fedora glibc package since glibc-2.11.90-17.
The current edition of the patch in fedora is http://pkgs.fedoraproject.org/cgit/glibc.git/tree/glibc-fedora-gai-rfc1918.patch

The irony is that this patch was made shortly after this bug was suspended by the same person who suspended it. Unfortunately, that person in his commit gave no reference to this bug report.

That's interesting. The reason why Fedora started carrying this patch in the first place, is because I submitted https://bugzilla.redhat.com/show_bug.cgi?id=577626.

Tore

Changed in glibc:
status: Incomplete → Confirmed

Patch installed.

Changed in glibc:
status: Confirmed → Fix Released

*** Bug 260998 has been marked as a duplicate of this bug. ***
Seen from the domain http://volichat.com
Page where seen: http://volichat.com/adult-chat-rooms
Marked for reference. Resolved as fixed @bugzilla.

To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.