]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
socket-util: Replace sockaddr length macros with functions
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 30 Apr 2025 20:09:37 +0000 (22:09 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 2 May 2025 07:41:41 +0000 (09:41 +0200)
There's no need for these to be macros, let's just make them regular
functions instead.

21 files changed:
src/basic/socket-util.c
src/basic/socket-util.h
src/libsystemd-network/dhcp-network.c
src/libsystemd/sd-bus/sd-bus.c
src/libsystemd/sd-journal/journal-send.c
src/libsystemd/sd-resolve/test-resolve.c
src/mountfsd/mountfsd-manager.c
src/nspawn/nspawn.c
src/nsresourced/nsresourced-manager.c
src/resolve/resolved-dns-server.c
src/resolve/resolved-dns-stream.c
src/resolve/resolved-dns-stub.c
src/resolve/test-resolved-stream.c
src/shared/local-addresses.c
src/shared/plymouth-util.c
src/ssh-generator/ssh-proxy.c
src/test/test-fileio.c
src/test/test-mempress.c
src/test/test-socket-util.c
src/udev/udev-ctrl.c
src/userdb/userdbd-manager.c

index b86b67e783ff285db7d0a82d7c24c82e774506d2..61a77370eb430c04d14eea9cb3e589723cf9110b 100644 (file)
@@ -4,6 +4,7 @@
 #include <errno.h>
 #include <limits.h>
 #include <linux/if.h>
+#include <linux/if_arp.h>
 #include <net/if.h>
 #include <netdb.h>
 #include <netinet/ip.h>
@@ -1350,6 +1351,53 @@ void* cmsg_find_and_copy_data(struct msghdr *mh, int level, int type, void *buf,
         return memcpy_safe(buf, CMSG_DATA(cmsg), buf_len);
 }
 
+size_t sockaddr_ll_len(const struct sockaddr_ll *sa) {
+        /* Certain hardware address types (e.g Infiniband) do not fit into sll_addr
+         * (8 bytes) and run over the structure. This function returns the correct size that
+         * must be passed to kernel. */
+
+        assert(sa->sll_family == AF_PACKET);
+
+        size_t mac_len = sizeof(sa->sll_addr);
+
+        if (be16toh(sa->sll_hatype) == ARPHRD_ETHER)
+                mac_len = MAX(mac_len, (size_t) ETH_ALEN);
+        if (be16toh(sa->sll_hatype) == ARPHRD_INFINIBAND)
+                mac_len = MAX(mac_len, (size_t) INFINIBAND_ALEN);
+
+        return offsetof(struct sockaddr_ll, sll_addr) + mac_len;
+}
+
+size_t sockaddr_un_len(const struct sockaddr_un *sa) {
+        /* Covers only file system and abstract AF_UNIX socket addresses, but not unnamed socket addresses. */
+
+        assert(sa->sun_family == AF_UNIX);
+
+        return offsetof(struct sockaddr_un, sun_path) +
+                (sa->sun_path[0] == 0 ?
+                        1 + strnlen(sa->sun_path+1, sizeof(sa->sun_path)-1) :
+                        strnlen(sa->sun_path, sizeof(sa->sun_path))+1);
+}
+
+size_t sockaddr_len(const union sockaddr_union *sa) {
+        switch (sa->sa.sa_family) {
+        case AF_INET:
+                return sizeof(struct sockaddr_in);
+        case AF_INET6:
+                return sizeof(struct sockaddr_in6);
+        case AF_UNIX:
+                return sockaddr_un_len(&sa->un);
+        case AF_PACKET:
+                return sockaddr_ll_len(&sa->ll);
+        case AF_NETLINK:
+                return sizeof(struct sockaddr_nl);
+        case AF_VSOCK:
+                return sizeof(struct sockaddr_vm);
+        default:
+                assert_not_reached();
+        }
+}
+
 int socket_ioctl_fd(void) {
         int fd;
 
index d0aedb524e80085e16d8885896ec9d339c42ec9c..a69277c63966c895f6a11f1c4080590572445a3b 100644 (file)
@@ -238,62 +238,11 @@ void* cmsg_find_and_copy_data(struct msghdr *mh, int level, int type, void *buf,
                                     (size) == CMSG_ALIGN(size) ? 1 : -1]; \
         }
 
-/*
- * Certain hardware address types (e.g Infiniband) do not fit into sll_addr
- * (8 bytes) and run over the structure. This macro returns the correct size that
- * must be passed to kernel.
- */
-#define SOCKADDR_LL_LEN(sa)                                             \
-        ({                                                              \
-                const struct sockaddr_ll *_sa = &(sa);                  \
-                size_t _mac_len = sizeof(_sa->sll_addr);                \
-                assert(_sa->sll_family == AF_PACKET);                   \
-                if (be16toh(_sa->sll_hatype) == ARPHRD_ETHER)           \
-                        _mac_len = MAX(_mac_len, (size_t) ETH_ALEN);    \
-                if (be16toh(_sa->sll_hatype) == ARPHRD_INFINIBAND)      \
-                        _mac_len = MAX(_mac_len, (size_t) INFINIBAND_ALEN); \
-                offsetof(struct sockaddr_ll, sll_addr) + _mac_len;      \
-        })
+size_t sockaddr_ll_len(const struct sockaddr_ll *sa);
 
-/* Covers only file system and abstract AF_UNIX socket addresses, but not unnamed socket addresses. */
-#define SOCKADDR_UN_LEN(sa)                                             \
-        ({                                                              \
-                const struct sockaddr_un *_sa = &(sa);                  \
-                assert(_sa->sun_family == AF_UNIX);                     \
-                offsetof(struct sockaddr_un, sun_path) +                \
-                        (_sa->sun_path[0] == 0 ?                        \
-                         1 + strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : \
-                         strnlen(_sa->sun_path, sizeof(_sa->sun_path))+1); \
-        })
+size_t sockaddr_un_len(const struct sockaddr_un *sa);
 
-#define SOCKADDR_LEN(saddr)                                             \
-        ({                                                              \
-                const union sockaddr_union *__sa = &(saddr);            \
-                size_t _len;                                            \
-                switch (__sa->sa.sa_family) {                           \
-                case AF_INET:                                           \
-                        _len = sizeof(struct sockaddr_in);              \
-                        break;                                          \
-                case AF_INET6:                                          \
-                        _len = sizeof(struct sockaddr_in6);             \
-                        break;                                          \
-                case AF_UNIX:                                           \
-                        _len = SOCKADDR_UN_LEN(__sa->un);               \
-                        break;                                          \
-                case AF_PACKET:                                         \
-                        _len = SOCKADDR_LL_LEN(__sa->ll);               \
-                        break;                                          \
-                case AF_NETLINK:                                        \
-                        _len = sizeof(struct sockaddr_nl);              \
-                        break;                                          \
-                case AF_VSOCK:                                          \
-                        _len = sizeof(struct sockaddr_vm);              \
-                        break;                                          \
-                default:                                                \
-                        assert_not_reached();                           \
-                }                                                       \
-                _len;                                                   \
-        })
+size_t sockaddr_len(const union sockaddr_union *sa);
 
 int socket_ioctl_fd(void);
 
index e9e500623d3e62d91efd1825f6416133b89a2aff..207f68a5e6e6e8dd8ca327ce4efbb8a034947a1c 100644 (file)
@@ -136,7 +136,7 @@ static int _bind_raw_socket(
         /* We may overflow link->ll. link->ll_buffer ensures we have enough space. */
         memcpy(link->ll.sll_addr, bcast_addr->bytes, bcast_addr->length);
 
-        r = bind(s, &link->sa, SOCKADDR_LL_LEN(link->ll));
+        r = bind(s, &link->sa, sockaddr_ll_len(&link->ll));
         if (r < 0)
                 return -errno;
 
@@ -258,7 +258,7 @@ int dhcp_network_send_raw_socket(
         assert(packet);
         assert(len > 0);
 
-        if (sendto(s, packet, len, 0, &link->sa, SOCKADDR_LL_LEN(link->ll)) < 0)
+        if (sendto(s, packet, len, 0, &link->sa, sockaddr_ll_len(&link->ll)) < 0)
                 return -errno;
 
         return 0;
index db8c19e45168daf2e83a8e01f73e9eba01d63b19..bbde421ebca90e90b909780b74fce58352ee0e8c 100644 (file)
@@ -1030,7 +1030,7 @@ static int parse_container_unix_address(sd_bus *b, const char **p, char **guid)
                 /* Note that we use the old /var/run prefix here, to increase compatibility with really old containers */
                 .sun_path = "/var/run/dbus/system_bus_socket",
         };
-        b->sockaddr_size = SOCKADDR_UN_LEN(b->sockaddr.un);
+        b->sockaddr_size = sockaddr_un_len(&b->sockaddr.un);
         b->is_local = false;
 
         return 0;
index 012592b4cd2257b97e3eb5103a7180989d9a9429..d043e1882d0179f3a395a7c51fc39bc056e84543 100644 (file)
@@ -230,7 +230,7 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) {
         };
         struct msghdr mh = {
                 .msg_name = (struct sockaddr*) &sa.sa,
-                .msg_namelen = SOCKADDR_UN_LEN(sa.un),
+                .msg_namelen = sockaddr_un_len(&sa.un),
         };
         ssize_t k;
         bool have_syslog_identifier = false;
index 829e13ea69df0b0d6fee88498fd3c8a36d2c0158..7a599925f4c51448ef88725fc6ae9fd3a91ce780 100644 (file)
@@ -84,7 +84,7 @@ int main(int argc, char *argv[]) {
 
         /* Make an address -> name query */
         sa.in.sin_addr.s_addr = inet_addr(argc >= 3 ? argv[2] : "193.99.144.71");
-        r = sd_resolve_getnameinfo(resolve, &q2, &sa.sa, SOCKADDR_LEN(sa), 0, SD_RESOLVE_GET_BOTH, getnameinfo_handler, NULL);
+        r = sd_resolve_getnameinfo(resolve, &q2, &sa.sa, sockaddr_len(&sa), 0, SD_RESOLVE_GET_BOTH, getnameinfo_handler, NULL);
         if (r < 0)
                 log_error_errno(r, "sd_resolve_getnameinfo(): %m");
 
index 9b10f15937fd9fbf55697114e270581661b261e8..0d24e2d696a250b485d3c155a1738fbf8ae0a4aa 100644 (file)
@@ -256,7 +256,7 @@ int manager_startup(Manager *m) {
                 (void) sockaddr_un_unlink(&sockaddr.un);
 
                 WITH_UMASK(0000)
-                        if (bind(m->listen_fd, &sockaddr.sa, SOCKADDR_UN_LEN(sockaddr.un)) < 0)
+                        if (bind(m->listen_fd, &sockaddr.sa, sockaddr_un_len(&sockaddr.un)) < 0)
                                 return log_error_errno(errno, "Failed to bind socket: %m");
 
                 if (listen(m->listen_fd, SOMAXCONN) < 0)
index b1eeef335df4375630133a107bc8eb08a9f743c5..dd9649d71e03e733cabc6de50538df25538855cf 100644 (file)
@@ -3660,7 +3660,7 @@ static int setup_notify_child(const void *directory) {
         (void) sockaddr_un_unlink(&sa.un);
 
         WITH_UMASK(0577) { /* only set "w" bit, which is all that's necessary for connecting from the container */
-                r = bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
+                r = bind(fd, &sa.sa, sockaddr_un_len(&sa.un));
                 if (r < 0)
                         return log_error_errno(errno, "bind(" NSPAWN_NOTIFY_SOCKET_PATH ") failed: %m");
         }
index 9849d63b0a0801ab8029021313dd058a9ffdd28b..ee52f09f84f04d4ef6768b4cf7923f010172509e 100644 (file)
@@ -445,7 +445,7 @@ static int manager_make_listen_socket(Manager *m) {
         (void) sockaddr_un_unlink(&sockaddr.un);
 
         WITH_UMASK(0000)
-                if (bind(m->listen_fd, &sockaddr.sa, SOCKADDR_UN_LEN(sockaddr.un)) < 0)
+                if (bind(m->listen_fd, &sockaddr.sa, sockaddr_un_len(&sockaddr.un)) < 0)
                         return log_error_errno(errno, "Failed to bind socket: %m");
 
         r = mkdir_p("/run/systemd/userdb", 0755);
index 36b7f74813a988f0d90b59b1ec60476d315d31f3..5996d9bcc6aaa5d0a764fe48e5faa9c489f5c1d4 100644 (file)
@@ -1274,7 +1274,7 @@ int dns_server_is_accessible(DnsServer *s) {
                         return r;
         }
 
-        r = RET_NERRNO(connect(fd, &sa.sa, SOCKADDR_LEN(sa)));
+        r = RET_NERRNO(connect(fd, &sa.sa, sockaddr_len(&sa)));
         if (!IN_SET(r,
                     0,
                     -ENETUNREACH,
index 41c31c5a4151e35831ecccc7e145ada36776c55a..03c6cd7cf4d7d38b72489cf1c3a93656065c4e26 100644 (file)
@@ -572,7 +572,7 @@ int dns_stream_new(
 
         if (tfo_address) {
                 s->tfo_address = *tfo_address;
-                s->tfo_salen = SOCKADDR_LEN(*tfo_address);
+                s->tfo_salen = sockaddr_len(tfo_address);
         }
 
         *ret = TAKE_PTR(s);
index 08b35690ba800751ac1ba830e3ab328a4a8d8be6..053365f7fa68c43001059f6c205afa322326ea6d 100644 (file)
@@ -1322,7 +1322,7 @@ static int manager_dns_stub_fd_extra(Manager *m, DnsStubListenerExtra *l, int ty
                         log_debug_errno(r, "Failed to enable fragment size reception, ignoring: %m");
         }
 
-        r = RET_NERRNO(bind(fd, &sa.sa, SOCKADDR_LEN(sa)));
+        r = RET_NERRNO(bind(fd, &sa.sa, sockaddr_len(&sa)));
         if (r < 0)
                 goto fail;
 
index ef5c2763ec1b59864d199b810e88be2c9a1a24f1..b5e8ce9f95532a8f21ac0155fcdadbaa783e2946 100644 (file)
@@ -111,7 +111,7 @@ static void *tcp_dns_server(void *p) {
 
         assert_se((bindfd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0)) >= 0);
         assert_se(setsockopt(bindfd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)) >= 0);
-        assert_se(bind(bindfd, &server_address.sa, SOCKADDR_LEN(server_address)) >= 0);
+        assert_se(bind(bindfd, &server_address.sa, sockaddr_len(&server_address)) >= 0);
         assert_se(listen(bindfd, 1) >= 0);
         assert_se((acceptfd = accept(bindfd, NULL, NULL)) >= 0);
         server_handle(acceptfd);
@@ -246,7 +246,7 @@ static void test_dns_stream(bool tls) {
         assert_se((clientfd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0)) >= 0);
 
         for (int i = 0; i < 100; i++) {
-                r = connect(clientfd, &server_address.sa, SOCKADDR_LEN(server_address));
+                r = connect(clientfd, &server_address.sa, sockaddr_len(&server_address));
                 if (r >= 0)
                         break;
                 usleep_safe(EVENT_TIMEOUT_USEC / 100);
index 1874bcbcee19ebc3756fb9e89ed4e84405504367..85269d4d709318361b298a4ec2c647ff07eaa7f1 100644 (file)
@@ -680,16 +680,16 @@ int local_outbounds(
                  * make use of the binding and return it. Hence, let's not unnecessarily fail early here: we
                  * can still easily detect if the auto-binding worked or not, by comparing the bound IP
                  * address with zero — which we do below. */
-                if (connect(fd, &sa.sa, SOCKADDR_LEN(sa)) < 0)
+                if (connect(fd, &sa.sa, sockaddr_len(&sa)) < 0)
                         log_debug_errno(errno, "Failed to connect SOCK_DGRAM socket to gateway, ignoring: %m");
 
                 /* Let's now read the socket address of the socket. A routing decision should have been
                  * made. Let's verify that and use the data. */
-                salen = SOCKADDR_LEN(sa);
+                salen = sockaddr_len(&sa);
                 if (getsockname(fd, &sa.sa, &salen) < 0)
                         return -errno;
                 assert(sa.sa.sa_family == i->family);
-                assert(salen == SOCKADDR_LEN(sa));
+                assert(salen == sockaddr_len(&sa));
 
                 switch (i->family) {
 
index 8ef52d90c887e05b7c252a3f89def4188e2825a5..72f282f9bd7a996b76b6c77c201d4b8f369ee04a 100644 (file)
@@ -17,7 +17,7 @@ int plymouth_connect(int flags) {
         if (fd < 0)
                 return -errno;
 
-        if (connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
+        if (connect(fd, &sa.sa, sockaddr_un_len(&sa.un)) < 0)
                 return -errno;
 
         return TAKE_FD(fd);
index 3c21f8d8981c640f9d20a3ccaa7303ddf8ea283b..86db2e1cde843a09d0379aa34e455f6b453b3fd0 100644 (file)
@@ -37,7 +37,7 @@ static int process_vsock_cid(unsigned cid, const char *port) {
         if (fd < 0)
                 return log_error_errno(errno, "Failed to allocate AF_VSOCK socket: %m");
 
-        if (connect(fd, &sa.sa, SOCKADDR_LEN(sa)) < 0)
+        if (connect(fd, &sa.sa, sockaddr_len(&sa)) < 0)
                 return log_error_errno(errno, "Failed to connect to vsock:%u:%u: %m", sa.vm.svm_cid, sa.vm.svm_port);
 
         /* OpenSSH wants us to send a single byte along with the file descriptor, hence do so */
index 97eeb59afbb642f58a7362aefd19f2bbc631a69b..731a37caf1db6273af34c9f4c40fd4058f278078 100644 (file)
@@ -928,7 +928,7 @@ TEST(read_full_file_socket) {
 
         assert_se(sockaddr_un_set_path(&sa.un, j) >= 0);
 
-        assert_se(bind(listener, &sa.sa, SOCKADDR_UN_LEN(sa.un)) >= 0);
+        assert_se(bind(listener, &sa.sa, sockaddr_un_len(&sa.un)) >= 0);
         assert_se(listen(listener, 1) >= 0);
 
         /* Make sure the socket doesn't fit into a struct sockaddr_un, but we can still access it */
index 6bbc485de6d4318bf317d93115be0c02d6688b96..6f4e6586161f895daf9b371283586a686e5fb64f 100644 (file)
@@ -86,7 +86,7 @@ TEST(fake_pressure) {
         socket_fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
         assert_se(socket_fd >= 0);
         assert_se(sockaddr_un_set_path(&sa.un, k) >= 0);
-        assert_se(bind(socket_fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) >= 0);
+        assert_se(bind(socket_fd, &sa.sa, sockaddr_un_len(&sa.un)) >= 0);
         assert_se(listen(socket_fd, 1) >= 0);
 
         /* Ideally we'd just allocate this on the stack, but AddressSanitizer doesn't like it if threads
index 63bbb1d1d274ae4d661fe31f74282a0ea44564cd..acf11f3639d293de0dc70040bdc4c44d628f8584 100644 (file)
@@ -134,8 +134,8 @@ TEST(sockaddr_un_len) {
                 .sun_path = "\0foobar",
         };
 
-        assert_se(SOCKADDR_UN_LEN(fs) == offsetof(struct sockaddr_un, sun_path) + strlen(fs.sun_path) + 1);
-        assert_se(SOCKADDR_UN_LEN(abstract) == offsetof(struct sockaddr_un, sun_path) + 1 + strlen(abstract.sun_path + 1));
+        assert_se(sockaddr_un_len(&fs) == offsetof(struct sockaddr_un, sun_path) + strlen(fs.sun_path) + 1);
+        assert_se(sockaddr_un_len(&abstract) == offsetof(struct sockaddr_un, sun_path) + 1 + strlen(abstract.sun_path + 1));
 }
 
 TEST(in_addr_is_multicast) {
@@ -564,14 +564,14 @@ TEST(sockaddr_un_set_path) {
 
         fd1 = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
         assert_se(fd1 >= 0);
-        assert_se(bind(fd1, &sa.sa, SOCKADDR_LEN(sa)) >= 0);
+        assert_se(bind(fd1, &sa.sa, sockaddr_len(&sa)) >= 0);
         assert_se(listen(fd1, 1) >= 0);
 
         sh = unlink_and_free(sh); /* remove temporary symlink */
 
         fd2 = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
         assert_se(fd2 >= 0);
-        assert_se(connect(fd2, &sa.sa, SOCKADDR_LEN(sa)) < 0);
+        assert_se(connect(fd2, &sa.sa, sockaddr_len(&sa)) < 0);
         assert_se(errno == ENOENT); /* we removed the symlink, must fail */
 
         free(j);
@@ -581,7 +581,7 @@ TEST(sockaddr_un_set_path) {
         assert_se(fd3 > 0);
         assert_se(sockaddr_un_set_path(&sa.un, FORMAT_PROC_FD_PATH(fd3)) >= 0); /* connect via O_PATH instead, circumventing 108ch limit */
 
-        assert_se(connect(fd2, &sa.sa, SOCKADDR_LEN(sa)) >= 0);
+        assert_se(connect(fd2, &sa.sa, sockaddr_len(&sa)) >= 0);
 }
 
 TEST(getpeerpidref) {
index 42e42ee33622628c1a3114c756414ef162305838..1914bf7929f2a2b61abc282d9fd94a2819b0c6a3 100644 (file)
@@ -73,7 +73,7 @@ int udev_ctrl_new_from_fd(UdevCtrl **ret, int fd) {
                 .sun_path = "/run/udev/control",
         };
 
-        uctrl->addrlen = SOCKADDR_UN_LEN(uctrl->saddr.un);
+        uctrl->addrlen = sockaddr_un_len(&uctrl->saddr.un);
 
         *ret = TAKE_PTR(uctrl);
         return 0;
index 63a53f0e00e8e07f0182ac1e6d6394745e15f152..e30ec8ed757d5885e3ea7342cf3466d89ba5b6de 100644 (file)
@@ -287,7 +287,7 @@ static int manager_make_listen_socket(Manager *m) {
         (void) sockaddr_un_unlink(&sockaddr.un);
 
         WITH_UMASK(0000)
-                if (bind(m->listen_fd, &sockaddr.sa, SOCKADDR_UN_LEN(sockaddr.un)) < 0)
+                if (bind(m->listen_fd, &sockaddr.sa, sockaddr_un_len(&sockaddr.un)) < 0)
                         return log_error_errno(errno, "Failed to bind socket: %m");
 
         FOREACH_STRING(alias,