patch-2.1.88 linux/net/ipv4/udp.c
Next file: linux/net/ipv6/Config.in
Previous file: linux/net/ipv4/tcp_ipv4.c
Back to the patch index
Back to the overall index
- Lines: 100
- Date:
Thu Feb 19 14:46:16 1998
- Orig file:
v2.1.87/linux/net/ipv4/udp.c
- Orig date:
Thu Feb 12 20:56:14 1998
diff -u --recursive --new-file v2.1.87/linux/net/ipv4/udp.c linux/net/ipv4/udp.c
@@ -55,6 +55,7 @@
* Olaf Kirch : Don't linearise iovec on sendmsg.
* Andi Kleen : Some cleanups, cache destination entry
* for connect.
+ * Vitaly E. Lavrov : Transparent proxy revived after year coma.
*
*
* This program is free software; you can redistribute it and/or
@@ -360,14 +361,14 @@
#ifdef CONFIG_IP_TRANSPARENT_PROXY
#define secondlist(hpnum, sk, fpass) \
({ struct sock *s1; if(!(sk) && (fpass)--) \
- s1 = udp_hash[(hpnum) & (TCP_HTABLE_SIZE - 1)]; \
+ s1 = udp_hash[(hpnum) & (UDP_HTABLE_SIZE - 1)]; \
else \
s1 = (sk); \
s1; \
})
#define udp_v4_proxy_loop_init(hnum, hpnum, sk, fpass) \
- secondlist((hpnum), udp_hash[(hnum)&(TCP_HTABLE_SIZE-1)],(fpass))
+ secondlist((hpnum), udp_hash[(hnum)&(UDP_HTABLE_SIZE-1)],(fpass))
#define udp_v4_proxy_loop_next(hnum, hpnum, sk, fpass) \
secondlist((hpnum),(sk)->next,(fpass))
@@ -641,8 +642,15 @@
if (msg->msg_flags&MSG_OOB) /* Mirror BSD error message compatibility */
return -EOPNOTSUPP;
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+ if (msg->msg_flags&~(MSG_DONTROUTE|MSG_DONTWAIT|MSG_PROXY))
+ return -EINVAL;
+ if ((msg->msg_flags&MSG_PROXY) && !suser() )
+ return -EPERM;
+#else
if (msg->msg_flags&~(MSG_DONTROUTE|MSG_DONTWAIT))
return -EINVAL;
+#endif
/*
* Get and verify the address.
@@ -685,8 +693,27 @@
*/
rt = (struct rtable *)dst_check(&sk->dst_cache, 0);
}
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+ if (msg->msg_flags&MSG_PROXY) {
+ /*
+ * We map the first 8 bytes of a second sockaddr_in
+ * into the last 8 (unused) bytes of a sockaddr_in.
+ */
+ struct sockaddr_in *from = (struct sockaddr_in *)msg->msg_name;
+ from = (struct sockaddr_in *)&from->sin_zero;
+ if (from->sin_family != AF_INET)
+ return -EINVAL;
+ ipc.addr = from->sin_addr.s_addr;
+ ufh.uh.source = from->sin_port;
+ if (ipc.addr == 0)
+ ipc.addr = sk->saddr;
+ } else
+#endif
+ {
+ ipc.addr = sk->saddr;
+ ufh.uh.source = sk->dummy_th.source;
+ }
- ipc.addr = sk->saddr;
ipc.opt = NULL;
ipc.oif = sk->bound_dev_if;
if (msg->msg_controllen) {
@@ -710,7 +737,7 @@
tos = RT_TOS(sk->ip_tos);
if (sk->localroute || (msg->msg_flags&MSG_DONTROUTE) ||
(ipc.opt && ipc.opt->is_strictroute)) {
- tos |= 1;
+ tos |= RTO_ONLINK;
rt = NULL; /* sorry */
}
@@ -722,7 +749,11 @@
}
if (rt == NULL) {
- err = ip_route_output(&rt, daddr, ufh.saddr, tos, ipc.oif);
+ err = ip_route_output(&rt, daddr, ufh.saddr,
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+ (msg->msg_flags&MSG_PROXY ? RTO_TPROXY : 0) |
+#endif
+ tos, ipc.oif);
if (err)
goto out;
localroute = 1;
@@ -735,7 +766,6 @@
ufh.saddr = rt->rt_src;
if (!ipc.addr)
ufh.daddr = ipc.addr = rt->rt_dst;
- ufh.uh.source = sk->dummy_th.source;
ufh.uh.len = htons(ulen);
ufh.uh.check = 0;
ufh.other = (htons(ulen) << 16) + IPPROTO_UDP*256;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov