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