1 |
This works around some strange behavior in glibc's getaddrinfo() |
2 |
implementation when the AI_ADDRCONFIG flag is set. |
3 |
|
4 |
For example: |
5 |
|
6 |
struct addrinfo *res, hints = { .ai_family = AF_INET, .ai_flags = AI_ADDRCONFIG }; |
7 |
getaddrinfo("localhost", NULL, &hints, &res); |
8 |
|
9 |
This returns no results if there are no non-loopback addresses configured. |
10 |
|
11 |
Bug: https://bugs.gentoo.org/690758 |
12 |
Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=12377#c13 |
13 |
Signed-off-by: Mike Gilbert <floppym@g.o> |
14 |
--- |
15 |
lib/portage/process.py | 43 +++++++++++++++++++++++++++--------------- |
16 |
1 file changed, 28 insertions(+), 15 deletions(-) |
17 |
|
18 |
diff --git a/lib/portage/process.py b/lib/portage/process.py |
19 |
index dfbda75de..4a5a35df2 100644 |
20 |
--- a/lib/portage/process.py |
21 |
+++ b/lib/portage/process.py |
22 |
@@ -9,8 +9,6 @@ import fcntl |
23 |
import multiprocessing |
24 |
import platform |
25 |
import signal |
26 |
-import socket |
27 |
-import struct |
28 |
import subprocess |
29 |
import sys |
30 |
import traceback |
31 |
@@ -446,6 +444,33 @@ def spawn(mycommand, env=None, opt_name=None, fd_pipes=None, returnpid=False, |
32 |
# Everything succeeded |
33 |
return 0 |
34 |
|
35 |
+def _configure_loopback_interface(): |
36 |
+ """ |
37 |
+ Configure the loopback interface. |
38 |
+ """ |
39 |
+ |
40 |
+ # We add some additional addresses to work around odd behavior in glibc's |
41 |
+ # getaddrinfo() implementation when the AI_ADDRCONFIG flag is set. |
42 |
+ # |
43 |
+ # For example: |
44 |
+ # |
45 |
+ # struct addrinfo *res, hints = { .ai_family = AF_INET, .ai_flags = AI_ADDRCONFIG }; |
46 |
+ # getaddrinfo("localhost", NULL, &hints, &res); |
47 |
+ # |
48 |
+ # This returns no results if there are no non-loopback addresses |
49 |
+ # configured for a given address family. |
50 |
+ # |
51 |
+ # Bug: https://bugs.gentoo.org/690758 |
52 |
+ # Bug: https://sourceware.org/bugzilla/show_bug.cgi?id=12377#c13 |
53 |
+ |
54 |
+ try: |
55 |
+ subprocess.check_call(['ip', 'link', 'set', 'lo', 'up']) |
56 |
+ subprocess.check_call(['ip', 'address', 'add', '10.0.0.1/8', 'dev', 'lo']) |
57 |
+ # Try IPv6, but don't fail if the kernel support is missing. |
58 |
+ subprocess.call(['ip', 'address', 'add', 'fd00::1/8', 'dev', 'lo']) |
59 |
+ except subprocess.CalledProcessError: |
60 |
+ writemsg("Unable to configure loopback interface\n") |
61 |
+ |
62 |
def _exec(binary, mycommand, opt_name, fd_pipes, |
63 |
env, gid, groups, uid, umask, cwd, |
64 |
pre_exec, close_fds, unshare_net, unshare_ipc, unshare_mount, unshare_pid, |
65 |
@@ -624,19 +649,7 @@ def _exec(binary, mycommand, opt_name, fd_pipes, |
66 |
noiselevel=-1) |
67 |
os._exit(1) |
68 |
if unshare_net: |
69 |
- # 'up' the loopback |
70 |
- IFF_UP = 0x1 |
71 |
- ifreq = struct.pack('16sh', b'lo', IFF_UP) |
72 |
- SIOCSIFFLAGS = 0x8914 |
73 |
- |
74 |
- sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, 0) |
75 |
- try: |
76 |
- fcntl.ioctl(sock, SIOCSIFFLAGS, ifreq) |
77 |
- except IOError as e: |
78 |
- writemsg("Unable to enable loopback interface: %s\n" % ( |
79 |
- errno.errorcode.get(e.errno, '?')), |
80 |
- noiselevel=-1) |
81 |
- sock.close() |
82 |
+ _configure_loopback_interface() |
83 |
except AttributeError: |
84 |
# unshare() not supported by libc |
85 |
pass |
86 |
-- |
87 |
2.22.0 |