]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
util: introduce bus_mesage_read_dns_servers()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 19 Jul 2020 02:32:18 +0000 (11:32 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 20 Jul 2020 19:08:22 +0000 (04:08 +0900)
src/network/networkd-link-bus.c
src/resolve/resolved-link-bus.c
src/shared/bus-message-util.c
src/shared/bus-message-util.h

index 8b271f9693a6f4623f2401e6fe56181d3ef146c1..be1967150533376db94fa21873b46dec2d1f1b3f 100644 (file)
@@ -7,6 +7,7 @@
 #include "alloc-util.h"
 #include "bus-common-errors.h"
 #include "bus-get-properties.h"
+#include "bus-message-util.h"
 #include "bus-polkit.h"
 #include "dns-domain.h"
 #include "networkd-link-bus.h"
@@ -115,9 +116,9 @@ int bus_link_method_set_ntp_servers(sd_bus_message *message, void *userdata, sd_
 }
 
 static int bus_link_method_set_dns_servers_internal(sd_bus_message *message, void *userdata, sd_bus_error *error, bool extended) {
-        struct in_addr_full **dns = NULL;
-        size_t allocated = 0, n = 0;
+        struct in_addr_full **dns;
         Link *l = userdata;
+        size_t n;
         int r;
 
         assert(message);
@@ -127,82 +128,10 @@ static int bus_link_method_set_dns_servers_internal(sd_bus_message *message, voi
         if (r < 0)
                 return r;
 
-        r = sd_bus_message_enter_container(message, 'a', extended ? "(iayqs)" : "(iay)");
+        r = bus_message_read_dns_servers(message, error, extended, &dns, &n);
         if (r < 0)
                 return r;
 
-        for (;;) {
-                const char *server_name = NULL;
-                union in_addr_union a;
-                uint16_t port = 0;
-                const void *d;
-                int family;
-                size_t sz;
-
-                assert_cc(sizeof(int) == sizeof(int32_t));
-
-                r = sd_bus_message_enter_container(message, 'r', extended ? "iayqs" : "iay");
-                if (r < 0)
-                        goto finalize;
-                if (r == 0)
-                        break;
-
-                r = sd_bus_message_read(message, "i", &family);
-                if (r < 0)
-                        goto finalize;
-
-                if (!IN_SET(family, AF_INET, AF_INET6)) {
-                        r = sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
-                        goto finalize;
-                }
-
-                r = sd_bus_message_read_array(message, 'y', &d, &sz);
-                if (r < 0)
-                        goto finalize;
-                if (sz != FAMILY_ADDRESS_SIZE(family)) {
-                        r = sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid address size");
-                        goto finalize;
-                }
-
-                if (!dns_server_address_valid(family, d)) {
-                        r = sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNS server address");
-                        goto finalize;
-                }
-
-                if (extended) {
-                        r = sd_bus_message_read(message, "q", &port);
-                        if (r < 0)
-                                goto finalize;
-
-                        if (IN_SET(port, 53, 853))
-                                port = 0;
-
-                        r = sd_bus_message_read(message, "s", &server_name);
-                        if (r < 0)
-                                goto finalize;
-                }
-
-                r = sd_bus_message_exit_container(message);
-                if (r < 0)
-                        goto finalize;
-
-                if (!GREEDY_REALLOC(dns, allocated, n+1)) {
-                        r = -ENOMEM;
-                        goto finalize;
-                }
-
-                memcpy(&a, d, sz);
-                r = in_addr_full_new(family, &a, port, 0, server_name, dns + n);
-                if (r < 0)
-                        goto finalize;
-
-                n++;
-        }
-
-        r = sd_bus_message_exit_container(message);
-        if (r < 0)
-                goto finalize;
-
         r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
                                     "org.freedesktop.network1.set-dns-servers",
                                     NULL, true, UID_INVALID,
index 117f8a378a3611b15caa9f85d571dd2a33b348ec..42d4ae7aaf863ee9f3278d893e4ba943cff566e3 100644 (file)
@@ -7,6 +7,7 @@
 #include "alloc-util.h"
 #include "bus-common-errors.h"
 #include "bus-get-properties.h"
+#include "bus-message-util.h"
 #include "bus-polkit.h"
 #include "parse-util.h"
 #include "resolve-util.h"
@@ -252,9 +253,9 @@ static int verify_unmanaged_link(Link *l, sd_bus_error *error) {
 }
 
 static int bus_link_method_set_dns_servers_internal(sd_bus_message *message, void *userdata, sd_bus_error *error, bool extended) {
-        struct in_addr_full **dns = NULL;
-        size_t allocated = 0, n = 0;
+        struct in_addr_full **dns;
         Link *l = userdata;
+        size_t n;
         int r;
 
         assert(message);
@@ -264,81 +265,10 @@ static int bus_link_method_set_dns_servers_internal(sd_bus_message *message, voi
         if (r < 0)
                 return r;
 
-        r = sd_bus_message_enter_container(message, 'a', extended ? "(iayqs)" : "(iay)");
+        r = bus_message_read_dns_servers(message, error, extended, &dns, &n);
         if (r < 0)
                 return r;
 
-        for (;;) {
-                const char *server_name = NULL;
-                union in_addr_union a;
-                uint16_t port = 0;
-                const void *d;
-                int family;
-                size_t sz;
-
-                assert_cc(sizeof(int) == sizeof(int32_t));
-
-                r = sd_bus_message_enter_container(message, 'r', extended ? "iayqs" : "iay");
-                if (r < 0)
-                        goto finalize;
-                if (r == 0)
-                        break;
-
-                r = sd_bus_message_read(message, "i", &family);
-                if (r < 0)
-                        goto finalize;
-
-                if (!IN_SET(family, AF_INET, AF_INET6)) {
-                        r = sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
-                        goto finalize;
-                }
-
-                r = sd_bus_message_read_array(message, 'y', &d, &sz);
-                if (r < 0)
-                        goto finalize;
-                if (sz != FAMILY_ADDRESS_SIZE(family)) {
-                        r = sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid address size");
-                        goto finalize;
-                }
-
-                if (!dns_server_address_valid(family, d)) {
-                        r = sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNS server address");
-                        goto finalize;
-                }
-
-                if (extended) {
-                        r = sd_bus_message_read(message, "q", &port);
-                        if (r < 0)
-                                goto finalize;
-
-                        if (IN_SET(port, 53, 853))
-                                port = 0;
-
-                        r = sd_bus_message_read(message, "s", &server_name);
-                        if (r < 0)
-                                goto finalize;
-                }
-
-                r = sd_bus_message_exit_container(message);
-                if (r < 0)
-                        goto finalize;
-
-                if (!GREEDY_REALLOC(dns, allocated, n+1)) {
-                        r = -ENOMEM;
-                        goto finalize;
-                }
-
-                memcpy(&a, d, sz);
-                r = in_addr_full_new(family, &a, port, 0, server_name, dns + n);
-                if (r < 0)
-                        goto finalize;
-                n++;
-        }
-
-        r = sd_bus_message_exit_container(message);
-        if (r < 0)
-                goto finalize;
-
         r = bus_verify_polkit_async(message, CAP_NET_ADMIN,
                                     "org.freedesktop.resolve1.set-dns-servers",
                                     NULL, true, UID_INVALID,
index 2b13001c32cd52a860ef27d7e3b6398b560fd123..4151b91aec7c52e7d721640322b7f8eba598f155 100644 (file)
@@ -2,6 +2,8 @@
 
 #include "bus-message-util.h"
 
+#include "resolve-util.h"
+
 int bus_message_read_family(sd_bus_message *message, sd_bus_error *error, int *ret) {
         int family, r;
 
@@ -48,3 +50,113 @@ int bus_message_read_in_addr_auto(sd_bus_message *message, sd_bus_error *error,
                 memcpy(ret_addr, d, sz);
         return 0;
 }
+
+static int bus_message_read_dns_one(
+                        sd_bus_message *message,
+                        sd_bus_error *error,
+                        bool extended,
+                        int *ret_family,
+                        union in_addr_union *ret_address,
+                        uint16_t *ret_port,
+                        const char **ret_server_name) {
+        const char *server_name = NULL;
+        union in_addr_union a;
+        uint16_t port = 0;
+        int family, r;
+
+        assert(message);
+        assert(ret_family);
+        assert(ret_address);
+        assert(ret_port);
+        assert(ret_server_name);
+
+        r = sd_bus_message_enter_container(message, 'r', extended ? "iayqs" : "iay");
+        if (r <= 0)
+                return r;
+
+        r = bus_message_read_in_addr_auto(message, error, &family, &a);
+        if (r < 0)
+                return r;
+
+        if (!dns_server_address_valid(family, &a))
+                return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid DNS server address");
+
+        if (extended) {
+                r = sd_bus_message_read(message, "q", &port);
+                if (r < 0)
+                        return r;
+
+                if (IN_SET(port, 53, 853))
+                        port = 0;
+
+                r = sd_bus_message_read(message, "s", &server_name);
+                if (r < 0)
+                        return r;
+        }
+
+        r = sd_bus_message_exit_container(message);
+        if (r < 0)
+                return r;
+
+        *ret_family = family;
+        *ret_address = a;
+        *ret_port = port;
+        *ret_server_name = server_name;
+
+        return 1;
+}
+
+int bus_message_read_dns_servers(
+                        sd_bus_message *message,
+                        sd_bus_error *error,
+                        bool extended,
+                        struct in_addr_full ***ret_dns,
+                        size_t *ret_n_dns) {
+
+        struct in_addr_full **dns = NULL;
+        size_t n = 0, allocated = 0;
+        int r;
+
+        assert(message);
+        assert(ret_dns);
+        assert(ret_n_dns);
+
+        r = sd_bus_message_enter_container(message, 'a', extended ? "(iayqs)" : "(iay)");
+        if (r < 0)
+                return r;
+
+        for (;;) {
+                const char *server_name;
+                union in_addr_union a;
+                uint16_t port;
+                int family;
+
+                r = bus_message_read_dns_one(message, error, extended, &family, &a, &port, &server_name);
+                if (r < 0)
+                        goto clear;
+                if (r == 0)
+                        break;
+
+                if (!GREEDY_REALLOC(dns, allocated, n+1)) {
+                        r = -ENOMEM;
+                        goto clear;
+                }
+
+                r = in_addr_full_new(family, &a, port, 0, server_name, dns + n);
+                if (r < 0)
+                        goto clear;
+
+                n++;
+        }
+
+        *ret_dns = TAKE_PTR(dns);
+        *ret_n_dns = n;
+        return 0;
+
+clear:
+        for (size_t i = 0; i < n; i++)
+                in_addr_full_free(dns[i]);
+        free(dns);
+
+        return r;
+}
index 79bef325e3b7587aa1a09190088b568c155c73e1..90b78f415f510dd7a45beb4b940e3b44eccb55f7 100644 (file)
@@ -4,6 +4,14 @@
 #include "sd-bus.h"
 
 #include "in-addr-util.h"
+#include "socket-netlink.h"
 
 int bus_message_read_family(sd_bus_message *message, sd_bus_error *error, int *ret);
 int bus_message_read_in_addr_auto(sd_bus_message *message, sd_bus_error *error, int *ret_family, union in_addr_union *ret_addr);
+
+int bus_message_read_dns_servers(
+                        sd_bus_message *message,
+                        sd_bus_error *error,
+                        bool extended,
+                        struct in_addr_full ***ret_dns,
+                        size_t *ret_n_dns);