socket-util: introduce socket_autobind() helper
Prompted by https://github.com/systemd/systemd/pull/36858#discussion_r2017719305 and #36833
This commit is contained in:
@@ -28,6 +28,7 @@
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#include "process-util.h"
|
||||
#include "random-util.h"
|
||||
#include "socket-util.h"
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
@@ -1454,6 +1455,36 @@ int socket_bind_to_ifindex(int fd, int ifindex) {
|
||||
return setsockopt_int(fd, SOL_SOCKET, SO_BINDTOIFINDEX, ifindex);
|
||||
}
|
||||
|
||||
int socket_autobind(int fd, char **ret_name) {
|
||||
_cleanup_free_ char *name = NULL;
|
||||
uint64_t random;
|
||||
int r;
|
||||
|
||||
/* Generate a random abstract socket name and bind fd to it. This is modeled after the kernel
|
||||
* "autobind" feature, but uses 64-bit random number internally. */
|
||||
|
||||
assert(fd >= 0);
|
||||
assert(ret_name);
|
||||
|
||||
random = random_u64();
|
||||
|
||||
if (asprintf(&name, "@%" PRIu64, random) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
union sockaddr_union sa;
|
||||
assert_cc(DECIMAL_STR_MAX(uint64_t) < sizeof(sa.un.sun_path));
|
||||
|
||||
r = sockaddr_un_set_path(&sa.un, name);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (bind(fd, &sa.sa, r) < 0)
|
||||
return -errno;
|
||||
|
||||
*ret_name = TAKE_PTR(name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t recvmsg_safe(int sockfd, struct msghdr *msg, int flags) {
|
||||
ssize_t n;
|
||||
|
||||
|
||||
@@ -322,6 +322,8 @@ static inline int getsockopt_int(int fd, int level, int optname, int *ret) {
|
||||
int socket_bind_to_ifname(int fd, const char *ifname);
|
||||
int socket_bind_to_ifindex(int fd, int ifindex);
|
||||
|
||||
int socket_autobind(int fd, char **ret_name);
|
||||
|
||||
/* Define a 64-bit version of timeval/timespec in any case, even on 32-bit userspace. */
|
||||
struct timeval_large {
|
||||
uint64_t tvl_sec, tvl_usec;
|
||||
|
||||
Reference in New Issue
Block a user