[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#468801: libc6: RFC3484 scoping rules should only affect IPv6, not IPv4

Package: libc6
Version: 2.7-9
Severity: normal
Tags: patch


Rule 2 of the Destination Address Selection algorithm in RFC3484

| Rule 2:  Prefer matching scope.
| If Scope(DA) = Scope(Source(DA)) and Scope(DB) <> Scope(Source(DB)),
| then prefer DA.  Similarly, if Scope(DA) <> Scope(Source(DA)) and
| Scope(DB) = Scope(Source(DB)), then prefer DB.

This rule makes lots of sense for IPv6 addresses - hosts should not try
to use link-local destinations with global source addresses or

However, glibc extends this rule to IPv4 as well: private RFC1918 IPv4
addresses are taken as a different scope from public IPv6 addresses.
This does not make much sense, especially with the widespread adoption
of Network Address Translation.

Because of this, a host with a (NATed) private IPv4 address and a 6to4
(2002::/16, global scope) or Teredo (2001:0::/32, global scope) IPv6
address will first try to use 6to4 or Teredo to reach any "native" IPv6
destination. Because 6to4 and especially Teredo are by design not very
reliable (depends on public relay), this often breaks connectivity
between 6to4/Teredo and native IPv6 nodes. IPv4 should be preferred.

Note that Windows (which could perhaps? be taken as the reference
implementation of RFC3484??) does prefer IPv4 in this case. Also note
that this make the separate 6to4 and Teredo _labels_ from inside the
Linux kernel and from /etc/gai.conf pretty useless. Finally, it violates
the RFC4380 requirement that Teredo be used as a last resort - i.e.
after IPv4.

Unfortunately, Rule 2 cannot even be configured or overriden in anyway.
The first configurable rule is number 5.

Trivial patch follows:

diff -Nru glibc-2.7.orig/sysdeps/posix/getaddrinfo.c
--- glibc-2.7.orig/sysdeps/posix/getaddrinfo.c  2008-03-01
17:18:48.000000000 +0200
+++ glibc-2.7/sysdeps/posix/getaddrinfo.c       2008-03-01
17:20:20.000000000 +0200
@@ -1039,9 +1039,6 @@
         169.254/16 and 127/8 are link-local.  */
       if ((addr[0] == 169 && addr[1] == 254) || addr[0] == 127)
        scope = 2;
-      else if (addr[0] == 10 || (addr[0] == 172 && (addr[1] & 0xf0) ==
-              || (addr[0] == 192 && addr[1] == 168))
-       scope = 5;
        scope = 14;

-- System Information:
Debian Release: lenny/sid
  APT prefers unstable
  APT policy: (100, 'unstable'), (100, 'testing')
Architecture: i386 (i686)

Kernel: Linux (SMP w/2 CPU cores)
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash

Versions of packages libc6 depends on:
ii  libgcc1                 1:4.3-20080227-1 GCC support library

libc6 recommends no packages.

-- debconf information:
  glibc/upgrade: true

Reply to: