mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-21 20:00:17 +00:00
MINOR: sock_inet: move the IPv4/v6 transparent mode code to sock_inet
This code was highly redundant, existing for TCP clients, TCP servers and UDP servers. Let's move it to sock_inet where it belongs. The new functions are sock_inet4_make_foreign() and sock_inet6_make_foreign().
This commit is contained in:
parent
2d34a710b1
commit
37bafdcbb1
@ -35,5 +35,7 @@ int sock_inet4_addrcmp(const struct sockaddr_storage *a, const struct sockaddr_s
|
|||||||
int sock_inet6_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_get_dst(int fd, struct sockaddr *sa, socklen_t salen, int dir);
|
||||||
int sock_inet_is_foreign(int fd, sa_family_t family);
|
int sock_inet_is_foreign(int fd, sa_family_t family);
|
||||||
|
int sock_inet4_make_foreign(int fd);
|
||||||
|
int sock_inet6_make_foreign(int fd);
|
||||||
|
|
||||||
#endif /* _HAPROXY_SOCK_INET_H */
|
#endif /* _HAPROXY_SOCK_INET_H */
|
||||||
|
@ -129,20 +129,7 @@ int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct so
|
|||||||
* multiple combinations of certain methods, so we try the
|
* multiple combinations of certain methods, so we try the
|
||||||
* supported ones until one succeeds.
|
* supported ones until one succeeds.
|
||||||
*/
|
*/
|
||||||
if (0
|
if (sock_inet4_make_foreign(fd))
|
||||||
#if defined(IP_TRANSPARENT)
|
|
||||||
|| (setsockopt(fd, SOL_IP, IP_TRANSPARENT, &one, sizeof(one)) == 0)
|
|
||||||
#endif
|
|
||||||
#if defined(IP_FREEBIND)
|
|
||||||
|| (setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == 0)
|
|
||||||
#endif
|
|
||||||
#if defined(IP_BINDANY)
|
|
||||||
|| (setsockopt(fd, IPPROTO_IP, IP_BINDANY, &one, sizeof(one)) == 0)
|
|
||||||
#endif
|
|
||||||
#if defined(SO_BINDANY)
|
|
||||||
|| (setsockopt(fd, SOL_SOCKET, SO_BINDANY, &one, sizeof(one)) == 0)
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
foreign_ok = 1;
|
foreign_ok = 1;
|
||||||
else
|
else
|
||||||
ip_transp_working = 0;
|
ip_transp_working = 0;
|
||||||
@ -150,20 +137,7 @@ int tcp_bind_socket(int fd, int flags, struct sockaddr_storage *local, struct so
|
|||||||
break;
|
break;
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
if (flags && ip6_transp_working) {
|
if (flags && ip6_transp_working) {
|
||||||
if (0
|
if (sock_inet6_make_foreign(fd))
|
||||||
#if defined(IPV6_TRANSPARENT) && defined(SOL_IPV6)
|
|
||||||
|| (setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &one, sizeof(one)) == 0)
|
|
||||||
#endif
|
|
||||||
#if defined(IP_FREEBIND)
|
|
||||||
|| (setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == 0)
|
|
||||||
#endif
|
|
||||||
#if defined(IPV6_BINDANY)
|
|
||||||
|| (setsockopt(fd, IPPROTO_IPV6, IPV6_BINDANY, &one, sizeof(one)) == 0)
|
|
||||||
#endif
|
|
||||||
#if defined(SO_BINDANY)
|
|
||||||
|| (setsockopt(fd, SOL_SOCKET, SO_BINDANY, &one, sizeof(one)) == 0)
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
foreign_ok = 1;
|
foreign_ok = 1;
|
||||||
else
|
else
|
||||||
ip6_transp_working = 0;
|
ip6_transp_working = 0;
|
||||||
@ -664,39 +638,13 @@ int tcp_bind_listener(struct listener *listener, char *errmsg, int errlen)
|
|||||||
if (!ext && (listener->options & LI_O_FOREIGN)) {
|
if (!ext && (listener->options & LI_O_FOREIGN)) {
|
||||||
switch (listener->addr.ss_family) {
|
switch (listener->addr.ss_family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
if (1
|
if (!sock_inet4_make_foreign(fd)) {
|
||||||
#if defined(IP_TRANSPARENT)
|
|
||||||
&& (setsockopt(fd, SOL_IP, IP_TRANSPARENT, &one, sizeof(one)) == -1)
|
|
||||||
#endif
|
|
||||||
#if defined(IP_FREEBIND)
|
|
||||||
&& (setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == -1)
|
|
||||||
#endif
|
|
||||||
#if defined(IP_BINDANY)
|
|
||||||
&& (setsockopt(fd, IPPROTO_IP, IP_BINDANY, &one, sizeof(one)) == -1)
|
|
||||||
#endif
|
|
||||||
#if defined(SO_BINDANY)
|
|
||||||
&& (setsockopt(fd, SOL_SOCKET, SO_BINDANY, &one, sizeof(one)) == -1)
|
|
||||||
#endif
|
|
||||||
) {
|
|
||||||
msg = "cannot make listening socket transparent";
|
msg = "cannot make listening socket transparent";
|
||||||
err |= ERR_ALERT;
|
err |= ERR_ALERT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
if (1
|
if (!sock_inet6_make_foreign(fd)) {
|
||||||
#if defined(IPV6_TRANSPARENT) && defined(SOL_IPV6)
|
|
||||||
&& (setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &one, sizeof(one)) == -1)
|
|
||||||
#endif
|
|
||||||
#if defined(IP_FREEBIND)
|
|
||||||
&& (setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == -1)
|
|
||||||
#endif
|
|
||||||
#if defined(IPV6_BINDANY)
|
|
||||||
&& (setsockopt(fd, IPPROTO_IPV6, IPV6_BINDANY, &one, sizeof(one)) == -1)
|
|
||||||
#endif
|
|
||||||
#if defined(SO_BINDANY)
|
|
||||||
&& (setsockopt(fd, SOL_SOCKET, SO_BINDANY, &one, sizeof(one)) == -1)
|
|
||||||
#endif
|
|
||||||
) {
|
|
||||||
msg = "cannot make listening socket transparent";
|
msg = "cannot make listening socket transparent";
|
||||||
err |= ERR_ALERT;
|
err |= ERR_ALERT;
|
||||||
}
|
}
|
||||||
@ -920,27 +868,6 @@ int tcp_pause_listener(struct listener *l)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
REGISTER_BUILD_OPTS("Built with transparent proxy support using:"
|
|
||||||
#if defined(IP_TRANSPARENT)
|
|
||||||
" IP_TRANSPARENT"
|
|
||||||
#endif
|
|
||||||
#if defined(IPV6_TRANSPARENT)
|
|
||||||
" IPV6_TRANSPARENT"
|
|
||||||
#endif
|
|
||||||
#if defined(IP_FREEBIND)
|
|
||||||
" IP_FREEBIND"
|
|
||||||
#endif
|
|
||||||
#if defined(IP_BINDANY)
|
|
||||||
" IP_BINDANY"
|
|
||||||
#endif
|
|
||||||
#if defined(IPV6_BINDANY)
|
|
||||||
" IPV6_BINDANY"
|
|
||||||
#endif
|
|
||||||
#if defined(SO_BINDANY)
|
|
||||||
" SO_BINDANY"
|
|
||||||
#endif
|
|
||||||
"");
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Local variables:
|
* Local variables:
|
||||||
|
@ -241,39 +241,13 @@ int udp_bind_listener(struct listener *listener, char *errmsg, int errlen)
|
|||||||
if (listener->options & LI_O_FOREIGN) {
|
if (listener->options & LI_O_FOREIGN) {
|
||||||
switch (addr_inet.ss_family) {
|
switch (addr_inet.ss_family) {
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
if (1
|
if (!sock_inet4_make_foreign(fd)) {
|
||||||
#if defined(IP_TRANSPARENT)
|
|
||||||
&& (setsockopt(fd, SOL_IP, IP_TRANSPARENT, &one, sizeof(one)) == -1)
|
|
||||||
#endif
|
|
||||||
#if defined(IP_FREEBIND)
|
|
||||||
&& (setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == -1)
|
|
||||||
#endif
|
|
||||||
#if defined(IP_BINDANY)
|
|
||||||
&& (setsockopt(fd, IPPROTO_IP, IP_BINDANY, &one, sizeof(one)) == -1)
|
|
||||||
#endif
|
|
||||||
#if defined(SO_BINDANY)
|
|
||||||
&& (setsockopt(fd, SOL_SOCKET, SO_BINDANY, &one, sizeof(one)) == -1)
|
|
||||||
#endif
|
|
||||||
) {
|
|
||||||
msg = "cannot make listening socket transparent";
|
msg = "cannot make listening socket transparent";
|
||||||
err |= ERR_ALERT;
|
err |= ERR_ALERT;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
if (1
|
if (!sock_inet6_make_foreign(fd)) {
|
||||||
#if defined(IPV6_TRANSPARENT) && defined(SOL_IPV6)
|
|
||||||
&& (setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &one, sizeof(one)) == -1)
|
|
||||||
#endif
|
|
||||||
#if defined(IP_FREEBIND)
|
|
||||||
&& (setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == -1)
|
|
||||||
#endif
|
|
||||||
#if defined(IPV6_BINDANY)
|
|
||||||
&& (setsockopt(fd, IPPROTO_IPV6, IPV6_BINDANY, &one, sizeof(one)) == -1)
|
|
||||||
#endif
|
|
||||||
#if defined(SO_BINDANY)
|
|
||||||
&& (setsockopt(fd, SOL_SOCKET, SO_BINDANY, &one, sizeof(one)) == -1)
|
|
||||||
#endif
|
|
||||||
) {
|
|
||||||
msg = "cannot make listening socket transparent";
|
msg = "cannot make listening socket transparent";
|
||||||
err |= ERR_ALERT;
|
err |= ERR_ALERT;
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
|
||||||
#include <haproxy/api.h>
|
#include <haproxy/api.h>
|
||||||
|
#include <haproxy/global.h>
|
||||||
#include <haproxy/sock_inet.h>
|
#include <haproxy/sock_inet.h>
|
||||||
#include <haproxy/tools.h>
|
#include <haproxy/tools.h>
|
||||||
|
|
||||||
@ -174,6 +175,52 @@ int sock_inet_is_foreign(int fd, sa_family_t family)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Attempt all known socket options to prepare an AF_INET4 socket to be bound
|
||||||
|
* to a foreign address. The socket must already exist and must not be bound.
|
||||||
|
* 1 is returned on success, 0 on failure. The caller must check the address
|
||||||
|
* family before calling this function.
|
||||||
|
*/
|
||||||
|
int sock_inet4_make_foreign(int fd)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
#if defined(IP_TRANSPARENT)
|
||||||
|
setsockopt(fd, SOL_IP, IP_TRANSPARENT, &one, sizeof(one)) == 0 ||
|
||||||
|
#endif
|
||||||
|
#if defined(IP_FREEBIND)
|
||||||
|
setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == 0 ||
|
||||||
|
#endif
|
||||||
|
#if defined(IP_BINDANY)
|
||||||
|
setsockopt(fd, IPPROTO_IP, IP_BINDANY, &one, sizeof(one)) == 0 ||
|
||||||
|
#endif
|
||||||
|
#if defined(SO_BINDANY)
|
||||||
|
setsockopt(fd, SOL_SOCKET, SO_BINDANY, &one, sizeof(one)) == 0 ||
|
||||||
|
#endif
|
||||||
|
0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attempt all known socket options to prepare an AF_INET6 socket to be bound
|
||||||
|
* to a foreign address. The socket must already exist and must not be bound.
|
||||||
|
* 1 is returned on success, 0 on failure. The caller must check the address
|
||||||
|
* family before calling this function.
|
||||||
|
*/
|
||||||
|
int sock_inet6_make_foreign(int fd)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
#if defined(IPV6_TRANSPARENT) && defined(SOL_IPV6)
|
||||||
|
setsockopt(fd, SOL_IPV6, IPV6_TRANSPARENT, &one, sizeof(one)) == 0 ||
|
||||||
|
#endif
|
||||||
|
#if defined(IP_FREEBIND)
|
||||||
|
setsockopt(fd, SOL_IP, IP_FREEBIND, &one, sizeof(one)) == 0 ||
|
||||||
|
#endif
|
||||||
|
#if defined(IPV6_BINDANY)
|
||||||
|
setsockopt(fd, IPPROTO_IPV6, IPV6_BINDANY, &one, sizeof(one)) == 0 ||
|
||||||
|
#endif
|
||||||
|
#if defined(SO_BINDANY)
|
||||||
|
setsockopt(fd, SOL_SOCKET, SO_BINDANY, &one, sizeof(one)) == 0 ||
|
||||||
|
#endif
|
||||||
|
0;
|
||||||
|
}
|
||||||
|
|
||||||
static void sock_inet_prepare()
|
static void sock_inet_prepare()
|
||||||
{
|
{
|
||||||
int fd, val;
|
int fd, val;
|
||||||
@ -210,3 +257,25 @@ static void sock_inet_prepare()
|
|||||||
}
|
}
|
||||||
|
|
||||||
INITCALL0(STG_PREPARE, sock_inet_prepare);
|
INITCALL0(STG_PREPARE, sock_inet_prepare);
|
||||||
|
|
||||||
|
|
||||||
|
REGISTER_BUILD_OPTS("Built with transparent proxy support using:"
|
||||||
|
#if defined(IP_TRANSPARENT)
|
||||||
|
" IP_TRANSPARENT"
|
||||||
|
#endif
|
||||||
|
#if defined(IPV6_TRANSPARENT)
|
||||||
|
" IPV6_TRANSPARENT"
|
||||||
|
#endif
|
||||||
|
#if defined(IP_FREEBIND)
|
||||||
|
" IP_FREEBIND"
|
||||||
|
#endif
|
||||||
|
#if defined(IP_BINDANY)
|
||||||
|
" IP_BINDANY"
|
||||||
|
#endif
|
||||||
|
#if defined(IPV6_BINDANY)
|
||||||
|
" IPV6_BINDANY"
|
||||||
|
#endif
|
||||||
|
#if defined(SO_BINDANY)
|
||||||
|
" SO_BINDANY"
|
||||||
|
#endif
|
||||||
|
"");
|
||||||
|
Loading…
Reference in New Issue
Block a user