From 0d8da5846251b66eebfbc36fc665b5967c2ed89a Mon Sep 17 00:00:00 2001 From: Dustin Lundquist Date: Mon, 17 Dec 2018 19:25:27 -0800 Subject: [PATCH] transparent proxy: use IP_BINDANY where available --- src/connection.c | 19 ++++++++++++++++--- src/listener.c | 2 +- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/connection.c b/src/connection.c index c10a1090..fcc0e64e 100644 --- a/src/connection.c +++ b/src/connection.c @@ -630,16 +630,29 @@ initiate_server_connect(struct Connection *con, struct ev_loop *loop) { if (con->listener->transparent_proxy && con->client.addr.ss_family == con->server.addr.ss_family) { -#ifdef IP_TRANSPARENT +#if defined(IP_TRANSPARENT) int on = 1; int result = setsockopt(sockfd, SOL_IP, IP_TRANSPARENT, &on, sizeof(on)); +#elif defined(IP_BINDANY) && defined(IPV6_BINDANY) + int on = 1; + int result = -EINVAL; + switch(con->server.addr.ss_family) { + case AF_INET: + result = setsockopt(sockfd, IPPROTO_IP, IP_BINDANY, &on, sizeof(on)); + break; + case AF_INET6: + result = setsockopt(sockfd, IPPROTO_IPV6, IPV6_BINDANY, &on, sizeof(on)); + break; + default: + err("unsupported address family %d does not support transparent mode", con->server.addr.ss_family); + } #else - int result = -EPERM; + int result = -EINVAL; /* XXX error: not implemented would be better, but this shouldn't be * reached since it is prohibited in the configuration parser. */ #endif if (result < 0) { - err("setsockopt IP_TRANSPARENT failed: %s", strerror(errno)); + err("setsockopt IP_TRANSPARENT/BINDANY failed: %s", strerror(errno)); close(sockfd); abort_connection(con); return; diff --git a/src/listener.c b/src/listener.c index ce5956da..6e0748b5 100644 --- a/src/listener.c +++ b/src/listener.c @@ -376,7 +376,7 @@ accept_listener_source_address(struct Listener *listener, const char *source) { } if (strcasecmp("client", source) == 0) { -#ifdef IP_TRANSPARENT +#if defined(IP_TRANSPARENT) || defined(IP_BINDANY) && defined(IPV6_BINDANY) listener->transparent_proxy = 1; return 1; #else