Transparent proxy in 2.1.x kernels

Savochkin Andrey Vladimirovich (saw@msu.ru)
Wed, 22 Apr 1998 16:34:46 +0400


--zYM0uCDKw75PZbzx
Content-Type: text/plain; charset=us-ascii

David,

I've track down the problem with transparent proxy in the latest kernels.
The reason for Oops is the missing bind bucket for the newly created
TCP socks because the listening socket has a different local port.
Patch fixing the problem is attached.

The patch contains also two unrelated one-line changes.
The first change concerns backlog counter modifications.
I think the modification should be done after creating of a new sock
safely against any creation failures (see the patch). Am I right?

The second change is for SOCK_DEBUG macro:
the former variant gives not what you could expect for a code like
if (result)
SOCK_DEBUG(result, ...);
else
...

Best wishes
Andrey

--zYM0uCDKw75PZbzx
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="proxy-2.1.x.patch"

--- ../linux.orig/net/ipv4/tcp_ipv4.c Fri Apr 17 10:34:51 1998
+++ net/ipv4/tcp_ipv4.c Wed Apr 22 15:16:07 1998
@@ -168,6 +168,18 @@
return tb;
}

+/* Ensure that the bound bucket for the port exists.
+ * Return 0 on success.
+ */
+static __inline__ int tcp_bucket_check(unsigned short snum)
+{
+ if (tcp_bound_hash[tcp_bhashfn(snum)] == NULL &&
+ tcp_bucket_create(snum) == NULL)
+ return 1;
+ else
+ return 0;
+}
+
static int tcp_v4_verify_bind(struct sock *sk, unsigned short snum)
{
struct tcp_bind_bucket *tb;
@@ -1278,9 +1290,16 @@
return NULL;
dst = &rt->u.dst;
}
-
- sk->tp_pinfo.af_tcp.syn_backlog--;
- sk->ack_backlog++;
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+ /* The new socket created for transparent proxy may fall
+ * into a non-existed bind bucket because sk->num != newsk->num.
+ * Ensure existance of the bucket now. The placement of the check
+ * later will require to destroy just created newsk in the case of fail.
+ * 1998/04/22 Andrey V. Savochkin <saw@msu.ru>
+ */
+ if (tcp_bucket_check(ntohs(skb->h.th->dest)))
+ goto exit;
+#endif

mtu = dst->pmtu;
if (mtu < 68)
@@ -1290,6 +1315,9 @@
newsk = tcp_create_openreq_child(sk, req, skb, snd_mss);
if (!newsk)
goto exit;
+
+ sk->tp_pinfo.af_tcp.syn_backlog--;
+ sk->ack_backlog++;

newsk->dst_cache = dst;

--- ../linux.orig/include/net/sock.h Sat Apr 11 21:42:18 1998
+++ include/net/sock.h Wed Apr 22 15:22:02 1998
@@ -323,7 +323,7 @@
/* Define this to get the sk->debug debugging facility. */
#define SOCK_DEBUGGING
#ifdef SOCK_DEBUGGING
-#define SOCK_DEBUG(sk, msg...) if((sk) && ((sk)->debug)) printk(KERN_DEBUG ## msg)
+#define SOCK_DEBUG(sk, msg...) do { if((sk) && ((sk)->debug)) printk(KERN_DEBUG ## msg); } while (0)
#else
#define SOCK_DEBUG(sk, msg...) do { } while (0)
#endif

--zYM0uCDKw75PZbzx--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu