summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2010-10-13 19:30:40 -0700
committerZac Medico <zmedico@gentoo.org>2010-10-13 19:30:40 -0700
commitc54c1af789b306a85e9d7e79fb54f02a05346616 (patch)
tree54f164ccc84d71b94797310c96179923a1795eff
parentShow hostname when getaddrinfo fails. (diff)
downloadportage-c54c1af789b306a85e9d7e79fb54f02a05346616.tar.gz
portage-c54c1af789b306a85e9d7e79fb54f02a05346616.tar.bz2
portage-c54c1af789b306a85e9d7e79fb54f02a05346616.zip
Bug #340899 - Validate getaddrinfo() results.
-rw-r--r--pym/_emerge/actions.py29
-rw-r--r--pym/_emerge/sync/getaddrinfo_validate.py29
2 files changed, 50 insertions, 8 deletions
diff --git a/pym/_emerge/actions.py b/pym/_emerge/actions.py
index 86e6a529f..186e508f7 100644
--- a/pym/_emerge/actions.py
+++ b/pym/_emerge/actions.py
@@ -59,6 +59,7 @@ from _emerge.Scheduler import Scheduler
from _emerge.search import search
from _emerge.SetArg import SetArg
from _emerge.show_invalid_depstring_notice import show_invalid_depstring_notice
+from _emerge.sync.getaddrinfo_validate import getaddrinfo_validate
from _emerge.sync.old_tree_timestamp import old_tree_timestamp_warn
from _emerge.unmerge import unmerge
from _emerge.UnmergeDepPriority import UnmergeDepPriority
@@ -2096,34 +2097,46 @@ def action_sync(settings, trees, mtimedb, myopts, myaction):
("-6" in all_rsync_opts or "--ipv6" in all_rsync_opts):
family = socket.AF_INET6
+ addrinfos = None
uris = []
try:
- addrinfos = socket.getaddrinfo(hostname, None,
- family, socket.SOCK_STREAM)
+ addrinfos = getaddrinfo_validate(
+ socket.getaddrinfo(hostname, None,
+ family, socket.SOCK_STREAM))
except socket.error as e:
- writemsg("!!! getaddrinfo failed for '%s': %s\n" % (hostname, e), noiselevel=-1)
+ writemsg_level(
+ "!!! getaddrinfo failed for '%s': %s\n" % (hostname, e),
+ noiselevel=-1, level=logging.ERROR)
+
+ if not addrinfos:
# With some configurations we need to use the plain hostname
# rather than try to resolve the ip addresses (bug #340817).
uris.append(syncuri)
else:
+
+ AF_INET = socket.AF_INET
+ AF_INET6 = None
+ if socket.has_ipv6:
+ AF_INET6 = socket.AF_INET6
+
ips_v4 = []
ips_v6 = []
for addrinfo in addrinfos:
- if socket.has_ipv6 and addrinfo[0] == socket.AF_INET6:
+ if addrinfo[0] == AF_INET:
+ ips_v4.append("%s" % addrinfo[4][0])
+ elif AF_INET6 is not None and addrinfo[0] == AF_INET6:
# IPv6 addresses need to be enclosed in square brackets
ips_v6.append("[%s]" % addrinfo[4][0])
- else:
- ips_v4.append(addrinfo[4][0])
random.shuffle(ips_v4)
random.shuffle(ips_v6)
# Give priority to the address family that
# getaddrinfo() returned first.
- if socket.has_ipv6 and addrinfos and \
- addrinfos[0][0] == socket.AF_INET6:
+ if AF_INET6 is not None and addrinfos and \
+ addrinfos[0][0] == AF_INET6:
ips = ips_v6 + ips_v4
else:
ips = ips_v4 + ips_v6
diff --git a/pym/_emerge/sync/getaddrinfo_validate.py b/pym/_emerge/sync/getaddrinfo_validate.py
new file mode 100644
index 000000000..5e6009c74
--- /dev/null
+++ b/pym/_emerge/sync/getaddrinfo_validate.py
@@ -0,0 +1,29 @@
+# Copyright 2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import sys
+
+if sys.hexversion >= 0x3000000:
+ basestring = str
+
+def getaddrinfo_validate(addrinfos):
+ """
+ Validate structures returned from getaddrinfo(),
+ since they may be corrupt, especially when python
+ has IPv6 support disabled (bug #340899).
+ """
+ valid_addrinfos = []
+ for addrinfo in addrinfos:
+ try:
+ if len(addrinfo) != 5:
+ continue
+ if len(addrinfo[4]) < 2:
+ continue
+ if not isinstance(addrinfo[4][0], basestring):
+ continue
+ except TypeError:
+ continue
+
+ valid_addrinfos.append(addrinfo)
+
+ return valid_addrinfos