summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-10-26 01:09:02 +0100
committerLennart Poettering <lennart@poettering.net>2015-10-26 01:24:39 +0100
commit2583fbea8e762d2e915582af60560f884d5093f5 (patch)
tree78b358f50557780c5d0bb64b4248eba5e1cec935
parent58ce77339c60c8c5f1f7789adf0ef80107dbafe3 (diff)
socket-util: move remaining socket-related calls from util.[ch] to socket-util.[ch]
-rw-r--r--src/basic/socket-util.c184
-rw-r--r--src/basic/socket-util.h12
-rw-r--r--src/basic/terminal-util.c1
-rw-r--r--src/basic/util.c181
-rw-r--r--src/basic/util.h12
-rw-r--r--src/core/namespace.c1
-rw-r--r--src/libsystemd/sd-login/sd-login.c1
-rw-r--r--src/libsystemd/sd-netlink/sd-netlink.c1
-rw-r--r--src/nspawn/nspawn-expose-ports.c1
-rw-r--r--src/nspawn/nspawn.c1
10 files changed, 201 insertions, 194 deletions
diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c
index 312512ba1d..684ac765f5 100644
--- a/src/basic/socket-util.c
+++ b/src/basic/socket-util.c
@@ -23,20 +23,22 @@
#include <errno.h>
#include <net/if.h>
#include <netdb.h>
+#include <netinet/ip.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
+#include "fd-util.h"
#include "fileio.h"
#include "formats-util.h"
#include "macro.h"
#include "missing.h"
#include "path-util.h"
+#include "socket-util.h"
#include "string-util.h"
#include "util.h"
-#include "socket-util.h"
int socket_address_parse(SocketAddress *a, const char *s) {
char *e, *n;
@@ -749,3 +751,183 @@ bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b
return false;
}
+
+int fd_inc_sndbuf(int fd, size_t n) {
+ int r, value;
+ socklen_t l = sizeof(value);
+
+ r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
+ if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
+ return 0;
+
+ /* If we have the privileges we will ignore the kernel limit. */
+
+ value = (int) n;
+ if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
+ if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
+ return -errno;
+
+ return 1;
+}
+
+int fd_inc_rcvbuf(int fd, size_t n) {
+ int r, value;
+ socklen_t l = sizeof(value);
+
+ r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
+ if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
+ return 0;
+
+ /* If we have the privileges we will ignore the kernel limit. */
+
+ value = (int) n;
+ if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
+ if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
+ return -errno;
+ return 1;
+}
+
+static const char* const ip_tos_table[] = {
+ [IPTOS_LOWDELAY] = "low-delay",
+ [IPTOS_THROUGHPUT] = "throughput",
+ [IPTOS_RELIABILITY] = "reliability",
+ [IPTOS_LOWCOST] = "low-cost",
+};
+
+DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
+
+int getpeercred(int fd, struct ucred *ucred) {
+ socklen_t n = sizeof(struct ucred);
+ struct ucred u;
+ int r;
+
+ assert(fd >= 0);
+ assert(ucred);
+
+ r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
+ if (r < 0)
+ return -errno;
+
+ if (n != sizeof(struct ucred))
+ return -EIO;
+
+ /* Check if the data is actually useful and not suppressed due
+ * to namespacing issues */
+ if (u.pid <= 0)
+ return -ENODATA;
+ if (u.uid == UID_INVALID)
+ return -ENODATA;
+ if (u.gid == GID_INVALID)
+ return -ENODATA;
+
+ *ucred = u;
+ return 0;
+}
+
+int getpeersec(int fd, char **ret) {
+ socklen_t n = 64;
+ char *s;
+ int r;
+
+ assert(fd >= 0);
+ assert(ret);
+
+ s = new0(char, n);
+ if (!s)
+ return -ENOMEM;
+
+ r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
+ if (r < 0) {
+ free(s);
+
+ if (errno != ERANGE)
+ return -errno;
+
+ s = new0(char, n);
+ if (!s)
+ return -ENOMEM;
+
+ r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
+ if (r < 0) {
+ free(s);
+ return -errno;
+ }
+ }
+
+ if (isempty(s)) {
+ free(s);
+ return -EOPNOTSUPP;
+ }
+
+ *ret = s;
+ return 0;
+}
+
+int send_one_fd(int transport_fd, int fd, int flags) {
+ union {
+ struct cmsghdr cmsghdr;
+ uint8_t buf[CMSG_SPACE(sizeof(int))];
+ } control = {};
+ struct msghdr mh = {
+ .msg_control = &control,
+ .msg_controllen = sizeof(control),
+ };
+ struct cmsghdr *cmsg;
+
+ assert(transport_fd >= 0);
+ assert(fd >= 0);
+
+ cmsg = CMSG_FIRSTHDR(&mh);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(int));
+ memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
+
+ mh.msg_controllen = CMSG_SPACE(sizeof(int));
+ if (sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags) < 0)
+ return -errno;
+
+ return 0;
+}
+
+int receive_one_fd(int transport_fd, int flags) {
+ union {
+ struct cmsghdr cmsghdr;
+ uint8_t buf[CMSG_SPACE(sizeof(int))];
+ } control = {};
+ struct msghdr mh = {
+ .msg_control = &control,
+ .msg_controllen = sizeof(control),
+ };
+ struct cmsghdr *cmsg, *found = NULL;
+
+ assert(transport_fd >= 0);
+
+ /*
+ * Receive a single FD via @transport_fd. We don't care for
+ * the transport-type. We retrieve a single FD at most, so for
+ * packet-based transports, the caller must ensure to send
+ * only a single FD per packet. This is best used in
+ * combination with send_one_fd().
+ */
+
+ if (recvmsg(transport_fd, &mh, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC | flags) < 0)
+ return -errno;
+
+ CMSG_FOREACH(cmsg, &mh) {
+ if (cmsg->cmsg_level == SOL_SOCKET &&
+ cmsg->cmsg_type == SCM_RIGHTS &&
+ cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
+ assert(!found);
+ found = cmsg;
+ break;
+ }
+ }
+
+ if (!found) {
+ cmsg_close_all(&mh);
+ return -EIO;
+ }
+
+ return *(int*) CMSG_DATA(found);
+}
diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h
index da1273e745..8b5410b391 100644
--- a/src/basic/socket-util.h
+++ b/src/basic/socket-util.h
@@ -115,3 +115,15 @@ int netlink_family_to_string_alloc(int b, char **s);
int netlink_family_from_string(const char *s) _pure_;
bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b);
+
+int fd_inc_sndbuf(int fd, size_t n);
+int fd_inc_rcvbuf(int fd, size_t n);
+
+int ip_tos_to_string_alloc(int i, char **s);
+int ip_tos_from_string(const char *s);
+
+int getpeercred(int fd, struct ucred *ucred);
+int getpeersec(int fd, char **ret);
+
+int send_one_fd(int transport_fd, int fd, int flags);
+int receive_one_fd(int transport_fd, int flags);
diff --git a/src/basic/terminal-util.c b/src/basic/terminal-util.c
index 3b3ca775d0..7dfab0af62 100644
--- a/src/basic/terminal-util.c
+++ b/src/basic/terminal-util.c
@@ -36,6 +36,7 @@
#include "io-util.h"
#include "path-util.h"
#include "process-util.h"
+#include "socket-util.h"
#include "string-util.h"
#include "terminal-util.h"
#include "time-util.h"
diff --git a/src/basic/util.c b/src/basic/util.c
index 010261b37d..2129d46aef 100644
--- a/src/basic/util.c
+++ b/src/basic/util.c
@@ -32,7 +32,6 @@
#include <linux/oom.h>
#include <linux/sched.h>
#include <locale.h>
-#include <netinet/ip.h>
#include <poll.h>
#include <pwd.h>
#include <sched.h>
@@ -2271,15 +2270,6 @@ static const char* const rlimit_table[_RLIMIT_MAX] = {
DEFINE_STRING_TABLE_LOOKUP(rlimit, int);
-static const char* const ip_tos_table[] = {
- [IPTOS_LOWDELAY] = "low-delay",
- [IPTOS_THROUGHPUT] = "throughput",
- [IPTOS_RELIABILITY] = "reliability",
- [IPTOS_LOWCOST] = "low-cost",
-};
-
-DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
-
bool kexec_loaded(void) {
bool loaded = false;
char *s;
@@ -2362,41 +2352,6 @@ void* memdup(const void *p, size_t l) {
return r;
}
-int fd_inc_sndbuf(int fd, size_t n) {
- int r, value;
- socklen_t l = sizeof(value);
-
- r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
- if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
- return 0;
-
- /* If we have the privileges we will ignore the kernel limit. */
-
- value = (int) n;
- if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
- if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
- return -errno;
-
- return 1;
-}
-
-int fd_inc_rcvbuf(int fd, size_t n) {
- int r, value;
- socklen_t l = sizeof(value);
-
- r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
- if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
- return 0;
-
- /* If we have the privileges we will ignore the kernel limit. */
-
- value = (int) n;
- if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
- if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
- return -errno;
- return 1;
-}
-
int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...) {
bool stdout_is_tty, stderr_is_tty;
pid_t parent_pid, agent_pid;
@@ -3264,73 +3219,6 @@ int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int
return reset_uid_gid();
}
-int getpeercred(int fd, struct ucred *ucred) {
- socklen_t n = sizeof(struct ucred);
- struct ucred u;
- int r;
-
- assert(fd >= 0);
- assert(ucred);
-
- r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
- if (r < 0)
- return -errno;
-
- if (n != sizeof(struct ucred))
- return -EIO;
-
- /* Check if the data is actually useful and not suppressed due
- * to namespacing issues */
- if (u.pid <= 0)
- return -ENODATA;
- if (u.uid == UID_INVALID)
- return -ENODATA;
- if (u.gid == GID_INVALID)
- return -ENODATA;
-
- *ucred = u;
- return 0;
-}
-
-int getpeersec(int fd, char **ret) {
- socklen_t n = 64;
- char *s;
- int r;
-
- assert(fd >= 0);
- assert(ret);
-
- s = new0(char, n);
- if (!s)
- return -ENOMEM;
-
- r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
- if (r < 0) {
- free(s);
-
- if (errno != ERANGE)
- return -errno;
-
- s = new0(char, n);
- if (!s)
- return -ENOMEM;
-
- r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
- if (r < 0) {
- free(s);
- return -errno;
- }
- }
-
- if (isempty(s)) {
- free(s);
- return -EOPNOTSUPP;
- }
-
- *ret = s;
- return 0;
-}
-
/* This is much like like mkostemp() but is subject to umask(). */
int mkostemp_safe(char *pattern, int flags) {
_cleanup_umask_ mode_t u;
@@ -4342,75 +4230,6 @@ int fgetxattr_malloc(int fd, const char *name, char **value) {
}
}
-int send_one_fd(int transport_fd, int fd, int flags) {
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(int))];
- } control = {};
- struct msghdr mh = {
- .msg_control = &control,
- .msg_controllen = sizeof(control),
- };
- struct cmsghdr *cmsg;
-
- assert(transport_fd >= 0);
- assert(fd >= 0);
-
- cmsg = CMSG_FIRSTHDR(&mh);
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- cmsg->cmsg_len = CMSG_LEN(sizeof(int));
- memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
-
- mh.msg_controllen = CMSG_SPACE(sizeof(int));
- if (sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags) < 0)
- return -errno;
-
- return 0;
-}
-
-int receive_one_fd(int transport_fd, int flags) {
- union {
- struct cmsghdr cmsghdr;
- uint8_t buf[CMSG_SPACE(sizeof(int))];
- } control = {};
- struct msghdr mh = {
- .msg_control = &control,
- .msg_controllen = sizeof(control),
- };
- struct cmsghdr *cmsg, *found = NULL;
-
- assert(transport_fd >= 0);
-
- /*
- * Receive a single FD via @transport_fd. We don't care for
- * the transport-type. We retrieve a single FD at most, so for
- * packet-based transports, the caller must ensure to send
- * only a single FD per packet. This is best used in
- * combination with send_one_fd().
- */
-
- if (recvmsg(transport_fd, &mh, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC | flags) < 0)
- return -errno;
-
- CMSG_FOREACH(cmsg, &mh) {
- if (cmsg->cmsg_level == SOL_SOCKET &&
- cmsg->cmsg_type == SCM_RIGHTS &&
- cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
- assert(!found);
- found = cmsg;
- break;
- }
- }
-
- if (!found) {
- cmsg_close_all(&mh);
- return -EIO;
- }
-
- return *(int*) CMSG_DATA(found);
-}
-
void nop_signal_handler(int sig) {
/* nothing here */
}
diff --git a/src/basic/util.h b/src/basic/util.h
index 7d6412523c..55b428fa63 100644
--- a/src/basic/util.h
+++ b/src/basic/util.h
@@ -330,9 +330,6 @@ int sched_policy_from_string(const char *s);
const char *rlimit_to_string(int i) _const_;
int rlimit_from_string(const char *s) _pure_;
-int ip_tos_to_string_alloc(int i, char **s);
-int ip_tos_from_string(const char *s);
-
extern int saved_argc;
extern char **saved_argv;
@@ -344,9 +341,6 @@ char *format_bytes(char *buf, size_t l, uint64_t t);
void* memdup(const void *p, size_t l) _alloc_(2);
-int fd_inc_sndbuf(int fd, size_t n);
-int fd_inc_rcvbuf(int fd, size_t n);
-
int fork_agent(pid_t *pid, const int except[], unsigned n_except, const char *path, ...);
int setrlimit_closest(int resource, const struct rlimit *rlim);
@@ -611,9 +605,6 @@ int container_get_leader(const char *machine, pid_t *pid);
int namespace_open(pid_t pid, int *pidns_fd, int *mntns_fd, int *netns_fd, int *userns_fd, int *root_fd);
int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int root_fd);
-int getpeercred(int fd, struct ucred *ucred);
-int getpeersec(int fd, char **ret);
-
int mkostemp_safe(char *pattern, int flags);
int open_tmpfile(const char *path, int flags);
@@ -700,9 +691,6 @@ int mount_move_root(const char *path);
int getxattr_malloc(const char *path, const char *name, char **value, bool allow_symlink);
int fgetxattr_malloc(int fd, const char *name, char **value);
-int send_one_fd(int transport_fd, int fd, int flags);
-int receive_one_fd(int transport_fd, int flags);
-
void nop_signal_handler(int sig);
int version(void);
diff --git a/src/core/namespace.c b/src/core/namespace.c
index 470f384056..4d11d54bfe 100644
--- a/src/core/namespace.c
+++ b/src/core/namespace.c
@@ -36,6 +36,7 @@
#include "namespace.h"
#include "path-util.h"
#include "selinux-util.h"
+#include "socket-util.h"
#include "string-util.h"
#include "strv.h"
#include "util.h"
diff --git a/src/libsystemd/sd-login/sd-login.c b/src/libsystemd/sd-login/sd-login.c
index 6012004a0b..f564d43e06 100644
--- a/src/libsystemd/sd-login/sd-login.c
+++ b/src/libsystemd/sd-login/sd-login.c
@@ -36,6 +36,7 @@
#include "io-util.h"
#include "login-util.h"
#include "macro.h"
+#include "socket-util.h"
#include "string-util.h"
#include "strv.h"
#include "user-util.h"
diff --git a/src/libsystemd/sd-netlink/sd-netlink.c b/src/libsystemd/sd-netlink/sd-netlink.c
index 57c5db1231..ba1f2a5a42 100644
--- a/src/libsystemd/sd-netlink/sd-netlink.c
+++ b/src/libsystemd/sd-netlink/sd-netlink.c
@@ -30,6 +30,7 @@
#include "missing.h"
#include "netlink-internal.h"
#include "netlink-util.h"
+#include "socket-util.h"
#include "util.h"
static int sd_netlink_new(sd_netlink **ret) {
diff --git a/src/nspawn/nspawn-expose-ports.c b/src/nspawn/nspawn-expose-ports.c
index df9fbe185b..98e4a7682f 100644
--- a/src/nspawn/nspawn-expose-ports.c
+++ b/src/nspawn/nspawn-expose-ports.c
@@ -27,6 +27,7 @@
#include "local-addresses.h"
#include "netlink-util.h"
#include "nspawn-expose-ports.h"
+#include "socket-util.h"
#include "string-util.h"
#include "util.h"
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index f01a376af8..6502fe1943 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -86,6 +86,7 @@
#include "seccomp-util.h"
#endif
#include "signal-util.h"
+#include "socket-util.h"
#include "string-util.h"
#include "strv.h"
#include "terminal-util.h"