]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Shuffle PF interception into its own function.
authorAmos Jeffries <squid3@treenet.co.nz>
Sat, 21 Mar 2009 00:57:14 +0000 (13:57 +1300)
committerAmos Jeffries <squid3@treenet.co.nz>
Sat, 21 Mar 2009 00:57:14 +0000 (13:57 +1300)
With this all of the transparent build options are independent, and may be
used in any combination. Squid is no longer bound to the single-firewall
interception support.

NP: one small note the PF lookup is slightly weird due to its altering
the local client address from the NAT information.

src/ip/IpIntercept.cc
src/ip/IpIntercept.h

index 57d0d282ceed55a683440bdfd38373efe8e294b7..39d8787bf632f4651d327144b53969cdc063340e 100644 (file)
@@ -294,73 +294,31 @@ IpIntercept::IpfInterception(int fd, const IpAddress &me, IpAddress &dst, int si
     return -1;
 }
 
-
 int
-IpIntercept::NatLookup(int fd, const IpAddress &me, const IpAddress &peer, IpAddress &client, IpAddress &dst)
+IpIntercept::PfInterception(int fd, IpAddress &client, IpAddress &dst, int silent)
 {
-  /* --enable-linux-netfilter    */
-  /* --enable-ipfw-transparent   */
-  /* --enable-ipf-transparent    */
-#if IPF_TRANSPARENT || LINUX_NETFILTER || IPFW_TRANSPARENT
-
-    /* Netfilter and IPFW share almost identical lookup methods for their NAT tables.
-     * This allows us to perform a nice clean failover sequence for them.
-     */
-
-    client = me;
-    dst = peer;
-
-    if ( !me.IsIPv4()   ) return -1;
-    if ( !peer.IsIPv4() ) return -1;
-
-#if 0
-    // Crop interception errors down to one per minute.
-    int silent = (squid_curtime - last_reported > 60 ? 0 : 1);
-#else
-    // Show all interception errors.
-    int silent = 0;
-#endif
-
-    if (intercept_active) {
-        if ( IpfInterception(fd, me, client, silent) == 0) return 0;
-        if ( NetfilterInterception(fd, me, client, silent) == 0) return 0;
-        if ( IpfwInterception(fd, me, client, silent) == 0) return 0;
-    }
-    if (transparent_active) {
-        if ( NetfilterTransparent(fd, me, dst, silent) == 0) return 0;
-    }
-
-    return -1;
-
-#elif PF_TRANSPARENT  /* --enable-pf-transparent */
+#if PF_TRANSPARENT  /* --enable-pf-transparent */
 
     struct pfioc_natlook nl;
     static int pffd = -1;
 
-    if ( !me.IsIPv4() ) return -1;
-    if ( !peer.IsIPv4() ) return -1;
-
     if (pffd < 0)
         pffd = open("/dev/pf", O_RDONLY);
 
     if (pffd < 0) {
-        if (squid_curtime - last_reported > 60) {
-            debugs(89, 1, "clientNatLookup: PF open failed: " << xstrerror());
+        if (!silent) {
+            debugs(89, 1, HERE << "PF open failed: " << xstrerror());
             last_reported = squid_curtime;
         }
-
         return -1;
-
     }
 
-    client.SetEmpty();
-
     memset(&nl, 0, sizeof(struct pfioc_natlook));
-    peer.GetInAddr(nl.saddr.v4);
-    nl.sport = htons(peer.GetPort());
+    dst.GetInAddr(nl.saddr.v4);
+    nl.sport = htons(dst.GetPort());
 
-    me.GetInAddr(nl.daddr.v4);
-    nl.dport = htons(me.GetPort());
+    client.GetInAddr(nl.daddr.v4);
+    nl.dport = htons(client.GetPort());
 
     nl.af = AF_INET;
     nl.proto = IPPROTO_TCP;
@@ -368,35 +326,71 @@ IpIntercept::NatLookup(int fd, const IpAddress &me, const IpAddress &peer, IpAdd
 
     if (ioctl(pffd, DIOCNATLOOK, &nl)) {
         if (errno != ENOENT) {
-            if (squid_curtime - last_reported > 60) {
+            if (!silent) {
                 debugs(89, 1, "clientNatLookup: PF lookup failed: ioctl(DIOCNATLOOK)");
                 last_reported = squid_curtime;
             }
-
             close(pffd);
             pffd = -1;
         }
-
-        return -1;
     } else {
-        int natted = (me != nl.rdaddr.v4);
+        int natted = (client != nl.rdaddr.v4);
         client = nl.rdaddr.v4;
         client.SetPort(ntohs(nl.rdport));
 
         if (natted)
             return 0;
-        else
-            return -1;
     }
 
+    debugs(89, 9, HERE << "address: client= " << client << ", dst= " << dst);
 
-#else /* none of the transparent options configured */
-
-    debugs(89, 1, "WARNING: transparent proxying not supported");
+#endif /* --enable-pf-transparent */
     return -1;
+}
+
+
+int
+IpIntercept::NatLookup(int fd, const IpAddress &me, const IpAddress &peer, IpAddress &client, IpAddress &dst)
+{
+  /* --enable-linux-netfilter    */
+  /* --enable-ipfw-transparent   */
+  /* --enable-ipf-transparent    */
+  /* --enable-pf-transparent     */
+#if IPF_TRANSPARENT || LINUX_NETFILTER || IPFW_TRANSPARENT || PF_TRANSPARENT
+
+    /* Netfilter and IPFW share almost identical lookup methods for their NAT tables.
+     * This allows us to perform a nice clean failover sequence for them.
+     */
+
+    client = me;
+    dst = peer;
+
+    if ( !me.IsIPv4()   ) return -1;
+    if ( !peer.IsIPv4() ) return -1;
+
+#if 0
+    // Crop interception errors down to one per minute.
+    int silent = (squid_curtime - last_reported > 60 ? 0 : 1);
+#else
+    // Show all interception errors.
+    int silent = 0;
+#endif
+
+    if (intercept_active) {
+        if ( IpfInterception(fd, me, client, silent) == 0) return 0;
+        if ( NetfilterInterception(fd, me, client, silent) == 0) return 0;
+        if ( IpfwInterception(fd, me, client, silent) == 0) return 0;
+        if ( PfInterception(fd, client, dst, silent) == 0) return 0;
+    }
+    if (transparent_active) {
+        if ( NetfilterTransparent(fd, me, dst, silent) == 0) return 0;
+    }
 
+#else /* none of the transparent options configured */
+    debugs(89, 1, "WARNING: transparent proxying not supported");
 #endif
 
+    return -1;
 }
 
 #if LINUX_TPROXY2
index 2ee72b8c799de4dfeac15905d904c2a103cbae4b..dc5b8bbe6207185d62fc405ea8ecb57a644a9729 100644 (file)
@@ -116,6 +116,15 @@ private:
      */
     int IpfInterception(int fd, const IpAddress &me, IpAddress &client, int silent);
 
+    /**
+     * perform Lookups on PF interception.
+     *
+     \param silent[in]   0 if errors are to be displayed. 1 if errors are to be hidden.
+     \retval 0     Successfuly located the new address.
+     \retval -1    An error occured during NAT lookups.
+     */
+    int PfInterception(int fd, IpAddress &client, IpAddress &client, int silent);
+
 
     int transparent_active;
     int intercept_active;