diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2020-07-19 11:32:18 +0900 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2020-07-21 04:08:22 +0900 |
commit | 10d4620467bc9b967d5d6446ecf1bd127e1d81f4 (patch) | |
tree | d0809799dadeb7682e3fbfabe4cc842c044dd93b /src/shared | |
parent | 976009897b2aac52d768e035bc9c2d4862c3956a (diff) | |
download | systemd-10d4620467bc9b967d5d6446ecf1bd127e1d81f4.tar.gz |
util: introduce bus_mesage_read_dns_servers()
Diffstat (limited to 'src/shared')
-rw-r--r-- | src/shared/bus-message-util.c | 112 | ||||
-rw-r--r-- | src/shared/bus-message-util.h | 8 |
2 files changed, 120 insertions, 0 deletions
diff --git a/src/shared/bus-message-util.c b/src/shared/bus-message-util.c index 2b13001c32..4151b91aec 100644 --- a/src/shared/bus-message-util.c +++ b/src/shared/bus-message-util.c @@ -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; +} diff --git a/src/shared/bus-message-util.h b/src/shared/bus-message-util.h index 79bef325e3..90b78f415f 100644 --- a/src/shared/bus-message-util.h +++ b/src/shared/bus-message-util.h @@ -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); |