From: Yu Watanabe Date: Fri, 20 Mar 2026 20:16:04 +0000 (+0900) Subject: dhcp-network: make dhcp_network_send_{raw,udp}_socket() take iovec_wrapper X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bcc775543894b88f88f443019599acaba637ecd0;p=thirdparty%2Fsystemd.git dhcp-network: make dhcp_network_send_{raw,udp}_socket() take iovec_wrapper --- diff --git a/src/libsystemd-network/dhcp-client-send.c b/src/libsystemd-network/dhcp-client-send.c index 56306fbf536..d1f20fef46e 100644 --- a/src/libsystemd-network/dhcp-client-send.c +++ b/src/libsystemd-network/dhcp-client-send.c @@ -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; diff --git a/src/libsystemd-network/dhcp-network.c b/src/libsystemd-network/dhcp-network.c index 24b8c12011f..c78f49159f7 100644 --- a/src/libsystemd-network/dhcp-network.c +++ b/src/libsystemd-network/dhcp-network.c @@ -7,13 +7,13 @@ #include #include #include -#include #include #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; diff --git a/src/libsystemd-network/dhcp-network.h b/src/libsystemd-network/dhcp-network.h index 3cc66dad9da..6bef8ddaf9c 100644 --- a/src/libsystemd-network/dhcp-network.h +++ b/src/libsystemd-network/dhcp-network.h @@ -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); diff --git a/src/libsystemd-network/fuzz-dhcp-client.c b/src/libsystemd-network/fuzz-dhcp-client.c index 21f693c4873..d6a2577194d 100644 --- a/src/libsystemd-network/fuzz-dhcp-client.c +++ b/src/libsystemd-network/fuzz-dhcp-client.c @@ -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; } diff --git a/src/libsystemd-network/sd-dhcp-server.c b/src/libsystemd-network/sd-dhcp-server.c index 48c481809f4..702a2d67553 100644 --- a/src/libsystemd-network/sd-dhcp-server.c +++ b/src/libsystemd-network/sd-dhcp-server.c @@ -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, diff --git a/src/libsystemd-network/test-dhcp-client.c b/src/libsystemd-network/test-dhcp-client.c index b2cadc07e5b..957e43d7627 100644 --- a/src/libsystemd-network/test-dhcp-client.c +++ b/src/libsystemd-network/test-dhcp-client.c @@ -13,12 +13,13 @@ #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; }