The getaddrinfo() implementation in sysdeps/posix/getaddrinfo.c in glibc sorts destination addresses incorrectly.
For example, I have a dual-stack v4/v6 network with site-local v4 addresses (192.168.x.x) and globally aggregatble 6to4 addresses (2002:52b6:8514::/48). One pair of hosts on this network are called pc7 and pc16. pc7's addresses are 192.168.1.254 and 2002:52b6:8514:200:20c:76ff:fe3b:a3f4. pc16's addresses are 192.168.0.7 and 2002:52b6:8514:100::3.
When I try to connect from pc7 to pc16, I get the destination addresses listed in the wrong order:
This is incorrect, since, according to pages 12-13 of RFC 3484, these should be tied on rules 1 through 5, and then the IPv6 addresses should be prioritized before the IPv4 address on Rule 6 (prefer higher precedence), since 6to4 addresses have precedence 30, while IPv4 addresses (treated as IPv4-mapped IPv6 addresses according to section 3.2 in RFC 3484) have precedence 10.
There is a small typo bug, however, in the match_prefix function in getaddrinfo.c that causes this behavior. On line 1267 (in the glibc-184.108.40.20641102 ebuild, including its patches), the condition is:
while (bits > 8)
whereas it should be:
while (bits >= 8)
Because of this, the match_prefix function never matches the entire address, and never finds the difference in scope. Instead, it goes on to rule 8 (prefer smaller scope), which prefers the IPv4 address since the scope of the v4 address in site-local, which is more narrow than the globally aggregatable 6to4 address.
I've reported this to the glibc bugzilla:
However, that was in November, and I still haven't got a reply, so I was at least hoping that Gentoo might patch this until it's fixed upstream (so that I don't have to patch manually anymore).
Created attachment 54182 [details, diff]
Patch to sort addresses correctly
This is the same patch that I sent to the glibc bugzilla.
Created attachment 54183 [details]
Simple program to test getaddrinfo()
This is a simple program to help test the getaddrinfo implementation. Call with
a hostname to get its addresses output (in hex format, though) on stdout.
Call without arguments to experience a segv. ;-)
should be sent to glibc bugzilla ...
By all means, and like I wrote in the initial description, I _have_ sent it to the glibc bugzilla.
However, since noone there seems to have noticed it in three months, it would be very nice to have the patch in portage until anyone on the glibc bugzilla sees it.
Upstream finally accepted the patch, so no more need for this bug.
yeah sorry, i cant read
i'll add this patch to our current glibc-2.3.5 patchset, thanks
now in glibc-2.3.5-r1
The more I have a look at the code snippet the more I am wondering iwhether the
patch itself is ok/enough or not. Have a look at the line immediately after the
if (bits < 8)
Before the patch was applied the case "bits is equal to 8" would result in the
fact that neither the while()-loop nor the if()-condition would met this case.
Now the if()-condition seems to be true at all- and therefore senseless.
So I am wondering if either the if()-condition was senseless already before or
do I miss something ?
P.S. I tried to get an account at sources.bugzilla... today in the morning to
make a comment directly into
http://sources.redhat.com/bugzilla/show_bug.cgi?id=524 but didn't get an
confirmation at my account request until now.
I'm not sure if I'm following you. Are you saying that the `if' condition is
always triggered? In that case, you are wrong, because it is not triggered if
`bits' was initially divisible by 8 (which seems to be the common case).
If you are saying that the `if' condition is never triggered, you are also
wrong, because it is used in the case where `bits' in not divisible by 8.
Admittedly, there are no such cases in the current prefix lists, but...
If you didn't mean either, then I am sorry, but I will have to ask that you
clarify yourself. I just couldn't seem to be able to parse "Now the
if()-condition seems to be true at all".
If there is anything that I'm dubious about, it is if the initializers of the
prefix lists really gain in the same results in all endiannesses.