Bug 216226

Summary: yum does not fallback to IPv4 when IPv6 connect times out
Product: [Fedora] Fedora Reporter: Vladimir Kotal <vlada>
Component: pythonAssignee: Mihai Ibanescu <mihai.ibanescu>
Status: CLOSED NOTABUG QA Contact: Brock Organ <borgan>
Severity: medium Docs Contact:
Priority: medium    
Version: 6CC: katzj
Target Milestone: ---   
Target Release: ---   
Hardware: All   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2006-11-27 22:11:54 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Vladimir Kotal 2006-11-17 21:39:44 UTC
Description of problem:
When yum reads repos it does not fallback to IPv4 as every other nice portable
app would do. Instead it bails out.

Version-Release number of selected component (if applicable):
yum-3.0-6

How reproducible:
select a repo with IPv6 connectivity, add it and then make local IPv6
connectivity not working. After that try to upgrade some package from the repo.

Steps to Reproduce:
1. install some repo with IPv6 enabled servers into /etc/yum.repos.d/ on a
system with both IPv4 *and* IPv6 connectivity
2. cripple the IPv6 connectivity (e.g. via firewall)
3. try to update packages from the repo

Actual results:
yum does not even try to connect to the IPv4 address once IPv6 connect fails.

Expected results:
yum should fallback to IPv4 address (if there is any). this is the way good
network applications work.

Additional info:
Here's the output from one failed attempt:

[root@erazim tmp]# yum upgrade wireshark
Loading "installonlyn" plugin
Setting up Upgrade Process
Setting up repositories
http://ftp.belnet.be/packages/dries.ulyssis.org/fedora/linux/6/i386/dries/RPMS/repodata/repomd.xml:
[Errno 12] Timeout: <urlopen error timed out>
Trying other mirror.
Error: Cannot open/read repomd.xml file for repository: dries

Let's verify yum is wrong:

[root@erazim tmp]# host ftp.belnet.be
ftp.belnet.be is an alias for niue.belnet.be.
niue.belnet.be has address 193.190.198.20
niue.belnet.be has IPv6 address 2001:6a8:3c80:0:203:baff:fe39:f931
[root@erazim tmp]# ping -c 3 ftp.belnet.be
PING niue.belnet.be (193.190.198.20) 56(84) bytes of data.
64 bytes from niue.belnet.be (193.190.198.20): icmp_seq=1 ttl=242 time=33.7 ms
64 bytes from niue.belnet.be (193.190.198.20): icmp_seq=2 ttl=242 time=32.9 ms
64 bytes from niue.belnet.be (193.190.198.20): icmp_seq=3 ttl=242 time=33.6 ms

--- niue.belnet.be ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 32.978/33.458/33.711/0.400 ms
[root@erazim tmp]# ping6 -c 3 ftp.belnet.be
PING ftp.belnet.be(niue.belnet.be) 56 data bytes
64 bytes from niue.belnet.be: icmp_seq=0 ttl=239 time=99.2 ms
64 bytes from niue.belnet.be: icmp_seq=1 ttl=239 time=98.1 ms
64 bytes from niue.belnet.be: icmp_seq=2 ttl=239 time=98.1 ms

--- ftp.belnet.be ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2001ms
rtt min/avg/max/mdev = 98.105/98.493/99.240/0.586 ms, pipe 2
[root@erazim tmp]# 


Okay, server has IPv4 and IPv6 connectivity. Now let's try to download the file
via IPv4 and IPv6:

[root@erazim tmp]# wget -4
http://ftp.belnet.be/packages/dries.ulyssis.org/fedora/linux/6/i386/dries/RPMS/repodata/repomd.xml
--22:06:59-- 
http://ftp.belnet.be/packages/dries.ulyssis.org/fedora/linux/6/i386/dries/RPMS/repodata/repomd.xml
Resolving ftp.belnet.be... 193.190.198.20
Connecting to ftp.belnet.be|193.190.198.20|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 951 [application/xml]
Saving to: `repomd.xml'

100%[=======================================>] 951         --.-K/s   in 0s     

22:07:00 (39.0 MB/s) - `repomd.xml' saved [951/951]

[root@erazim tmp]# 
[root@erazim tmp]# wget --tries=1 -6
http://ftp.belnet.be/packages/dries.ulyssis.org/fedora/linux/6/i386/dries/RPMS/repodata/repomd.xml
--22:22:06-- 
http://ftp.belnet.be/packages/dries.ulyssis.org/fedora/linux/6/i386/dries/RPMS/repodata/repomd.xml
Resolving ftp.belnet.be... 2001:6a8:3c80:0:203:baff:fe39:f931
Connecting to ftp.belnet.be|2001:6a8:3c80:0:203:baff:fe39:f931|:80... connected.
HTTP request sent, awaiting response... Read error (Connection timed out) in
headers.
Giving up.

[root@erazim tmp]# 


I have also verified by tcpdump that yum does try to connect to IPv6 first but
after it times out no fallback to IPv4 is made.

Comment 1 Seth Vidal 2006-11-17 22:05:32 UTC
try doing the same test as with wget but using:
/usr/bin/urlgrabber

I think this is a lower level problem in python.

thanks,

Comment 2 Vladimir Kotal 2006-11-18 17:02:10 UTC
urlgrabber seems to exhibit the same behavior.

I have checked that client asks for both AAAA and A DNS records and got both 
answers. Then it tries to connect to IPv6 first and if TCP connect fails it
tries IPv4. The number of attempts was cca 18 for each address family.

The problem in my case is that IPv6 TCP connect *was* successfull but server did
not respond with data for some reason. This can be seen in the above output.
('HTTP request sent' is executed only after successful TCP connect) After yums
patience is over it will not try IPv4.

Comment 3 Seth Vidal 2006-11-18 17:53:14 UTC
I'm going to reassign this to python b/c I _think_ that's where the problem is.

Comment 4 Jeremy Katz 2006-11-27 22:11:54 UTC
The problem is that there's no way for python to "know" that you want to
fallback to IPv4 AFAIK.  If you want to use ipv4 vs ipv6 for a specific site
with both addresses, you need to set up appropriate rules in /etc/gai.conf (see
man gai.conf)

Comment 5 Vladimir Kotal 2006-11-27 22:29:21 UTC
While this is true that this is not a bug, reordering AF_INET/AF_INET6 addrinfo
entries in getaddrinfo(3) will not provide any sort of fallback in this case -
this is just a crude way how to get around this problem for a specific address.

Possible solution would be to build more network logic into the application (if
TCP connect to AAAA DNS record fails/times-out try TCP connect to A record) but
that approach has obvious drawbacks.