summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLuca Boccassi <luca.boccassi@microsoft.com>2020-12-07 21:15:28 +0000
committerGitHub <noreply@github.com>2020-12-07 21:15:28 +0000
commit77613416e0c79050b46bd728608e2c9e05e216d9 (patch)
treefd918c9df45b09d88b0f16da2efccbfd69b90c1f /src
parent88fc9c9bad006a9fd05fbe4fe0107a2adccdae3c (diff)
parent52975f86721e4f1c612dbf39f92a590edcea2b72 (diff)
downloadsystemd-77613416e0c79050b46bd728608e2c9e05e216d9.tar.gz
Merge pull request #17855 from poettering/more-socktops
socket-util: some helpers for various sockopts
Diffstat (limited to 'src')
-rw-r--r--src/basic/missing_socket.h8
-rw-r--r--src/basic/socket-util.c32
-rw-r--r--src/basic/socket-util.h19
3 files changed, 59 insertions, 0 deletions
diff --git a/src/basic/missing_socket.h b/src/basic/missing_socket.h
index 17bc1a5a01..30ac297e17 100644
--- a/src/basic/missing_socket.h
+++ b/src/basic/missing_socket.h
@@ -67,6 +67,14 @@ struct sockaddr_vm {
#define IPV6_FREEBIND 78
#endif
+#ifndef IP_RECVFRAGSIZE
+#define IP_RECVFRAGSIZE 25
+#endif
+
+#ifndef IPV6_RECVFRAGSIZE
+#define IPV6_RECVFRAGSIZE 77
+#endif
+
/* linux/sockios.h */
#ifndef SIOCGSKNS
#define SIOCGSKNS 0x894C
diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c
index 1e53ac4e86..59039bea4f 100644
--- a/src/basic/socket-util.c
+++ b/src/basic/socket-util.c
@@ -1314,3 +1314,35 @@ int socket_set_option(int fd, int af, int opt_ipv4, int opt_ipv6, int val) {
return -EAFNOSUPPORT;
}
}
+
+int socket_get_mtu(int fd, int af, size_t *ret) {
+ int mtu, r;
+
+ if (af == AF_UNSPEC) {
+ r = socket_get_family(fd, &af);
+ if (r < 0)
+ return r;
+ }
+
+ switch (af) {
+
+ case AF_INET:
+ r = getsockopt_int(fd, IPPROTO_IP, IP_MTU, &mtu);
+ break;
+
+ case AF_INET6:
+ r = getsockopt_int(fd, IPPROTO_IPV6, IPV6_MTU, &mtu);
+ break;
+
+ default:
+ return -EAFNOSUPPORT;
+ }
+
+ if (r < 0)
+ return r;
+ if (mtu <= 0)
+ return -EINVAL;
+
+ *ret = (size_t) mtu;
+ return 0;
+}
diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h
index e353f82a42..240d209c14 100644
--- a/src/basic/socket-util.h
+++ b/src/basic/socket-util.h
@@ -258,6 +258,19 @@ static inline int setsockopt_int(int fd, int level, int optname, int value) {
return 0;
}
+static inline int getsockopt_int(int fd, int level, int optname, int *ret) {
+ int v;
+ socklen_t sl = sizeof(v);
+
+ if (getsockopt(fd, level, optname, &v, &sl) < 0)
+ return -errno;
+ if (sl != sizeof(v))
+ return -EIO;
+
+ *ret = v;
+ return 0;
+}
+
int socket_bind_to_ifname(int fd, const char *ifname);
int socket_bind_to_ifindex(int fd, int ifindex);
@@ -266,6 +279,7 @@ ssize_t recvmsg_safe(int sockfd, struct msghdr *msg, int flags);
int socket_get_family(int fd, int *ret);
int socket_set_recvpktinfo(int fd, int af, bool b);
int socket_set_unicast_if(int fd, int af, int ifi);
+
int socket_set_option(int fd, int af, int opt_ipv4, int opt_ipv6, int val);
static inline int socket_set_recverr(int fd, int af, bool b) {
return socket_set_option(fd, af, IP_RECVERR, IPV6_RECVERR, b);
@@ -282,3 +296,8 @@ static inline int socket_set_freebind(int fd, int af, bool b) {
static inline int socket_set_transparent(int fd, int af, bool b) {
return socket_set_option(fd, af, IP_TRANSPARENT, IPV6_TRANSPARENT, b);
}
+static inline int socket_set_recvfragsize(int fd, int af, bool b) {
+ return socket_set_option(fd, af, IP_RECVFRAGSIZE, IPV6_RECVFRAGSIZE, b);
+}
+
+int socket_get_mtu(int fd, int af, size_t *ret);