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.
This commit is contained in:
Willy Tarreau 2020-08-28 15:40:33 +02:00
parent c5a94c936b
commit 25140cc573
4 changed files with 62 additions and 60 deletions

View File

@ -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 */

View File

@ -117,6 +117,7 @@
#include <haproxy/server.h>
#include <haproxy/session.h>
#include <haproxy/signal.h>
#include <haproxy/sock_inet.h>
#include <haproxy/ssl_sock.h>
#include <haproxy/stream.h>
#include <haproxy/task.h>
@ -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

View File

@ -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 <family>.
*/
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.
*/

View File

@ -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 <family>.
*/
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;
}