#include "IPInterception.h"
#include "SquidTime.h"
+
#if IPF_TRANSPARENT
+
#if HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#elif HAVE_NETINET_IP_NAT_H
#include <netinet/ip_nat.h>
#endif
-#endif
+
+#endif /* IPF_TRANSPARENT required headers */
#if PF_TRANSPARENT
#include <sys/types.h>
#include <net/if.h>
#include <netinet/in.h>
#include <net/pfvar.h>
-#endif
+#endif /* PF_TRANSPARENT required headers */
#if LINUX_NETFILTER
#include <linux/netfilter_ipv4.h>
#endif
+#if LINUX_TPROXY2
+#ifdef HAVE_LINUX_NETFILTER_IPV4_IP_TPROXY_H
+#include <linux/netfilter_ipv4/ip_tproxy.h>
+#else
+#error " TPROXY v2 Header file missing: linux/netfilter_ipv4/ip_tproxy.h. Perhapse you meant to use TPROXY v4 ? "
+#endif
+#endif
+
// single global instance for access by other components.
IPIntercept IPInterceptor;
#endif
}
+
+#if LINUX_TPROXY2
+IPIntercept::SetTproxy2OutgoingAddr(int fd, const IPAddress &src)
+{
+ IPAddress addr;
+ struct in_tproxy itp;
+
+ src.GetInAddr(itp.v.addr.faddr);
+ itp.v.addr.fport = 0;
+
+ /* If these syscalls fail then we just fallback to connecting
+ * normally by simply ignoring the errors...
+ */
+ itp.op = TPROXY_ASSIGN;
+
+ addr = (struct in_addr)itp.v.addr.faddr;
+ addr.SetPort(itp.v.addr.fport);
+
+ if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp, sizeof(itp)) == -1) {
+ debugs(20, 1, "tproxy ip=" << addr << " ERROR ASSIGN");
+ return -1;
+ } else {
+ itp.op = TPROXY_FLAGS;
+ itp.v.flags = ITP_CONNECT;
+
+ if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp, sizeof(itp)) == -1) {
+ debugs(20, 1, "tproxy ip=" << addr << " ERROR CONNECT");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+#endif
{
public:
int NatLookup(int fd, const IPAddress &me, const IPAddress &peer, IPAddress &dst);
+
+#if LINUX_TPROXY2
+ // only relevant to TPROXY v2 connections.
+ // which require the address be set specifically post-connect.
+ int SetTproxy2OutgoingAddr(int fd, const IPAddress &src);
+#endif
}
#if !defined(IP_TRANSPARENT)
#include "SquidTime.h"
#include "Store.h"
-#if LINUX_TPROXY2
-#ifdef HAVE_LINUX_NETFILTER_IPV4_IP_TPROXY_H
-#include <linux/netfilter_ipv4/ip_tproxy.h>
-#else
-#error " TPROXY v2 Header file missing: linux/netfilter_ipv4/ip_tproxy.h. Perhapse you meant to use TPROXY v4 ? "
-#endif
-#endif
+/* for IPInterceptor API */
+#include "IPInterception.h"
static PSC fwdStartCompleteWrapper;
static PF fwdServerClosedWrapper;
const char *domain = NULL;
int ctimeout;
int ftimeout = Config.Timeout.forward - (squid_curtime - start_t);
-#if LINUX_TPROXY2
-
- struct in_tproxy itp;
-#endif
IPAddress outgoing;
unsigned short tos;
#if LINUX_TPROXY2
if (request->flags.tproxy) {
- IPAddress addr;
-
- src.GetInAddr(itp.v.addr.faddr);
- itp.v.addr.fport = 0;
-
- /* If these syscalls fail then we just fallback to connecting
- * normally by simply ignoring the errors...
- */
- itp.op = TPROXY_ASSIGN;
-
- addr = (struct in_addr)itp.v.addr.faddr;
- addr.SetPort(itp.v.addr.fport);
-
- if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp, sizeof(itp)) == -1) {
- debugs(20, 1, "tproxy ip=" << addr << " ERROR ASSIGN");
-
+ // try to set the outgoing address using TPROXY v2
+ // if it fails we abort any further TPROXY actions on this connection
+ if(IPInterceptor.SetTPROXY2OutgoingAddr(int fd, const IPAddress &src) == -1) {
request->flags.tproxy = 0;
- } else {
- itp.op = TPROXY_FLAGS;
- itp.v.flags = ITP_CONNECT;
-
- if (setsockopt(fd, SOL_IP, IP_TPROXY, &itp, sizeof(itp)) == -1) {
- debugs(20, 1, "tproxy ip=" << addr << " ERROR CONNECT");
-
- request->flags.tproxy = 0;
- }
}
}
-
#endif
+
hierarchyNote(&request->hier, fs->code, request->GetHost());
}