]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dhcp-network: make dhcp_network_send_{raw,udp}_socket() take iovec_wrapper
authorYu Watanabe <watanabe.yu+github@gmail.com>
Fri, 20 Mar 2026 20:16:04 +0000 (05:16 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 12 May 2026 17:59:00 +0000 (02:59 +0900)
src/libsystemd-network/dhcp-client-send.c
src/libsystemd-network/dhcp-network.c
src/libsystemd-network/dhcp-network.h
src/libsystemd-network/fuzz-dhcp-client.c
src/libsystemd-network/sd-dhcp-server.c
src/libsystemd-network/test-dhcp-client.c

index 56306fbf53647c0144d3c0d74c826a1653bfbd6e..d1f20fef46e691466706c0f941adea0b1d79afd9 100644 (file)
@@ -8,6 +8,8 @@
 #include "dhcp-network.h"
 #include "dhcp-packet.h"
 #include "fd-util.h"
+#include "iovec-util.h"
+#include "iovec-wrapper.h"
 #include "socket-util.h"
 
 static int client_get_socket(sd_dhcp_client *client, int domain) {
@@ -112,8 +114,10 @@ int dhcp_client_send_raw(
         r = dhcp_network_send_raw_socket(
                         fd,
                         &client->link,
-                        packet,
-                        sizeof(DHCPPacket) + optoffset);
+                        &(struct iovec_wrapper) {
+                                .iovec = &IOVEC_MAKE(packet, sizeof(DHCPPacket) + optoffset),
+                                .count = 1,
+                        });
         if (r < 0)
                 return r;
 
@@ -166,8 +170,10 @@ int dhcp_client_send_udp(
                         fd,
                         client->lease->server_address,
                         client->server_port,
-                        &packet->dhcp,
-                        sizeof(DHCPMessage) + optoffset);
+                        &(struct iovec_wrapper) {
+                                .iovec = &IOVEC_MAKE(&packet->dhcp, sizeof(DHCPMessage) + optoffset),
+                                .count = 1,
+                        });
         if (r < 0)
                 return r;
 
index 24b8c12011f7325a0b47e098930af515c90580b8..c78f49159f7e408b88458d2c00787b2fe3d24738 100644 (file)
@@ -7,13 +7,13 @@
 #include <linux/if_infiniband.h>
 #include <linux/if_packet.h>
 #include <net/if_arp.h>
-#include <stdio.h>
 #include <string.h>
 
 #include "dhcp-network.h"
 #include "dhcp-protocol.h"
 #include "ether-addr-util.h"
 #include "fd-util.h"
+#include "iovec-wrapper.h"
 #include "socket-util.h"
 #include "unaligned.h"
 
@@ -244,30 +244,37 @@ int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port, int
 }
 
 int dhcp_network_send_raw_socket(
-                int s,
+                int fd,
                 const union sockaddr_union *link,
-                const void *packet,
-                size_t len) {
+                const struct iovec_wrapper *iovw) {
 
-        /* Do not add assert(s >= 0) here, as this is called in fuzz-dhcp-server, and in that case this
-         * function should fail with negative errno. */
+        /* Do not add assert(fd >= 0) here, as this is also called from fuzz-dhcp-server, and in that case
+         * fd is negative and this function should fail with negative errno. */
 
         assert(link);
-        assert(packet);
-        assert(len > 0);
+        assert(!iovw_isempty(iovw));
 
-        if (sendto(s, packet, len, 0, &link->sa, sockaddr_ll_len(&link->ll)) < 0)
+        struct msghdr mh = {
+                .msg_name = (struct sockaddr*) &link->sa,
+                .msg_namelen = sockaddr_ll_len(&link->ll),
+                .msg_iov = iovw->iovec,
+                .msg_iovlen = iovw->count,
+        };
+
+        if (sendmsg(fd, &mh, MSG_NOSIGNAL) < 0)
                 return -errno;
 
         return 0;
 }
 
 int dhcp_network_send_udp_socket(
-                int s,
+                int fd,
                 be32_t address,
                 uint16_t port,
-                const void *packet,
-                size_t len) {
+                const struct iovec_wrapper *iovw) {
+
+        assert(fd >= 0);
+        assert(!iovw_isempty(iovw));
 
         union sockaddr_union dest = {
                 .in.sin_family = AF_INET,
@@ -275,11 +282,14 @@ int dhcp_network_send_udp_socket(
                 .in.sin_addr.s_addr = address,
         };
 
-        assert(s >= 0);
-        assert(packet);
-        assert(len > 0);
+        struct msghdr mh = {
+                .msg_name = &dest.sa,
+                .msg_namelen = sizeof(dest.in),
+                .msg_iov = iovw->iovec,
+                .msg_iovlen = iovw->count,
+        };
 
-        if (sendto(s, packet, len, 0, &dest.sa, sizeof(dest.in)) < 0)
+        if (sendmsg(fd, &mh, MSG_NOSIGNAL) < 0)
                 return -errno;
 
         return 0;
index 3cc66dad9da91f1709c5c759016957f613faed26..6bef8ddaf9cbf778140678ce6f643c5387a99536 100644 (file)
@@ -20,13 +20,11 @@ int dhcp_network_bind_udp_socket(
                 uint16_t port,
                 int ip_service_type);
 int dhcp_network_send_raw_socket(
-                int s,
+                int fd,
                 const union sockaddr_union *link,
-                const void *packet,
-                size_t len);
+                const struct iovec_wrapper *iovw);
 int dhcp_network_send_udp_socket(
-                int s,
+                int fd,
                 be32_t address,
                 uint16_t port,
-                const void *packet,
-                size_t len);
+                const struct iovec_wrapper *iovw);
index 21f693c4873a3454656f442f82863b484cb46325..d6a2577194d51afd176746c8ac48a4fe0c1d0140 100644 (file)
@@ -24,7 +24,7 @@ int dhcp_network_bind_raw_socket(
         return ASSERT_OK_ERRNO(socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0));
 }
 
-int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link, const void *packet, size_t len) {
+int dhcp_network_send_raw_socket(int fd, const union sockaddr_union *link, const struct iovec_wrapper *iovw) {
         return 0;
 }
 
@@ -32,7 +32,7 @@ int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port, int
         return ASSERT_OK_ERRNO(socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0));
 }
 
-int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port, const void *packet, size_t len) {
+int dhcp_network_send_udp_socket(int fd, be32_t address, uint16_t port, const struct iovec_wrapper *iovw) {
         return 0;
 }
 
index 48c481809f4e54e997a48b963b2d02dda9df54d1..702a2d67553e07048e8ede528caf240e7764a41d 100644 (file)
@@ -349,7 +349,13 @@ static int dhcp_server_send_unicast_raw(
         if (r < 0)
                 return r;
 
-        return dhcp_network_send_raw_socket(server->fd_raw, &link, packet, len);
+        return dhcp_network_send_raw_socket(
+                        server->fd_raw,
+                        &link,
+                        &(struct iovec_wrapper) {
+                                .iovec = &IOVEC_MAKE(packet, len),
+                                .count = 1,
+                        });
 }
 
 static int dhcp_server_send_udp(sd_dhcp_server *server, be32_t destination,
index b2cadc07e5b1e63f67d3db838a82f362b866bd63..957e43d76274d8a41f744d97ec6b4fd9b345da76 100644 (file)
 #include "sd-dhcp-lease.h"
 #include "sd-event.h"
 
-#include "alloc-util.h"
 #include "dhcp-duid-internal.h"
 #include "dhcp-network.h"
 #include "dhcp-option.h"
 #include "ether-addr-util.h"
 #include "fd-util.h"
+#include "iovec-util.h"
+#include "iovec-wrapper.h"
 #include "ip-util.h"
 #include "log.h"
 #include "tests.h"
@@ -149,15 +150,19 @@ static int check_options(uint8_t code, uint8_t len, const void *option, void *us
         return 0;
 }
 
-int dhcp_network_send_raw_socket(int s, const union sockaddr_union *link, const void *packet, size_t len) {
+int dhcp_network_send_raw_socket(int fd, const union sockaddr_union *link, const struct iovec_wrapper *iovw) {
         uint16_t ip_check, udp_check;
 
-        ASSERT_OK(s);
-        ASSERT_NOT_NULL(packet);
+        ASSERT_OK(fd);
+        ASSERT_NOT_NULL(iovw);
 
+        _cleanup_(iovec_done) struct iovec iov = {};
+        ASSERT_OK(iovw_concat(iovw, &iov));
+
+        size_t len = iov.iov_len;
         ASSERT_GT(len, sizeof(DHCPPacket));
 
-        _cleanup_free_ DHCPPacket *discover = ASSERT_NOT_NULL(memdup(packet, len));
+        DHCPPacket *discover = ASSERT_NOT_NULL(iov.iov_base);
 
         ASSERT_EQ(discover->ip.ttl, IPDEFTTL);
         ASSERT_EQ(discover->ip.protocol, IPPROTO_UDP);
@@ -208,7 +213,7 @@ int dhcp_network_bind_udp_socket(int ifindex, be32_t address, uint16_t port, int
         return ASSERT_OK_ERRNO(socket(AF_INET, SOCK_DGRAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0));
 }
 
-int dhcp_network_send_udp_socket(int s, be32_t address, uint16_t port, const void *packet, size_t len) {
+int dhcp_network_send_udp_socket(int fd, be32_t address, uint16_t port, const struct iovec_wrapper *iovw) {
         return 0;
 }