From 25140cc5733a67173421681cfe5b8b010ea6891d Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Fri, 28 Aug 2020 15:40:33 +0200 Subject: [PATCH] REORG: inet: replace tcp_is_foreign() with sock_inet_is_foreign() The function now makes it clear that it's independent on the socket type and solely relies on the address family. Note that it supports both IPv4 and IPv6 as we don't seem to need it per-family. --- include/haproxy/sock_inet.h | 1 + src/haproxy.c | 3 +- src/proto_tcp.c | 59 ------------------------------------- src/sock_inet.c | 59 +++++++++++++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 60 deletions(-) diff --git a/include/haproxy/sock_inet.h b/include/haproxy/sock_inet.h index 8b1de095a..48b23b3fd 100644 --- a/include/haproxy/sock_inet.h +++ b/include/haproxy/sock_inet.h @@ -30,5 +30,6 @@ int sock_inet4_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_storage *b); int sock_inet6_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_storage *b); int sock_inet_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir); +int sock_inet_is_foreign(int fd, sa_family_t family); #endif /* _HAPROXY_SOCK_INET_H */ diff --git a/src/haproxy.c b/src/haproxy.c index 03a05cdd4..3744547d2 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -117,6 +117,7 @@ #include #include #include +#include #include #include #include @@ -1306,7 +1307,7 @@ static int get_old_sockets(const char *unixsocket) curoff += sizeof(int); /* determine the foreign status directly from the socket itself */ - if (tcp_is_foreign(fd, xfer_sock->addr.ss_family)) + if (sock_inet_is_foreign(fd, xfer_sock->addr.ss_family)) xfer_sock->options |= LI_O_FOREIGN; /* keep only the v6only flag depending on what's currently diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 675c686ee..fba60834b 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -581,65 +581,6 @@ int tcp_connect_server(struct connection *conn, int flags) return SF_ERR_NONE; /* connection is OK */ } -/* Returns true if the passed FD corresponds to a socket bound with LI_O_FOREIGN - * according to the various supported socket options. The socket's address family - * must be passed in . - */ -int tcp_is_foreign(int fd, sa_family_t family) -{ - int val __maybe_unused; - socklen_t len __maybe_unused; - - switch (family) { - case AF_INET: -#if defined(IP_TRANSPARENT) - val = 0; len = sizeof(val); - if (getsockopt(fd, SOL_IP, IP_TRANSPARENT, &val, &len) == 0 && val) - return 1; -#endif -#if defined(IP_FREEBIND) - val = 0; len = sizeof(val); - if (getsockopt(fd, SOL_IP, IP_FREEBIND, &val, &len) == 0 && val) - return 1; -#endif -#if defined(IP_BINDANY) - val = 0; len = sizeof(val); - if (getsockopt(fd, IPPROTO_IP, IP_BINDANY, &val, &len) == 0 && val) - return 1; -#endif -#if defined(SO_BINDANY) - val = 0; len = sizeof(val); - if (getsockopt(fd, SOL_SOCKET, SO_BINDANY, &val, &len) == 0 && val) - return 1; -#endif - break; - - case AF_INET6: -#if defined(IPV6_TRANSPARENT) && defined(SOL_IPV6) - val = 0; len = sizeof(val); - if (getsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &val, &len) == 0 && val) - return 1; -#endif -#if defined(IP_FREEBIND) - val = 0; len = sizeof(val); - if (getsockopt(fd, SOL_IP, IP_FREEBIND, &val, &len) == 0 && val) - return 1; -#endif -#if defined(IPV6_BINDANY) - val = 0; len = sizeof(val); - if (getsockopt(fd, IPPROTO_IPV6, IPV6_BINDANY, &val, &len) == 0 && val) - return 1; -#endif -#if defined(SO_BINDANY) - val = 0; len = sizeof(val); - if (getsockopt(fd, SOL_SOCKET, SO_BINDANY, &val, &len) == 0 && val) - return 1; -#endif - break; - } - return 0; -} - /* sets the v6only_default flag according to the OS' default settings; for * simplicity it's set to zero if not supported. */ diff --git a/src/sock_inet.c b/src/sock_inet.c index b82a920ad..db1a8c00e 100644 --- a/src/sock_inet.c +++ b/src/sock_inet.c @@ -106,3 +106,62 @@ int sock_inet_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir) return ret; } } + +/* Returns true if the passed FD corresponds to a socket bound with LI_O_FOREIGN + * according to the various supported socket options. The socket's address family + * must be passed in . + */ +int sock_inet_is_foreign(int fd, sa_family_t family) +{ + int val __maybe_unused; + socklen_t len __maybe_unused; + + switch (family) { + case AF_INET: +#if defined(IP_TRANSPARENT) + val = 0; len = sizeof(val); + if (getsockopt(fd, SOL_IP, IP_TRANSPARENT, &val, &len) == 0 && val) + return 1; +#endif +#if defined(IP_FREEBIND) + val = 0; len = sizeof(val); + if (getsockopt(fd, SOL_IP, IP_FREEBIND, &val, &len) == 0 && val) + return 1; +#endif +#if defined(IP_BINDANY) + val = 0; len = sizeof(val); + if (getsockopt(fd, IPPROTO_IP, IP_BINDANY, &val, &len) == 0 && val) + return 1; +#endif +#if defined(SO_BINDANY) + val = 0; len = sizeof(val); + if (getsockopt(fd, SOL_SOCKET, SO_BINDANY, &val, &len) == 0 && val) + return 1; +#endif + break; + + case AF_INET6: +#if defined(IPV6_TRANSPARENT) && defined(SOL_IPV6) + val = 0; len = sizeof(val); + if (getsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &val, &len) == 0 && val) + return 1; +#endif +#if defined(IP_FREEBIND) + val = 0; len = sizeof(val); + if (getsockopt(fd, SOL_IP, IP_FREEBIND, &val, &len) == 0 && val) + return 1; +#endif +#if defined(IPV6_BINDANY) + val = 0; len = sizeof(val); + if (getsockopt(fd, IPPROTO_IPV6, IPV6_BINDANY, &val, &len) == 0 && val) + return 1; +#endif +#if defined(SO_BINDANY) + val = 0; len = sizeof(val); + if (getsockopt(fd, SOL_SOCKET, SO_BINDANY, &val, &len) == 0 && val) + return 1; +#endif + break; + } + return 0; +}