]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
resolve/varlink: replace json_dispatch_address() with json_dispatch_byte_array_iovec()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sun, 3 Aug 2025 19:44:19 +0000 (04:44 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 18 Sep 2025 00:06:48 +0000 (09:06 +0900)
src/resolve/resolved-varlink.c

index 606babf2d8003942fd009bf82d906485aba9e2dc..a4a6ee24f057138fa8db3b7eea6005e834df1860 100644 (file)
@@ -9,6 +9,7 @@
 #include "errno-util.h"
 #include "glyph-util.h"
 #include "in-addr-util.h"
+#include "iovec-util.h"
 #include "json-util.h"
 #include "resolved-dns-answer.h"
 #include "resolved-dns-browse-services.h"
@@ -37,8 +38,7 @@ typedef struct LookupParameters {
         int ifindex;
         uint64_t flags;
         int family;
-        union in_addr_union address;
-        size_t address_size;
+        struct iovec address;
         char *name;
         uint16_t class;
         uint16_t type;
@@ -62,6 +62,8 @@ typedef struct LookupParamatersBrowseServices {
 
 static void lookup_parameters_destroy(LookupParameters *p) {
         assert(p);
+
+        iovec_done(&p->address);
         free(p->name);
 }
 
@@ -409,42 +411,6 @@ static int vl_method_resolve_hostname(sd_varlink *link, sd_json_variant *paramet
         return 1;
 }
 
-static int json_dispatch_address(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
-        LookupParameters *p = ASSERT_PTR(userdata);
-        union in_addr_union buf = {};
-        sd_json_variant *i;
-        size_t n, k = 0;
-
-        assert(variant);
-
-        if (!sd_json_variant_is_array(variant))
-                return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an array.", strna(name));
-
-        n = sd_json_variant_elements(variant);
-        if (!IN_SET(n, 4, 16))
-                return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is array of unexpected size.", strna(name));
-
-        JSON_VARIANT_ARRAY_FOREACH(i, variant) {
-                int64_t b;
-
-                if (!sd_json_variant_is_integer(i))
-                        return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "Element %zu of JSON field '%s' is not an integer.", k, strna(name));
-
-                b = sd_json_variant_integer(i);
-                if (b < 0 || b > 0xff)
-                        return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL),
-                                        "Element %zu of JSON field '%s' is out of range 0%s255.",
-                                        k, strna(name), glyph(GLYPH_ELLIPSIS));
-
-                buf.bytes[k++] = (uint8_t) b;
-        }
-
-        p->address = buf;
-        p->address_size = k;
-
-        return 0;
-}
-
 static void vl_method_resolve_address_complete(DnsQuery *query) {
         _cleanup_(sd_json_variant_unrefp) sd_json_variant *array = NULL;
         _cleanup_(dns_query_freep) DnsQuery *q = query;
@@ -507,10 +473,10 @@ finish:
 
 static int vl_method_resolve_address(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
         static const sd_json_dispatch_field dispatch_table[] = {
-                { "ifindex", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_ifindex,   offsetof(LookupParameters, ifindex), SD_JSON_RELAX     },
-                { "family",  _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_int,    offsetof(LookupParameters, family),  SD_JSON_MANDATORY },
-                { "address", SD_JSON_VARIANT_ARRAY,         json_dispatch_address,   0,                                   SD_JSON_MANDATORY },
-                { "flags",   _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64, offsetof(LookupParameters, flags),   0                 },
+                { "ifindex", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_ifindex,          offsetof(LookupParameters, ifindex), SD_JSON_RELAX     },
+                { "family",  _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_int,           offsetof(LookupParameters, family),  SD_JSON_MANDATORY },
+                { "address", SD_JSON_VARIANT_ARRAY,         json_dispatch_byte_array_iovec, offsetof(LookupParameters, address), SD_JSON_MANDATORY },
+                { "flags",   _SD_JSON_VARIANT_TYPE_INVALID, sd_json_dispatch_uint64,        offsetof(LookupParameters, flags),   0                 },
                 {}
         };
 
@@ -537,13 +503,15 @@ static int vl_method_resolve_address(sd_varlink *link, sd_json_variant *paramete
         if (!IN_SET(p.family, AF_INET, AF_INET6))
                 return sd_varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("family"));
 
-        if (FAMILY_ADDRESS_SIZE(p.family) != p.address_size)
+        if (FAMILY_ADDRESS_SIZE(p.family) != p.address.iov_len)
                 return sd_varlink_error(link, "io.systemd.Resolve.BadAddressSize", NULL);
 
         if (validate_and_mangle_query_flags(m, &p.flags, /* name = */ NULL, /* ok = */ 0) < 0)
                 return sd_varlink_error_invalid_parameter(link, JSON_VARIANT_STRING_CONST("flags"));
 
-        r = dns_question_new_reverse(&question, p.family, &p.address);
+        union in_addr_union a = IN_ADDR_NULL;
+        memcpy(&a, p.address.iov_base, p.address.iov_len);
+        r = dns_question_new_reverse(&question, p.family, &a);
         if (r < 0)
                 return r;
 
@@ -555,7 +523,7 @@ static int vl_method_resolve_address(sd_varlink *link, sd_json_variant *paramete
         sd_varlink_set_userdata(link, q);
 
         q->request_family = p.family;
-        q->request_address = p.address;
+        q->request_address = a;
         q->complete = vl_method_resolve_address_complete;
 
         r = dns_query_go(q);