Re: [PATCH] Update getaddrinfo to RFC 6724 (bug 29496)

Adhemerval Zanella Netto <[email protected]> Thu, 30 Jul 2026 15:44:35 -0300
Newsgroups gmane.comp.lib.glibc.alpha
Organization Linaro
Message-ID <[email protected]>

On 28/07/26 10:47, Andreas Schwab wrote:
> RFC 6724 is the successor of RFC 3484 and updated the default policy table
> and the address selection rules.  The policy table contains more entries
> to depreference deprecated prefixes.  The longest prefix match rule has
> been updated to only compare the prefix part of the addresses, so that
> addresses on the same subnet are no longer reordered.

I still reading about the RFC 6724 and our current implementation, and
reading the patch history I think Florian should be ok with the possible
deviations from rule 9.

I think this change should have a NEWS entry besides the bug fixing describing
what its does not implement from RFC.

> ---
>  nss/Makefile                             |   7 +-
>  nss/getaddrinfo.c                        | 107 ++++++++++++++---------
>  nss/{tst-rfc3484-2.c => tst-rfc6724-2.c} |   6 +-
>  nss/{tst-rfc3484-3.c => tst-rfc6724-3.c} |   4 +-
>  nss/{tst-rfc3484-2.c => tst-rfc6724-4.c} |  51 ++++++-----
>  nss/{tst-rfc3484.c => tst-rfc6724.c}     |   6 +-
>  posix/gai.conf                           |  48 +++++-----
>  7 files changed, 125 insertions(+), 104 deletions(-)
>  copy nss/{tst-rfc3484-2.c => tst-rfc6724-2.c} (95%)
>  rename nss/{tst-rfc3484-3.c => tst-rfc6724-3.c} (96%)
>  rename nss/{tst-rfc3484-2.c => tst-rfc6724-4.c} (74%)
>  rename nss/{tst-rfc3484.c => tst-rfc6724.c} (95%)
> 
> diff --git a/nss/Makefile b/nss/Makefile
> index b1f25f0d71..3f57694fd7 100644
> --- a/nss/Makefile
> +++ b/nss/Makefile
> @@ -306,9 +306,10 @@ tests-static            = tst-field
>  
>  tests-internal := \
>    tst-field \
> -  tst-rfc3484 \
> -  tst-rfc3484-2 \
> -  tst-rfc3484-3 \
> +  tst-rfc6724 \
> +  tst-rfc6724-2 \
> +  tst-rfc6724-3 \
> +  tst-rfc6724-4 \
>    # tests-internal
>  
>  tests := \
> diff --git a/nss/getaddrinfo.c b/nss/getaddrinfo.c
> index 4f6ac3358a..2451dccaed 100644
> --- a/nss/getaddrinfo.c
> +++ b/nss/getaddrinfo.c
> @@ -1326,7 +1326,7 @@ static const struct prefixentry *labels;
>  /* Default labels.  */
>  static const struct prefixentry default_labels[] =
>    {
> -    /* See RFC 3484 for the details.  */
> +    /* See RFC 6724 for the details.  */
>      { { .__in6_u
>  	= { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>  			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
> @@ -1343,26 +1343,22 @@ static const struct prefixentry default_labels[] =
>  	= { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>  			    0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
>        }, 96, 4 },
> -    /* The next two entries differ from RFC 3484.  We need to treat
> -       IPv6 site-local addresses special because they are never NATed,
> -       unlike site-locale IPv4 addresses.  If this would not happen, on
> -       machines which have only IPv4 and IPv6 site-local addresses, the
> -       sorting would prefer the IPv6 site-local addresses, causing
> -       unnecessary delays when trying to connect to a global IPv6 address
> -       through a site-local IPv6 address.  */
> +    { { .__in6_u
> +	= { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
> +      }, 32, 5 },
>      { { .__in6_u
>  	= { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>  			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
> -      }, 10, 5 },
> +      }, 10, 11 },
>      { { .__in6_u
> -	= { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +	= { .__u6_addr8 = { 0x3f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>  			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
> -      }, 7, 6 },
> -    /* Additional rule for Teredo tunnels.  */
> +      }, 16, 12 },
>      { { .__in6_u
> -	= { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +	= { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>  			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
> -      }, 32, 7 },
> +      }, 7, 13 },
>      { { .__in6_u
>  	= { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>  			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
> @@ -1376,23 +1372,39 @@ static const struct prefixentry *precedence;
>  /* The default precedences.  */
>  static const struct prefixentry default_precedence[] =
>    {
> -    /* See RFC 3484 for the details.  */
> +    /* See RFC 6724 for the details.  */
>      { { .__in6_u
>  	= { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>  			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 } }
>        }, 128, 50 },
> +    { { .__in6_u
> +	= { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +			    0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
> +      }, 96, 35 },
>      { { .__in6_u
>  	= { .__u6_addr8 = { 0x20, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>  			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
>        }, 16, 30 },
>      { { .__in6_u
> -	= { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -			  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
> -      }, 96, 20 },
> +	= { .__u6_addr8 = { 0x20, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
> +      }, 32, 5 },
> +    { { .__in6_u
> +	= { .__u6_addr8 = { 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
> +      }, 7, 3 },
>      { { .__in6_u
>  	= { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> -			    0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00 } }
> -      }, 96, 10 },
> +			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
> +      }, 96, 1 },
> +    { { .__in6_u
> +	= { .__u6_addr8 = { 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
> +      }, 10, 1 },
> +    { { .__in6_u
> +	= { .__u6_addr8 = { 0x3f, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
> +			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
> +      }, 16, 1 },
>      { { .__in6_u
>  	= { .__u6_addr8 = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
>  			    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } }
> @@ -1469,7 +1481,7 @@ get_precedence (const struct sockaddr_in6 *in6)
>  }
>  
>  static int
> -rfc3484_sort (const void *p1, const void *p2, void *arg)
> +rfc6724_sort (const void *p1, const void *p2, void *arg)
>  {
>    const size_t idx1 = *(const size_t *) p1;
>    const size_t idx2 = *(const size_t *) p2;
> @@ -1632,6 +1644,8 @@ rfc3484_sort (const void *p1, const void *p2, void *arg)
>        int bit1 = 0;
>        int bit2 = 0;
>  
> +      /* Compute the common prefix length between source and destination
> +	 address.  */
>        if (a1->dest_addr->ai_family == PF_INET)
>  	{
>  	  assert (a1->source_addr.sin6_family == PF_INET);
> @@ -1650,7 +1664,7 @@ rfc3484_sort (const void *p1, const void *p2, void *arg)
>  	  in_addr_t netmask1 = 0xffffffffu << (32 - a1->prefixlen);
>  
>  	  if ((in1_src_addr & netmask1) == (in1_dst_addr & netmask1))
> -	    bit1 = stdc_leading_zeros (in1_dst_addr ^ in1_src_addr);
> +	    bit1 = a1->prefixlen;
>  
>  	  struct sockaddr_in *in2_dst
>  	    = (struct sockaddr_in *) a2->dest_addr->ai_addr;
> @@ -1661,7 +1675,7 @@ rfc3484_sort (const void *p1, const void *p2, void *arg)
>  	  in_addr_t netmask2 = 0xffffffffu << (32 - a2->prefixlen);
>  
>  	  if ((in2_src_addr & netmask2) == (in2_dst_addr & netmask2))
> -	    bit2 = stdc_leading_zeros (in2_dst_addr ^ in2_src_addr);
> +	    bit2 = a2->prefixlen;
>  	}
>        else if (a1->dest_addr->ai_family == PF_INET6)
>  	{
> @@ -1680,20 +1694,33 @@ rfc3484_sort (const void *p1, const void *p2, void *arg)
>  
>  	  int i;
>  	  for (i = 0; i < 4; ++i)
> -	    if (in1_dst->sin6_addr.s6_addr32[i]
> -		!= in1_src->sin6_addr.s6_addr32[i]
> -		|| (in2_dst->sin6_addr.s6_addr32[i]
> -		    != in2_src->sin6_addr.s6_addr32[i]))
> -	      break;
> -
> -	  if (i < 4)
>  	    {
> -	      uint32_t set_bits1 = (in1_dst->sin6_addr.s6_addr32[i]
> -				    ^ in1_src->sin6_addr.s6_addr32[i]);
> -	      uint32_t set_bits2 = (in2_dst->sin6_addr.s6_addr32[i]
> -				    ^ in2_src->sin6_addr.s6_addr32[i]);
> -	      bit1 = stdc_leading_zeros (ntohl (set_bits1));
> -	      bit2 = stdc_leading_zeros (ntohl (set_bits2));
> +	      uint32_t mask1, mask2;
> +	      if (i * 32 >= a1->prefixlen)
> +		mask1 = 0xffffffffu;
> +	      else if ((i + 1) * 32 > a1->prefixlen)
> +		mask1 = 0xffffffffu >> (a1->prefixlen & 31);
> +	      else
> +		mask1 = 0;
> +	      if (i * 32 >= a2->prefixlen)
> +		mask2 = 0xffffffffu;
> +	      else if ((i + 1) * 32 > a2->prefixlen)
> +		mask2 = 0xffffffffu >> (a2->prefixlen & 31);
> +	      else
> +		mask2 = 0;
> +	      if (((in1_dst->sin6_addr.s6_addr32[i]
> +		    ^ in1_src->sin6_addr.s6_addr32[i]) & htonl (~mask1)) != 0
> +		  || ((in2_dst->sin6_addr.s6_addr32[i]
> +		       ^ in2_src->sin6_addr.s6_addr32[i]) & htonl (~mask2)) != 0)
> +		{
> +		  bit1 = stdc_leading_zeros (ntohl (in1_dst->sin6_addr.s6_addr32[i]
> +						    ^ in1_src->sin6_addr.s6_addr32[i])
> +					     | mask1);
> +		  bit2 = stdc_leading_zeros (ntohl (in2_dst->sin6_addr.s6_addr32[i]
> +						    ^ in2_src->sin6_addr.s6_addr32[i])
> +					     | mask2);
> +		  break;
> +		}
>  	    }
>  	}
>  
> @@ -1722,7 +1749,7 @@ in6aicmp (const void *p1, const void *p2)
>  }
>  
>  
> -/* Name of the config file for RFC 3484 sorting (for now).  */
> +/* Name of the config file for RFC 6724 sorting (for now).  */
>  #define GAICONF_FNAME "/etc/gai.conf"
>  
>  
> @@ -2407,7 +2434,7 @@ getaddrinfo (const char *name, const char *service,
>        __libc_once_define (static, once);
>        __typeof (once) old_once = once;
>        __libc_once (once, gaiconf_init);
> -      /* Sort results according to RFC 3484.  */
> +      /* Sort results according to RFC 6724.  */
>        struct sort_result *results;
>        size_t *order;
>        struct addrinfo *q;
> @@ -2579,11 +2606,11 @@ getaddrinfo (const char *name, const char *service,
>  	  __libc_lock_lock (lock);
>  	  if (__libc_once_get (old_once) && gaiconf_reload_flag)
>  	    gaiconf_reload ();
> -	  __qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
> +	  __qsort_r (order, nresults, sizeof (order[0]), rfc6724_sort, &src);
>  	  __libc_lock_unlock (lock);
>  	}
>        else
> -	__qsort_r (order, nresults, sizeof (order[0]), rfc3484_sort, &src);
> +	__qsort_r (order, nresults, sizeof (order[0]), rfc6724_sort, &src);
>  
>        /* Queue the results up as they come out of sorting.  */
>        q = p = results[order[0]].dest_addr;
> diff --git a/nss/tst-rfc3484-2.c b/nss/tst-rfc6724-2.c
> similarity index 95%
> copy from nss/tst-rfc3484-2.c
> copy to nss/tst-rfc6724-2.c
> index 7f89e1527c..62b06cb8f1 100644
> --- a/nss/tst-rfc3484-2.c
> +++ b/nss/tst-rfc6724-2.c
> @@ -60,7 +60,7 @@ _res_hconf_init (void)
>  #include "getaddrinfo.c"
>  
>  /* This is the beginning of the real test code.  The above defines
> -   (among other things) the function rfc3484_sort.  */
> +   (among other things) the function rfc6724_sort.  */
>  
>  
>  #if __BYTE_ORDER == __BIG_ENDIAN
> @@ -142,7 +142,7 @@ do_test (void)
>  
>  
>    struct sort_result_combo combo = { .results = results, .nresults = 2 };
> -  qsort_r (order, 2, sizeof (order[0]), rfc3484_sort, &combo);
> +  qsort_r (order, 2, sizeof (order[0]), rfc6724_sort, &combo);
>  
>    int result = 0;
>    if (results[order[0]].dest_addr->ai_family == AF_INET6)
> @@ -172,7 +172,7 @@ do_test (void)
>    order[0] = 0;
>  
>  
> -  qsort_r (order, 2, sizeof (order[0]), rfc3484_sort, &combo);
> +  qsort_r (order, 2, sizeof (order[0]), rfc6724_sort, &combo);
>  
>    if (results[order[0]].dest_addr->ai_family == AF_INET6)
>      {
> diff --git a/nss/tst-rfc3484-3.c b/nss/tst-rfc6724-3.c
> similarity index 96%
> rename from nss/tst-rfc3484-3.c
> rename to nss/tst-rfc6724-3.c
> index 23aebfd54a..fce34961fe 100644
> --- a/nss/tst-rfc3484-3.c
> +++ b/nss/tst-rfc6724-3.c
> @@ -60,7 +60,7 @@ _res_hconf_init (void)
>  #include "getaddrinfo.c"
>  
>  /* This is the beginning of the real test code.  The above defines
> -   (among other things) the function rfc3484_sort.  */
> +   (among other things) the function rfc6724_sort.  */
>  
>  
>  #if __BYTE_ORDER == __BIG_ENDIAN
> @@ -139,7 +139,7 @@ do_test (void)
>      }
>  
>    struct sort_result_combo combo = { .results = results, .nresults = naddrs };
> -  qsort_r (order, naddrs, sizeof (order[0]), rfc3484_sort, &combo);
> +  qsort_r (order, naddrs, sizeof (order[0]), rfc6724_sort, &combo);
>  
>    int result = 0;
>    for (int i = 0; i < naddrs; ++i)
> diff --git a/nss/tst-rfc3484-2.c b/nss/tst-rfc6724-4.c
> similarity index 74%
> rename from nss/tst-rfc3484-2.c
> rename to nss/tst-rfc6724-4.c
> index 7f89e1527c..6f4f9974f1 100644
> --- a/nss/tst-rfc3484-2.c
> +++ b/nss/tst-rfc6724-4.c
> @@ -59,8 +59,10 @@ _res_hconf_init (void)
>  #undef	USE_NSCD
>  #include "getaddrinfo.c"
>  
> +nss_action_list __nss_hosts_database attribute_hidden;
> +
>  /* This is the beginning of the real test code.  The above defines
> -   (among other things) the function rfc3484_sort.  */
> +   (among other things) the function rfc6724_sort.  */
>  
>  
>  #if __BYTE_ORDER == __BIG_ENDIAN
> @@ -86,33 +88,30 @@ do_test (void)
>    precedence = default_precedence;
>    scopes = default_scopes;
>  
> -  struct sockaddr_in so1;
> -  so1.sin_family = AF_INET;
> -  so1.sin_addr.s_addr = h (0xc0a85f19);
> -  /* Clear the rest of the structure to avoid warnings.  */
> -  memset (so1.sin_zero, '\0', sizeof (so1.sin_zero));
> +  struct sockaddr_in6 so1;
> +  so1.sin6_family = AF_INET6;
> +  so1.sin6_addr.s6_addr32[0] = h (0xfec01234);
> +  so1.sin6_addr.s6_addr32[1] = 1;
> +  so1.sin6_addr.s6_addr32[2] = 1;
> +  so1.sin6_addr.s6_addr32[3] = 1;
>  
> -  struct sockaddr_in sa1;
> -  sa1.sin_family = AF_INET;
> -  sa1.sin_addr.s_addr = h (0xe0a85f19);
> +  struct sockaddr_in6 sa1;
> +  sa1.sin6_family = AF_INET6;
> +  sa1.sin6_addr.s6_addr32[0] = h (0x07d10001);
> +  sa1.sin6_addr.s6_addr32[1] = 1;
> +  sa1.sin6_addr.s6_addr32[2] = 1;
> +  sa1.sin6_addr.s6_addr32[3] = 1;
>  
>    struct addrinfo ai1;
> -  ai1.ai_family = AF_INET;
> +  ai1.ai_family = AF_INET6;
>    ai1.ai_addr = (struct sockaddr *) &sa1;
>  
> -  struct sockaddr_in6 so2;
> -  so2.sin6_family = AF_INET6;
> -  so2.sin6_addr.s6_addr32[0] = h (0xfec01234);
> -  so2.sin6_addr.s6_addr32[1] = 1;
> -  so2.sin6_addr.s6_addr32[2] = 1;
> -  so2.sin6_addr.s6_addr32[3] = 1;
> -
>    struct sockaddr_in6 sa2;
>    sa2.sin6_family = AF_INET6;
>    sa2.sin6_addr.s6_addr32[0] = h (0x07d10001);
>    sa2.sin6_addr.s6_addr32[1] = 1;
>    sa2.sin6_addr.s6_addr32[2] = 1;
> -  sa2.sin6_addr.s6_addr32[3] = 1;
> +  sa2.sin6_addr.s6_addr32[3] = 2;
>  
>    struct addrinfo ai2;
>    ai2.ai_family = AF_INET6;
> @@ -133,19 +132,19 @@ do_test (void)
>  
>    results[1].dest_addr = &ai2;
>    results[1].got_source_addr = true;
> -  results[1].source_addr_len = sizeof (so2);
> +  results[1].source_addr_len = sizeof (so1);
>    results[1].source_addr_flags = 0;
>    results[1].prefixlen = 16;
>    results[1].index = 0;
> -  memcpy (&results[1].source_addr, &so2, sizeof (so2));
> +  memcpy (&results[1].source_addr, &so1, sizeof (so1));
>    order[1] = 1;
>  
>  
>    struct sort_result_combo combo = { .results = results, .nresults = 2 };
> -  qsort_r (order, 2, sizeof (order[0]), rfc3484_sort, &combo);
> +  qsort_r (order, 2, sizeof (order[0]), rfc6724_sort, &combo);
>  
>    int result = 0;
> -  if (results[order[0]].dest_addr->ai_family == AF_INET6)
> +  if (order[0] != 0)
>      {
>        puts ("wrong order in first test");
>        result |= 1;
> @@ -164,17 +163,17 @@ do_test (void)
>  
>    results[0].dest_addr = &ai2;
>    results[0].got_source_addr = true;
> -  results[0].source_addr_len = sizeof (so2);
> +  results[0].source_addr_len = sizeof (so1);
>    results[0].source_addr_flags = 0;
>    results[0].prefixlen = 16;
>    results[0].index = 0;
> -  memcpy (&results[0].source_addr, &so2, sizeof (so2));
> +  memcpy (&results[0].source_addr, &so1, sizeof (so1));
>    order[0] = 0;
>  
>  
> -  qsort_r (order, 2, sizeof (order[0]), rfc3484_sort, &combo);
> +  qsort_r (order, 2, sizeof (order[0]), rfc6724_sort, &combo);
>  
> -  if (results[order[0]].dest_addr->ai_family == AF_INET6)
> +  if (order[0] != 0)
>      {
>        puts ("wrong order in second test");
>        result |= 1;
> diff --git a/nss/tst-rfc3484.c b/nss/tst-rfc6724.c
> similarity index 95%
> rename from nss/tst-rfc3484.c
> rename to nss/tst-rfc6724.c
> index f882f95f84..57bdc099b4 100644
> --- a/nss/tst-rfc3484.c
> +++ b/nss/tst-rfc6724.c
> @@ -60,7 +60,7 @@ _res_hconf_init (void)
>  #include "getaddrinfo.c"
>  
>  /* This is the beginning of the real test code.  The above defines
> -   (among other things) the function rfc3484_sort.  */
> +   (among other things) the function rfc6724_sort.  */
>  
>  
>  #if __BYTE_ORDER == __BIG_ENDIAN
> @@ -89,7 +89,7 @@ static size_t order[naddrs];
>  
>  static int expected[naddrs] =
>    {
> -    9, 4, 3, 6, 5, 7, 8, 2, 0, 1
> +    2, 3, 4, 5, 6, 7, 8, 9, 0, 1
>    };
>  
>  
> @@ -131,7 +131,7 @@ do_test (void)
>      }
>  
>    struct sort_result_combo combo = { .results = results, .nresults = naddrs };
> -  qsort_r (order, naddrs, sizeof (order[0]), rfc3484_sort, &combo);
> +  qsort_r (order, naddrs, sizeof (order[0]), rfc6724_sort, &combo);
>  
>    int result = 0;
>    for (int i = 0; i < naddrs; ++i)
> diff --git a/posix/gai.conf b/posix/gai.conf
> index 4616ed005b..de76e2c26f 100644
> --- a/posix/gai.conf
> +++ b/posix/gai.conf
> @@ -1,7 +1,7 @@
>  # Configuration for getaddrinfo(3).
>  #
>  # So far only configuration for the destination address sorting is needed.
> -# RFC 3484 governs the sorting.  But the RFC also says that system
> +# RFC 6724 governs the sorting.  But the RFC also says that system
>  # administrators should be able to overwrite the defaults.  This can be
>  # achieved here.
>  #
> @@ -16,40 +16,34 @@
>  #    used.  There are possible runtime problems.  The default is no.
>  #
>  # label   <mask>   <value>
> -#    Add another rule to the RFC 3484 label table.  See section 2.1 in
> -#    RFC 3484.  The default is:
> +#    Add another rule to the RFC 6724 label table.  See section 2.1 in
> +#    RFC 6724.  The default is:
>  #
>  #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
> -#
> -#    This default differs from the tables given in RFC 3484 by handling
> -#    (now obsolete) site-local IPv6 addresses and Unique Local Addresses.
> -#    The reason for this difference is that these addresses are never
> -#    NATed while IPv4 site-local addresses most probably are.  Given
> -#    the precedence of IPv6 over IPv4 (see below) on machines having only
> -#    site-local IPv4 and IPv6 addresses a lookup for a global address would
> -#    see the IPv6 be preferred.  The result is a long delay because the
> -#    site-local IPv6 addresses cannot be used while the IPv4 address is
> -#    (at least for the foreseeable future) NATed.  We also treat Teredo
> -#    tunnels special.
> +#label 2001::/32     5
> +#label fec0::/10     11
> +#label 3ffe::/16     12
> +#label fc00::/7      13
>  #
>  # precedence  <mask>   <value>
> -#    Add another rule to the RFC 3484 precedence table.  See section 2.1
> -#    and 10.3 in RFC 3484.  The default is:
> -#
> -#precedence  ::1/128       50
> -#precedence  ::/0          40
> -#precedence  2002::/16     30
> -#precedence ::/96          20
> -#precedence ::ffff:0:0/96  10
> -#
> -#    For sites which prefer IPv4 connections change the last line to
> +#    Add another rule to the RFC 6724 precedence table.  See section 2.1
> +#    and 10.3 in RFC 6724.  The default is:
> +#
> +#precedence ::1/128        50
> +#precedence ::/0           40
> +#precedence ::ffff:0:0/96  35
> +#precedence 2002::/16      30
> +#precedence 2001::/32      5
> +#precedence fc00::/7       3
> +#precedence ::/96          1
> +#precedence fec0::/10      1
> +#precedence 3ffe::/16      1
> +#
> +#    For sites which prefer IPv4 connections change the coresponding line to
>  #
>  #precedence ::ffff:0:0/96  100
>