[systemd-commits] 5 commits - Makefile.am src/libsystemd src/machine src/network src/nss-myhostname src/resolve src/shared src/test

Lennart Poettering lennart at kemper.freedesktop.org
Thu Jul 10 12:35:10 PDT 2014


 Makefile.am                              |    8 -
 src/libsystemd/sd-bus/bus-internal.h     |    7 -
 src/libsystemd/sd-daemon/sd-daemon.c     |   11 -
 src/libsystemd/sd-rtnl/local-addresses.c |  150 ++++++++++++++++++++++
 src/libsystemd/sd-rtnl/local-addresses.h |   37 +++++
 src/machine/machine-dbus.c               |  103 ++-------------
 src/network/networkd-link.c              |    8 -
 src/network/networkd.h                   |    5 
 src/nss-myhostname/addresses.c           |  149 ---------------------
 src/nss-myhostname/addresses.h           |   43 ------
 src/nss-myhostname/nss-myhostname.c      |   42 +++---
 src/resolve/resolved.h                   |    2 
 src/shared/in-addr-util.c                |  211 +++++++++++++++++++++++++++++++
 src/shared/in-addr-util.h                |   44 ++++++
 src/shared/socket-util.c                 |  187 ---------------------------
 src/shared/socket-util.h                 |   12 -
 src/test/test-socket-util.c              |    1 
 17 files changed, 497 insertions(+), 523 deletions(-)

New commits:
commit 4faefc7ff884eae65a80e82313fd9f4bb859d6db
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jul 10 21:32:44 2014 +0200

    networkd: always prefer dhcp routes over ipv4ll routes

diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c
index 6257372..3e35090 100644
--- a/src/network/networkd-link.c
+++ b/src/network/networkd-link.c
@@ -427,7 +427,7 @@ static int link_set_dhcp_routes(Link *link) {
                 route->in_addr.in = static_routes[i].gw_addr;
                 route->dst_addr.in = static_routes[i].dst_addr;
                 route->dst_prefixlen = static_routes[i].dst_prefixlen;
-                route->metrics = DHCP_STATIC_ROUTE_METRIC;
+                route->metrics = DHCP_ROUTE_METRIC;
 
                 r = route_configure(route, link, &route_handler);
                 if (r < 0) {
@@ -491,7 +491,7 @@ static int link_enter_set_routes(Link *link) {
 
                         route->family = AF_INET;
                         route->scope = RT_SCOPE_LINK;
-                        route->metrics = 99;
+                        route->metrics = IPV4LL_ROUTE_METRIC;
 
                         r = route_configure(route, link, &route_handler);
                         if (r < 0) {
@@ -539,7 +539,7 @@ static int link_enter_set_routes(Link *link) {
                         route_gw->dst_addr.in = gateway;
                         route_gw->dst_prefixlen = 32;
                         route_gw->scope = RT_SCOPE_LINK;
-                        route_gw->metrics = DHCP_STATIC_ROUTE_METRIC;
+                        route_gw->metrics = DHCP_ROUTE_METRIC;
 
                         r = route_configure(route_gw, link, &route_handler);
                         if (r < 0) {
@@ -552,7 +552,7 @@ static int link_enter_set_routes(Link *link) {
 
                         route->family = AF_INET;
                         route->in_addr.in = gateway;
-                        route->metrics = DHCP_STATIC_ROUTE_METRIC;
+                        route->metrics = DHCP_ROUTE_METRIC;
 
                         r = route_configure(route, link, &route_handler);
                         if (r < 0) {
diff --git a/src/network/networkd.h b/src/network/networkd.h
index c39d221..9132e70 100644
--- a/src/network/networkd.h
+++ b/src/network/networkd.h
@@ -42,7 +42,8 @@
 
 #define CACHE_INFO_INFINITY_LIFE_TIME 0xFFFFFFFFU
 #define VXLAN_VID_MAX (1u << 24) - 1
-#define DHCP_STATIC_ROUTE_METRIC 1024
+#define DHCP_ROUTE_METRIC 1024
+#define IPV4LL_ROUTE_METRIC 2048
 
 typedef struct NetDev NetDev;
 typedef struct Network Network;

commit 496a5a69707653b231fbb350c0d8d837762248bb
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jul 10 21:27:14 2014 +0200

    machined: when querying addresses of a container, use same code as nss-myhostname uses

diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c
index 6504dba..3741485 100644
--- a/src/machine/machine-dbus.c
+++ b/src/machine/machine-dbus.c
@@ -24,15 +24,14 @@
 #include <sys/capability.h>
 #include <arpa/inet.h>
 
-#include "sd-rtnl.h"
 #include "bus-util.h"
 #include "bus-label.h"
 #include "strv.h"
-#include "rtnl-util.h"
 #include "bus-errors.h"
 #include "copy.h"
 #include "fileio.h"
 #include "in-addr-util.h"
+#include "local-addresses.h"
 #include "machine.h"
 
 static int property_get_id(
@@ -173,9 +172,9 @@ int bus_machine_method_get_addresses(sd_bus *bus, sd_bus_message *message, void
                 return sd_bus_error_set_errno(error, -errno);
 
         if (child == 0) {
-                _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *resp = NULL;
-                _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
-                sd_rtnl_message *addr;
+                _cleanup_free_ struct local_address *addresses = NULL;
+                struct local_address *a;
+                int i, n;
 
                 pair[0] = safe_close(pair[0]);
 
@@ -183,97 +182,23 @@ int bus_machine_method_get_addresses(sd_bus *bus, sd_bus_message *message, void
                 if (r < 0)
                         _exit(EXIT_FAILURE);
 
-                r = sd_rtnl_open(&rtnl, 0);
-                if (r < 0)
-                        _exit(EXIT_FAILURE);
-
-                r = sd_rtnl_message_new_addr(rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC);
-                if (r < 0)
-                        _exit(EXIT_FAILURE);
-
-                r = sd_rtnl_call(rtnl, req, 0, &resp);
-                if (r < 0)
+                n = local_addresses(&addresses);
+                if (n < 0)
                         _exit(EXIT_FAILURE);
 
-                for (addr = resp; addr; addr = sd_rtnl_message_next(addr)) {
-                        uint16_t type;
-                        unsigned char family, scope;
-                        union in_addr_union in_addr;
-                        struct iovec iov[2];
-                        unsigned char flags;
-
-                        r = sd_rtnl_message_get_errno(addr);
-                        if (r < 0)
-                                _exit(EXIT_FAILURE);
-
-                        r = sd_rtnl_message_get_type(addr, &type);
-                        if (r < 0)
-                                _exit(EXIT_FAILURE);
-
-                        if (type != RTM_NEWADDR)
-                                continue;
-
-                        r = sd_rtnl_message_addr_get_flags(addr, &flags);
-                        if (r < 0)
-                                _exit(EXIT_FAILURE);
-
-                        if (flags & IFA_F_DEPRECATED)
-                                continue;
-
-                        r = sd_rtnl_message_addr_get_scope(addr, &scope);
-                        if (r < 0)
-                                _exit(EXIT_FAILURE);
-
-                        if (scope == RT_SCOPE_HOST || scope == RT_SCOPE_NOWHERE)
-                                continue;
-
-                        r = sd_rtnl_message_addr_get_family(addr, &family);
-                        if (r < 0)
-                                _exit(EXIT_FAILURE);
-
-                        iov[0] = (struct iovec) { .iov_base = &family, .iov_len = sizeof(family) };
-
-                        switch (family) {
-
-                        case AF_INET:
-
-                                r = sd_rtnl_message_read_in_addr(addr, IFA_LOCAL, &in_addr.in);
-                                if (r < 0) {
-                                        r = sd_rtnl_message_read_in_addr(addr, IFA_ADDRESS, &in_addr.in);
-                                        if (r < 0)
-                                                _exit(EXIT_FAILURE);
-                                }
-
-                                if (in_addr.in.s_addr == htobe32(INADDR_LOOPBACK))
-                                        continue;
-
-                                iov[1] = (struct iovec) { .iov_base = &in_addr.in, .iov_len = sizeof(in_addr.in) };
-                                break;
-
-                        case AF_INET6:
-
-                                r = sd_rtnl_message_read_in6_addr(addr, IFA_LOCAL, &in_addr.in6);
-                                if (r < 0) {
-                                        r = sd_rtnl_message_read_in6_addr(addr, IFA_ADDRESS, &in_addr.in6);
-                                        if (r < 0)
-                                                _exit(EXIT_FAILURE);
-                                }
-
-                                if (IN6_IS_ADDR_LOOPBACK(&in_addr.in6))
-                                        continue;
-
-                                iov[1] = (struct iovec) { .iov_base = &in_addr.in6, .iov_len = sizeof(in_addr.in6) };
-                                break;
-
-                        default:
-                                continue;
-                        }
+                for (a = addresses, i = 0; i < n; a++, i++) {
+                        struct iovec iov[2] = {
+                                { .iov_base = &a->family, .iov_len = sizeof(a->family) },
+                                { .iov_base = &a->address, .iov_len = PROTO_ADDRESS_SIZE(a->family) },
+                        };
 
                         r = writev(pair[1], iov, 2);
                         if (r < 0)
                                 _exit(EXIT_FAILURE);
                 }
 
+                pair[1] = safe_close(pair[1]);
+
                 _exit(EXIT_SUCCESS);
         }
 

commit 3cb4674019567ef93e4a463dd145fd3af6242877
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jul 10 21:16:40 2014 +0200

    libsystemd: make use of our common sockaddr_union everywhere

diff --git a/src/libsystemd/sd-bus/bus-internal.h b/src/libsystemd/sd-bus/bus-internal.h
index d1183d6..618e82c 100644
--- a/src/libsystemd/sd-bus/bus-internal.h
+++ b/src/libsystemd/sd-bus/bus-internal.h
@@ -237,12 +237,7 @@ struct sd_bus {
         Hashmap *vtable_methods;
         Hashmap *vtable_properties;
 
-        union {
-                struct sockaddr sa;
-                struct sockaddr_un un;
-                struct sockaddr_in in;
-                struct sockaddr_in6 in6;
-        } sockaddr;
+        union sockaddr_union sockaddr;
         socklen_t sockaddr_size;
 
         char *kernel;
diff --git a/src/libsystemd/sd-daemon/sd-daemon.c b/src/libsystemd/sd-daemon/sd-daemon.c
index 7caa63d..46241f7 100644
--- a/src/libsystemd/sd-daemon/sd-daemon.c
+++ b/src/libsystemd/sd-daemon/sd-daemon.c
@@ -37,6 +37,7 @@
 
 #include "util.h"
 #include "path-util.h"
+#include "socket-util.h"
 #include "sd-daemon.h"
 
 _public_ int sd_listen_fds(int unset_environment) {
@@ -196,14 +197,6 @@ static int sd_is_socket_internal(int fd, int type, int listening) {
         return 1;
 }
 
-union sockaddr_union {
-        struct sockaddr sa;
-        struct sockaddr_in in4;
-        struct sockaddr_in6 in6;
-        struct sockaddr_un un;
-        struct sockaddr_storage storage;
-};
-
 _public_ int sd_is_socket(int fd, int family, int type, int listening) {
         int r;
 
@@ -261,7 +254,7 @@ _public_ int sd_is_socket_inet(int fd, int family, int type, int listening, uint
                         if (l < sizeof(struct sockaddr_in))
                                 return -EINVAL;
 
-                        return htons(port) == sockaddr.in4.sin_port;
+                        return htons(port) == sockaddr.in.sin_port;
                 } else {
                         if (l < sizeof(struct sockaddr_in6))
                                 return -EINVAL;

commit 3b653205cf7bd3851befd0a9f6a3ded6e267c173
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jul 10 21:15:26 2014 +0200

    shared: split out in_addr related calls from socket-util.[ch] into its private in-addr-util.[ch]
    
    These are enough calls for a new file, and they are sufficiently
    different from the sockaddr-related calls, hence let's split this out.

diff --git a/Makefile.am b/Makefile.am
index 50e31db..2dd36c8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -765,6 +765,8 @@ libsystemd_shared_la_SOURCES = \
 	src/shared/pager.h \
 	src/shared/socket-util.c \
 	src/shared/socket-util.h \
+	src/shared/in-addr-util.c \
+	src/shared/in-addr-util.h \
 	src/shared/conf-files.c \
 	src/shared/conf-files.h \
 	src/shared/cgroup-util.c \
diff --git a/src/libsystemd/sd-rtnl/local-addresses.h b/src/libsystemd/sd-rtnl/local-addresses.h
index cc26fc4..d3dff8b 100644
--- a/src/libsystemd/sd-rtnl/local-addresses.h
+++ b/src/libsystemd/sd-rtnl/local-addresses.h
@@ -26,7 +26,7 @@
 #include <assert.h>
 #include <sys/socket.h>
 
-#include "socket-util.h"
+#include "in-addr-util.h"
 
 struct local_address {
         int ifindex;
diff --git a/src/machine/machine-dbus.c b/src/machine/machine-dbus.c
index 39db505..6504dba 100644
--- a/src/machine/machine-dbus.c
+++ b/src/machine/machine-dbus.c
@@ -32,7 +32,7 @@
 #include "bus-errors.h"
 #include "copy.h"
 #include "fileio.h"
-#include "socket-util.h"
+#include "in-addr-util.h"
 #include "machine.h"
 
 static int property_get_id(
diff --git a/src/network/networkd.h b/src/network/networkd.h
index b9c5eee..c39d221 100644
--- a/src/network/networkd.h
+++ b/src/network/networkd.h
@@ -38,7 +38,7 @@
 #include "list.h"
 #include "set.h"
 #include "condition-util.h"
-#include "socket-util.h"
+#include "in-addr-util.h"
 
 #define CACHE_INFO_INFINITY_LIFE_TIME 0xFFFFFFFFU
 #define VXLAN_VID_MAX (1u << 24) - 1
diff --git a/src/resolve/resolved.h b/src/resolve/resolved.h
index 48b361d..ad49c63 100644
--- a/src/resolve/resolved.h
+++ b/src/resolve/resolved.h
@@ -26,7 +26,7 @@
 
 #include "util.h"
 #include "list.h"
-#include "socket-util.h"
+#include "in-addr-util.h"
 
 typedef struct Address Address;
 typedef struct Manager Manager;
diff --git a/src/shared/in-addr-util.c b/src/shared/in-addr-util.c
new file mode 100644
index 0000000..98d2446
--- /dev/null
+++ b/src/shared/in-addr-util.c
@@ -0,0 +1,211 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <arpa/inet.h>
+
+#include "in-addr-util.h"
+
+int in_addr_null(unsigned family, union in_addr_union *u) {
+        assert(u);
+
+        if (family == AF_INET)
+                return u->in.s_addr == 0;
+
+        if (family == AF_INET6)
+                return
+                        u->in6.s6_addr32[0] == 0 &&
+                        u->in6.s6_addr32[1] == 0 &&
+                        u->in6.s6_addr32[2] == 0 &&
+                        u->in6.s6_addr32[3] == 0;
+
+        return -EAFNOSUPPORT;
+}
+
+
+int in_addr_equal(unsigned family, union in_addr_union *a, union in_addr_union *b) {
+        assert(a);
+        assert(b);
+
+        if (family == AF_INET)
+                return a->in.s_addr == b->in.s_addr;
+
+        if (family == AF_INET6)
+                return
+                        a->in6.s6_addr32[0] == b->in6.s6_addr32[0] &&
+                        a->in6.s6_addr32[1] == b->in6.s6_addr32[1] &&
+                        a->in6.s6_addr32[2] == b->in6.s6_addr32[2] &&
+                        a->in6.s6_addr32[3] == b->in6.s6_addr32[3];
+
+        return -EAFNOSUPPORT;
+}
+
+int in_addr_prefix_intersect(
+                unsigned family,
+                const union in_addr_union *a,
+                unsigned aprefixlen,
+                const union in_addr_union *b,
+                unsigned bprefixlen) {
+
+        unsigned m;
+
+        assert(a);
+        assert(b);
+
+        /* Checks whether there are any addresses that are in both
+         * networks */
+
+        m = MIN(aprefixlen, bprefixlen);
+
+        if (family == AF_INET) {
+                uint32_t x, nm;
+
+                x = be32toh(a->in.s_addr ^ b->in.s_addr);
+                nm = (m == 0) ? 0 : 0xFFFFFFFFUL << (32 - m);
+
+                return (x & nm) == 0;
+        }
+
+        if (family == AF_INET6) {
+                unsigned i;
+
+                if (m > 128)
+                        m = 128;
+
+                for (i = 0; i < 16; i++) {
+                        uint8_t x, nm;
+
+                        x = a->in6.s6_addr[i] ^ b->in6.s6_addr[i];
+
+                        if (m < 8)
+                                nm = 0xFF << (8 - m);
+                        else
+                                nm = 0xFF;
+
+                        if ((x & nm) != 0)
+                                return 0;
+
+                        if (m > 8)
+                                m -= 8;
+                        else
+                                m = 0;
+                }
+
+                return 1;
+        }
+
+        return -EAFNOSUPPORT;
+}
+
+int in_addr_prefix_next(unsigned family, union in_addr_union *u, unsigned prefixlen) {
+        assert(u);
+
+        /* Increases the network part of an address by one. Returns
+         * positive it that succeeds, or 0 if this overflows. */
+
+        if (prefixlen <= 0)
+                return 0;
+
+        if (family == AF_INET) {
+                uint32_t c, n;
+
+                if (prefixlen > 32)
+                        prefixlen = 32;
+
+                c = be32toh(u->in.s_addr);
+                n = c + (1UL << (32 - prefixlen));
+                if (n < c)
+                        return 0;
+                n &= 0xFFFFFFFFUL << (32 - prefixlen);
+
+                u->in.s_addr = htobe32(n);
+                return 1;
+        }
+
+        if (family == AF_INET6) {
+                struct in6_addr add = {}, result;
+                uint8_t overflow = 0;
+                unsigned i;
+
+                if (prefixlen > 128)
+                        prefixlen = 128;
+
+                /* First calculate what we have to add */
+                add.s6_addr[(prefixlen-1) / 8] = 1 << (7 - (prefixlen-1) % 8);
+
+                for (i = 16; i > 0; i--) {
+                        unsigned j = i - 1;
+
+                        result.s6_addr[j] = u->in6.s6_addr[j] + add.s6_addr[j] + overflow;
+                        overflow = (result.s6_addr[j] < u->in6.s6_addr[j]);
+                }
+
+                if (overflow)
+                        return 0;
+
+                u->in6 = result;
+                return 1;
+        }
+
+        return -EAFNOSUPPORT;
+}
+
+int in_addr_to_string(unsigned family, const union in_addr_union *u, char **ret) {
+        char *x;
+        size_t l;
+
+        assert(u);
+        assert(ret);
+
+        if (family == AF_INET)
+                l = INET_ADDRSTRLEN;
+        else if (family == AF_INET6)
+                l = INET6_ADDRSTRLEN;
+        else
+                return -EAFNOSUPPORT;
+
+        x = new(char, l);
+        if (!x)
+                return -ENOMEM;
+
+        errno = 0;
+        if (!inet_ntop(family, u, x, l)) {
+                free(x);
+                return errno ? -errno : -EINVAL;
+        }
+
+        *ret = x;
+        return 0;
+}
+
+int in_addr_from_string(unsigned family, const char *s, union in_addr_union *ret) {
+
+        assert(s);
+        assert(ret);
+
+        if (!IN_SET(family, AF_INET, AF_INET6))
+                return -EAFNOSUPPORT;
+
+        errno = 0;
+        if (inet_pton(family, s, ret) <= 0)
+                return errno ? -errno : -EINVAL;
+
+        return 0;
+}
diff --git a/src/shared/in-addr-util.h b/src/shared/in-addr-util.h
new file mode 100644
index 0000000..ae3aa90
--- /dev/null
+++ b/src/shared/in-addr-util.h
@@ -0,0 +1,44 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2014 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <netinet/in.h>
+
+#include "macro.h"
+#include "util.h"
+
+union in_addr_union {
+        struct in_addr in;
+        struct in6_addr in6;
+};
+
+int in_addr_null(unsigned family, union in_addr_union *u);
+int in_addr_equal(unsigned family, union in_addr_union *a, union in_addr_union *b);
+int in_addr_prefix_intersect(unsigned family, const union in_addr_union *a, unsigned aprefixlen, const union in_addr_union *b, unsigned bprefixlen);
+int in_addr_prefix_next(unsigned family, union in_addr_union *u, unsigned prefixlen);
+int in_addr_to_string(unsigned family, const union in_addr_union *u, char **ret);
+int in_addr_from_string(unsigned family, const char *s, union in_addr_union *ret);
+
+static inline size_t PROTO_ADDRESS_SIZE(int proto) {
+        assert(proto == AF_INET || proto == AF_INET6);
+        return proto == AF_INET6 ? 16 : 4;
+}
diff --git a/src/shared/socket-util.c b/src/shared/socket-util.c
index 6f49798..92564e3 100644
--- a/src/shared/socket-util.c
+++ b/src/shared/socket-util.c
@@ -640,193 +640,6 @@ int socket_address_unlink(SocketAddress *a) {
         return 1;
 }
 
-int in_addr_null(unsigned family, union in_addr_union *u) {
-        assert(u);
-
-        if (family == AF_INET)
-                return u->in.s_addr == 0;
-
-        if (family == AF_INET6)
-                return
-                        u->in6.s6_addr32[0] == 0 &&
-                        u->in6.s6_addr32[1] == 0 &&
-                        u->in6.s6_addr32[2] == 0 &&
-                        u->in6.s6_addr32[3] == 0;
-
-        return -EAFNOSUPPORT;
-}
-
-
-int in_addr_equal(unsigned family, union in_addr_union *a, union in_addr_union *b) {
-        assert(a);
-        assert(b);
-
-        if (family == AF_INET)
-                return a->in.s_addr == b->in.s_addr;
-
-        if (family == AF_INET6)
-                return
-                        a->in6.s6_addr32[0] == b->in6.s6_addr32[0] &&
-                        a->in6.s6_addr32[1] == b->in6.s6_addr32[1] &&
-                        a->in6.s6_addr32[2] == b->in6.s6_addr32[2] &&
-                        a->in6.s6_addr32[3] == b->in6.s6_addr32[3];
-
-        return -EAFNOSUPPORT;
-}
-
-int in_addr_prefix_intersect(
-                unsigned family,
-                const union in_addr_union *a,
-                unsigned aprefixlen,
-                const union in_addr_union *b,
-                unsigned bprefixlen) {
-
-        unsigned m;
-
-        assert(a);
-        assert(b);
-
-        /* Checks whether there are any addresses that are in both
-         * networks */
-
-        m = MIN(aprefixlen, bprefixlen);
-
-        if (family == AF_INET) {
-                uint32_t x, nm;
-
-                x = be32toh(a->in.s_addr ^ b->in.s_addr);
-                nm = (m == 0) ? 0 : 0xFFFFFFFFUL << (32 - m);
-
-                return (x & nm) == 0;
-        }
-
-        if (family == AF_INET6) {
-                unsigned i;
-
-                if (m > 128)
-                        m = 128;
-
-                for (i = 0; i < 16; i++) {
-                        uint8_t x, nm;
-
-                        x = a->in6.s6_addr[i] ^ b->in6.s6_addr[i];
-
-                        if (m < 8)
-                                nm = 0xFF << (8 - m);
-                        else
-                                nm = 0xFF;
-
-                        if ((x & nm) != 0)
-                                return 0;
-
-                        if (m > 8)
-                                m -= 8;
-                        else
-                                m = 0;
-                }
-
-                return 1;
-        }
-
-        return -EAFNOSUPPORT;
-}
-
-int in_addr_prefix_next(unsigned family, union in_addr_union *u, unsigned prefixlen) {
-        assert(u);
-
-        /* Increases the network part of an address by one. Returns
-         * positive it that succeeds, or 0 if this overflows. */
-
-        if (prefixlen <= 0)
-                return 0;
-
-        if (family == AF_INET) {
-                uint32_t c, n;
-
-                if (prefixlen > 32)
-                        prefixlen = 32;
-
-                c = be32toh(u->in.s_addr);
-                n = c + (1UL << (32 - prefixlen));
-                if (n < c)
-                        return 0;
-                n &= 0xFFFFFFFFUL << (32 - prefixlen);
-
-                u->in.s_addr = htobe32(n);
-                return 1;
-        }
-
-        if (family == AF_INET6) {
-                struct in6_addr add = {}, result;
-                uint8_t overflow = 0;
-                unsigned i;
-
-                if (prefixlen > 128)
-                        prefixlen = 128;
-
-                /* First calculate what we have to add */
-                add.s6_addr[(prefixlen-1) / 8] = 1 << (7 - (prefixlen-1) % 8);
-
-                for (i = 16; i > 0; i--) {
-                        unsigned j = i - 1;
-
-                        result.s6_addr[j] = u->in6.s6_addr[j] + add.s6_addr[j] + overflow;
-                        overflow = (result.s6_addr[j] < u->in6.s6_addr[j]);
-                }
-
-                if (overflow)
-                        return 0;
-
-                u->in6 = result;
-                return 1;
-        }
-
-        return -EAFNOSUPPORT;
-}
-
-int in_addr_to_string(unsigned family, const union in_addr_union *u, char **ret) {
-        char *x;
-        size_t l;
-
-        assert(u);
-        assert(ret);
-
-        if (family == AF_INET)
-                l = INET_ADDRSTRLEN;
-        else if (family == AF_INET6)
-                l = INET6_ADDRSTRLEN;
-        else
-                return -EAFNOSUPPORT;
-
-        x = new(char, l);
-        if (!x)
-                return -ENOMEM;
-
-        errno = 0;
-        if (!inet_ntop(family, u, x, l)) {
-                free(x);
-                return errno ? -errno : -EINVAL;
-        }
-
-        *ret = x;
-        return 0;
-}
-
-int in_addr_from_string(unsigned family, const char *s, union in_addr_union *ret) {
-
-        assert(s);
-        assert(ret);
-
-        if (!IN_SET(family, AF_INET, AF_INET6))
-                return -EAFNOSUPPORT;
-
-        errno = 0;
-        if (inet_pton(family, s, ret) <= 0)
-                return errno ? -errno : -EINVAL;
-
-        return 0;
-}
-
 static const char* const netlink_family_table[] = {
         [NETLINK_ROUTE] = "route",
         [NETLINK_FIREWALL] = "firewall",
diff --git a/src/shared/socket-util.h b/src/shared/socket-util.h
index 8d521ae..ec85d94 100644
--- a/src/shared/socket-util.h
+++ b/src/shared/socket-util.h
@@ -41,11 +41,6 @@ union sockaddr_union {
         struct sockaddr_ll ll;
 };
 
-union in_addr_union {
-        struct in_addr in;
-        struct in6_addr in6;
-};
-
 typedef struct SocketAddress {
         union sockaddr_union sockaddr;
 
@@ -111,15 +106,3 @@ SocketAddressBindIPv6Only socket_address_bind_ipv6_only_from_string(const char *
 
 int netlink_family_to_string_alloc(int b, char **s);
 int netlink_family_from_string(const char *s) _pure_;
-
-int in_addr_null(unsigned family, union in_addr_union *u);
-int in_addr_equal(unsigned family, union in_addr_union *a, union in_addr_union *b);
-int in_addr_prefix_intersect(unsigned family, const union in_addr_union *a, unsigned aprefixlen, const union in_addr_union *b, unsigned bprefixlen);
-int in_addr_prefix_next(unsigned family, union in_addr_union *u, unsigned prefixlen);
-int in_addr_to_string(unsigned family, const union in_addr_union *u, char **ret);
-int in_addr_from_string(unsigned family, const char *s, union in_addr_union *ret);
-
-static inline size_t PROTO_ADDRESS_SIZE(int proto) {
-        assert(proto == AF_INET || proto == AF_INET6);
-        return proto == AF_INET6 ? 16 : 4;
-}
diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c
index 9f42dbf..ed183e8 100644
--- a/src/test/test-socket-util.c
+++ b/src/test/test-socket-util.c
@@ -18,6 +18,7 @@
 ***/
 
 #include "socket-util.h"
+#include "in-addr-util.h"
 #include "util.h"
 #include "macro.h"
 #include "log.h"

commit e80af1bdddbc7a51191e29b0c841e8dcafe7b1cc
Author: Lennart Poettering <lennart at poettering.net>
Date:   Thu Jul 10 21:01:25 2014 +0200

    nss-myhostname: move local address listing logic into shared, so that we can make use of it from machined

diff --git a/Makefile.am b/Makefile.am
index b28fa3f..50e31db 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -2320,6 +2320,8 @@ libsystemd_internal_la_SOURCES = \
 	src/libsystemd/sd-rtnl/rtnl-types.c \
 	src/libsystemd/sd-rtnl/rtnl-util.h \
 	src/libsystemd/sd-rtnl/rtnl-util.c \
+	src/libsystemd/sd-rtnl/local-addresses.h \
+	src/libsystemd/sd-rtnl/local-addresses.c \
 	src/libsystemd/sd-id128/sd-id128.c \
 	src/libsystemd/sd-daemon/sd-daemon.c \
 	src/libsystemd/sd-login/sd-login.c \
@@ -4398,9 +4400,7 @@ endif
 if HAVE_MYHOSTNAME
 libnss_myhostname_la_SOURCES = \
 	src/nss-myhostname/nss-myhostname.sym \
-	src/nss-myhostname/nss-myhostname.c \
-	src/nss-myhostname/addresses.h \
-	src/nss-myhostname/addresses.c
+	src/nss-myhostname/nss-myhostname.c
 
 libnss_myhostname_la_LDFLAGS = \
 	$(AM_LDFLAGS) \
diff --git a/src/libsystemd/sd-rtnl/local-addresses.c b/src/libsystemd/sd-rtnl/local-addresses.c
new file mode 100644
index 0000000..dd5cced
--- /dev/null
+++ b/src/libsystemd/sd-rtnl/local-addresses.c
@@ -0,0 +1,150 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+/***
+  This file is part of systemd.
+
+  Copyright 2008-2011 Lennart Poettering
+  Copyright 2014 Tom Gundersen
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include "sd-rtnl.h"
+#include "rtnl-util.h"
+#include "macro.h"
+#include "local-addresses.h"
+
+static int address_compare(const void *_a, const void *_b) {
+        const struct local_address *a = _a, *b = _b;
+
+        /* Order lowest scope first, IPv4 before IPv6, lowest interface index first */
+
+        if (a->scope < b->scope)
+                return -1;
+        if (a->scope > b->scope)
+                return 1;
+
+        if (a->family == AF_INET && b->family == AF_INET6)
+                return -1;
+        if (a->family == AF_INET6 && b->family == AF_INET)
+                return 1;
+
+        if (a->ifindex < b->ifindex)
+                return -1;
+        if (a->ifindex > b->ifindex)
+                return 1;
+
+        return 0;
+}
+
+int local_addresses(struct local_address **ret) {
+        _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
+        _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
+        _cleanup_free_ struct local_address *list = NULL;
+        size_t n_list = 0, n_allocated = 0;
+        sd_rtnl_message *m;
+        int r;
+
+        assert(ret);
+
+        r = sd_rtnl_open(&rtnl, 0);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_message_new_addr(rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC);
+        if (r < 0)
+                return r;
+
+        r = sd_rtnl_call(rtnl, req, 0, &reply);
+        if (r < 0)
+                return r;
+
+        for (m = reply; m; m = sd_rtnl_message_next(m)) {
+                struct local_address *a;
+                unsigned char flags;
+                uint16_t type;
+
+                r = sd_rtnl_message_get_errno(m);
+                if (r < 0)
+                        return r;
+
+                r = sd_rtnl_message_get_type(m, &type);
+                if (r < 0)
+                        return r;
+
+                if (type != RTM_NEWADDR)
+                        continue;
+
+                r = sd_rtnl_message_addr_get_flags(m, &flags);
+                if (r < 0)
+                        return r;
+
+                if (flags & IFA_F_DEPRECATED)
+                        continue;
+
+                if (!GREEDY_REALLOC(list, n_allocated, n_list+1))
+                        return -ENOMEM;
+
+                a = list + n_list;
+
+                r = sd_rtnl_message_addr_get_scope(m, &a->scope);
+                if (r < 0)
+                        return r;
+
+                if (a->scope == RT_SCOPE_HOST || a->scope == RT_SCOPE_NOWHERE)
+                        continue;
+
+                r = sd_rtnl_message_addr_get_family(m, &a->family);
+                if (r < 0)
+                        return r;
+
+                switch (a->family) {
+
+                case AF_INET:
+                        r = sd_rtnl_message_read_in_addr(m, IFA_LOCAL, &a->address.in);
+                        if (r < 0) {
+                                r = sd_rtnl_message_read_in_addr(m, IFA_ADDRESS, &a->address.in);
+                                if (r < 0)
+                                        continue;
+                        }
+                        break;
+
+                case AF_INET6:
+                        r = sd_rtnl_message_read_in6_addr(m, IFA_LOCAL, &a->address.in6);
+                        if (r < 0) {
+                                r = sd_rtnl_message_read_in6_addr(m, IFA_ADDRESS, &a->address.in6);
+                                if (r < 0)
+                                        continue;
+                        }
+                        break;
+
+                default:
+                        continue;
+                }
+
+                r = sd_rtnl_message_addr_get_ifindex(m, &a->ifindex);
+                if (r < 0)
+                        return r;
+
+                n_list++;
+        };
+
+        if (n_list)
+                qsort(list, n_list, sizeof(struct local_address), address_compare);
+
+        *ret = list;
+        list = NULL;
+
+        return (int) n_list;
+}
diff --git a/src/libsystemd/sd-rtnl/local-addresses.h b/src/libsystemd/sd-rtnl/local-addresses.h
new file mode 100644
index 0000000..cc26fc4
--- /dev/null
+++ b/src/libsystemd/sd-rtnl/local-addresses.h
@@ -0,0 +1,37 @@
+/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
+
+#pragma once
+
+/***
+  This file is part of systemd.
+
+  Copyright 2008-2011 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <inttypes.h>
+#include <sys/types.h>
+#include <assert.h>
+#include <sys/socket.h>
+
+#include "socket-util.h"
+
+struct local_address {
+        int ifindex;
+        unsigned char family, scope;
+        union in_addr_union address;
+};
+
+int local_addresses(struct local_address **ret);
diff --git a/src/nss-myhostname/addresses.c b/src/nss-myhostname/addresses.c
deleted file mode 100644
index d75e850..0000000
--- a/src/nss-myhostname/addresses.c
+++ /dev/null
@@ -1,149 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-/***
-  This file is part of systemd.
-
-  Copyright 2008-2011 Lennart Poettering
-  Copyright 2014 Tom Gundersen
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include "sd-rtnl.h"
-#include "rtnl-util.h"
-#include "macro.h"
-#include "addresses.h"
-
-static int address_compare(const void *_a, const void *_b) {
-        const struct address *a = _a, *b = _b;
-
-        /* Order lowest scope first, IPv4 before IPv6, lowest interface index first */
-
-        if (a->scope < b->scope)
-                return -1;
-        if (a->scope > b->scope)
-                return 1;
-
-        if (a->family == AF_INET && b->family == AF_INET6)
-                return -1;
-        if (a->family == AF_INET6 && b->family == AF_INET)
-                return 1;
-
-        if (a->ifindex < b->ifindex)
-                return -1;
-        if (a->ifindex > b->ifindex)
-                return 1;
-
-        return 0;
-}
-
-int acquire_addresses(struct address **_list, unsigned *_n_list) {
-        _cleanup_rtnl_message_unref_ sd_rtnl_message *req = NULL, *reply = NULL;
-        _cleanup_rtnl_unref_ sd_rtnl *rtnl = NULL;
-        _cleanup_free_ struct address *list = NULL;
-        size_t n_list = 0, n_allocated = 0;
-        sd_rtnl_message *m;
-        int r;
-
-        r = sd_rtnl_open(&rtnl, 0);
-        if (r < 0)
-                return r;
-
-        r = sd_rtnl_message_new_addr(rtnl, &req, RTM_GETADDR, 0, AF_UNSPEC);
-        if (r < 0)
-                return r;
-
-        r = sd_rtnl_call(rtnl, req, 0, &reply);
-        if (r < 0)
-                return r;
-
-        for (m = reply; m; m = sd_rtnl_message_next(m)) {
-                struct address *a;
-                unsigned char flags;
-                uint16_t type;
-
-                r = sd_rtnl_message_get_errno(m);
-                if (r < 0)
-                        return r;
-
-                r = sd_rtnl_message_get_type(m, &type);
-                if (r < 0)
-                        return r;
-
-                if (type != RTM_NEWADDR)
-                        continue;
-
-                r = sd_rtnl_message_addr_get_flags(m, &flags);
-                if (r < 0)
-                        return r;
-
-                if (flags & IFA_F_DEPRECATED)
-                        continue;
-
-                if (!GREEDY_REALLOC(list, n_allocated, n_list+1))
-                        return -ENOMEM;
-
-                a = list + n_list;
-
-                r = sd_rtnl_message_addr_get_scope(m, &a->scope);
-                if (r < 0)
-                        return r;
-
-                if (a->scope == RT_SCOPE_HOST || a->scope == RT_SCOPE_NOWHERE)
-                        continue;
-
-                r = sd_rtnl_message_addr_get_family(m, &a->family);
-                if (r < 0)
-                        return r;
-
-                switch (a->family) {
-
-                case AF_INET:
-                        r = sd_rtnl_message_read_in_addr(m, IFA_LOCAL, &a->address.in);
-                        if (r < 0) {
-                                r = sd_rtnl_message_read_in_addr(m, IFA_ADDRESS, &a->address.in);
-                                if (r < 0)
-                                        continue;
-                        }
-                        break;
-
-                case AF_INET6:
-                        r = sd_rtnl_message_read_in6_addr(m, IFA_LOCAL, &a->address.in6);
-                        if (r < 0) {
-                                r = sd_rtnl_message_read_in6_addr(m, IFA_ADDRESS, &a->address.in6);
-                                if (r < 0)
-                                        continue;
-                        }
-                        break;
-
-                default:
-                        continue;
-                }
-
-                r = sd_rtnl_message_addr_get_ifindex(m, &a->ifindex);
-                if (r < 0)
-                        return r;
-
-                n_list++;
-        };
-
-        if (n_list)
-                qsort(list, n_list, sizeof(struct address), address_compare);
-
-        *_list = list;
-        list = NULL;
-        *_n_list = n_list;
-
-        return 0;
-}
diff --git a/src/nss-myhostname/addresses.h b/src/nss-myhostname/addresses.h
deleted file mode 100644
index 1bfb357..0000000
--- a/src/nss-myhostname/addresses.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
-
-#pragma once
-
-/***
-  This file is part of systemd.
-
-  Copyright 2008-2011 Lennart Poettering
-
-  systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU Lesser General Public License as published by
-  the Free Software Foundation; either version 2.1 of the License, or
-  (at your option) any later version.
-
-  systemd is distributed in the hope that it will be useful, but
-  WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  Lesser General Public License for more details.
-
-  You should have received a copy of the GNU Lesser General Public License
-  along with systemd; If not, see <http://www.gnu.org/licenses/>.
-***/
-
-#include <inttypes.h>
-#include <sys/types.h>
-#include <assert.h>
-#include <sys/socket.h>
-
-#include "socket-util.h"
-
-struct address {
-        unsigned char family, scope;
-        union in_addr_union address;
-        int ifindex;
-};
-
-static inline size_t PROTO_ADDRESS_SIZE(int proto) {
-        assert(proto == AF_INET || proto == AF_INET6);
-
-        return proto == AF_INET6 ? 16 : 4;
-}
-
-int acquire_addresses(struct address **_list, unsigned *_n_list);
diff --git a/src/nss-myhostname/nss-myhostname.c b/src/nss-myhostname/nss-myhostname.c
index 6551ac9..15a35f3 100644
--- a/src/nss-myhostname/nss-myhostname.c
+++ b/src/nss-myhostname/nss-myhostname.c
@@ -30,7 +30,7 @@
 #include <stdlib.h>
 #include <arpa/inet.h>
 
-#include "addresses.h"
+#include "local-addresses.h"
 #include "macro.h"
 
 /* Ensure that glibc's assert is used. We cannot use assert from macro.h, as
@@ -99,15 +99,15 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
                 int32_t *ttlp) {
 
         struct gaih_addrtuple *r_tuple, *r_tuple_prev = NULL;
-        _cleanup_free_ struct address *addresses = NULL;
+        _cleanup_free_ struct local_address *addresses = NULL;
         _cleanup_free_ char *hn = NULL;
         const char *canonical = NULL;
-        unsigned n_addresses = 0, n;
+        int n_addresses = 0, lo_ifi;
         uint32_t local_address_ipv4;
-        struct address *a;
+        struct local_address *a;
         size_t l, idx, ms;
         char *r_name;
-        int lo_ifi;
+        unsigned n;
 
         assert(name);
         assert(pat);
@@ -136,8 +136,9 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
                         return NSS_STATUS_NOTFOUND;
                 }
 
-                /* If this fails, n_addresses is 0. Which is fine */
-                acquire_addresses(&addresses, &n_addresses);
+                n_addresses = local_addresses(&addresses);
+                if (n_addresses < 0)
+                        n_addresses = 0;
 
                 canonical = hn;
                 local_address_ipv4 = LOCALADDRESS_IPV4;
@@ -184,7 +185,7 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
         }
 
         /* Fourth, fill actual addresses in, but in backwards order */
-        for (a = addresses + n_addresses - 1, n = 0; n < n_addresses; n++, a--) {
+        for (a = addresses + n_addresses - 1, n = 0; (int) n < n_addresses; n++, a--) {
                 r_tuple = (struct gaih_addrtuple*) (buffer + idx);
                 r_tuple->next = r_tuple_prev;
                 r_tuple->name = r_name;
@@ -214,7 +215,7 @@ enum nss_status _nss_myhostname_gethostbyname4_r(
 static enum nss_status fill_in_hostent(
                 const char *canonical, const char *additional,
                 int af,
-                struct address *addresses, unsigned n_addresses,
+                struct local_address *addresses, unsigned n_addresses,
                 uint32_t local_address_ipv4,
                 struct hostent *result,
                 char *buffer, size_t buflen,
@@ -225,7 +226,7 @@ static enum nss_status fill_in_hostent(
         size_t l_canonical, l_additional, idx, ms;
         char *r_addr, *r_name, *r_aliases, *r_alias = NULL, *r_addr_list;
         size_t alen;
-        struct address *a;
+        struct local_address *a;
         unsigned n, c;
 
         assert(canonical);
@@ -351,11 +352,11 @@ enum nss_status _nss_myhostname_gethostbyname3_r(
                 int32_t *ttlp,
                 char **canonp) {
 
-        _cleanup_free_ struct address *addresses = NULL;
+        _cleanup_free_ struct local_address *addresses = NULL;
         const char *canonical, *additional = NULL;
         _cleanup_free_ char *hn = NULL;
         uint32_t local_address_ipv4;
-        unsigned n_addresses = 0;
+        int n_addresses = 0;
 
         assert(name);
         assert(host);
@@ -389,7 +390,9 @@ enum nss_status _nss_myhostname_gethostbyname3_r(
                         return NSS_STATUS_NOTFOUND;
                 }
 
-                acquire_addresses(&addresses, &n_addresses);
+                n_addresses = local_addresses(&addresses);
+                if (n_addresses < 0)
+                        n_addresses = 0;
 
                 canonical = hn;
                 additional = n_addresses <= 0 && af == AF_INET6 ? "localhost" : NULL;
@@ -451,10 +454,11 @@ enum nss_status _nss_myhostname_gethostbyaddr2_r(
 
         const char *canonical = NULL, *additional = NULL;
         uint32_t local_address_ipv4 = LOCALADDRESS_IPV4;
-        _cleanup_free_ struct address *addresses = NULL;
+        _cleanup_free_ struct local_address *addresses = NULL;
         _cleanup_free_ char *hn = NULL;
-        unsigned n_addresses = 0, n;
-        struct address *a;
+        int n_addresses = 0;
+        struct local_address *a;
+        unsigned n;
 
         assert(addr);
         assert(host);
@@ -492,9 +496,11 @@ enum nss_status _nss_myhostname_gethostbyaddr2_r(
                 return NSS_STATUS_UNAVAIL;
         }
 
-        acquire_addresses(&addresses, &n_addresses);
+        n_addresses = local_addresses(&addresses);
+        if (n_addresses < 0)
+                n_addresses = 0;
 
-        for (a = addresses, n = 0; n < n_addresses; n++, a++) {
+        for (a = addresses, n = 0; (int) n < n_addresses; n++, a++) {
                 if (af != a->family)
                         continue;
 
diff --git a/src/shared/socket-util.h b/src/shared/socket-util.h
index 25c4a7e..8d521ae 100644
--- a/src/shared/socket-util.h
+++ b/src/shared/socket-util.h
@@ -118,3 +118,8 @@ int in_addr_prefix_intersect(unsigned family, const union in_addr_union *a, unsi
 int in_addr_prefix_next(unsigned family, union in_addr_union *u, unsigned prefixlen);
 int in_addr_to_string(unsigned family, const union in_addr_union *u, char **ret);
 int in_addr_from_string(unsigned family, const char *s, union in_addr_union *ret);
+
+static inline size_t PROTO_ADDRESS_SIZE(int proto) {
+        assert(proto == AF_INET || proto == AF_INET6);
+        return proto == AF_INET6 ? 16 : 4;
+}



More information about the systemd-commits mailing list