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; +}