import logging
import platform
import pwd
+import random
import re
import shutil
import signal
extra_rsync_opts = portage.util.shlex_split(
settings.get("PORTAGE_RSYNC_EXTRA_OPTS",""))
all_rsync_opts.update(extra_rsync_opts)
- family = socket.AF_INET
- if "-4" in all_rsync_opts or "--ipv4" in all_rsync_opts:
- family = socket.AF_INET
- elif socket.has_ipv6 and \
- ("-6" in all_rsync_opts or "--ipv6" in all_rsync_opts):
- family = socket.AF_INET6
- ips=[]
+
+ ips_v4 = []
+ ips_v6 = []
+
+ try:
+ addrinfos = socket.getaddrinfo(hostname, None,
+ socket.AF_UNSPEC, socket.SOCK_STREAM)
+ except socket.error as e:
+ writemsg("!!! getaddrinfo failed: %s\n" % (e,), noiselevel=-1)
+ return 1
+
+ for addrinfo in addrinfos:
+ if socket.has_ipv6 and addrinfo[0] == socket.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:
+ ips = ips_v6 + ips_v4
+ else:
+ ips = ips_v4 + ips_v6
+
+ # reverse, for use with pop()
+ ips.reverse()
+
SERVER_OUT_OF_DATE = -1
EXCEEDED_MAX_RETRIES = -2
while (1):
if ips:
- del ips[0]
- if ips==[]:
- try:
- for addrinfo in socket.getaddrinfo(
- hostname, None, family, socket.SOCK_STREAM):
- if socket.has_ipv6 and addrinfo[0] == socket.AF_INET6:
- # IPv6 addresses need to be enclosed in square brackets
- ips.append("[%s]" % addrinfo[4][0])
- else:
- ips.append(addrinfo[4][0])
- from random import shuffle
- shuffle(ips)
- except SystemExit as e:
- raise # Needed else can't exit
- except Exception as e:
- print("Notice:",str(e))
- dosyncuri=syncuri
-
- if ips:
- try:
- dosyncuri = syncuri.replace(
- "//" + user_name + hostname + port + "/",
- "//" + user_name + ips[0] + port + "/", 1)
- except SystemExit as e:
- raise # Needed else can't exit
- except Exception as e:
- print("Notice:",str(e))
- dosyncuri=syncuri
+ dosyncuri = syncuri.replace(
+ "//" + user_name + hostname + port + "/",
+ "//" + user_name + ips.pop() + port + "/", 1)
+ else:
+ writemsg("!!! Exhausted addresses for %s\n" % \
+ hostname, noiselevel=-1)
+ return 1
if (retries==0):
if "--ask" in myopts: