Hi, Sorry to disturb you again with my transparent proxy efforts, but finally after my third complete reorganization, things seem to work fine, without _any_ core TCP changes.
I have a couple of problems though, which all involve core TCP code patches, and so I would like some advice on the preferred way. 1. notification about destroyed sockets I definitely need a notification when a socket is closed. Possible solutions: a) create a notifier in inet_sock_release() function, where my tproxy module registers itself. b) call a netfilter specific function when CONFIG_NETFILTER is defined in a way similar to how setsockopts are delegated to netfilter. I like the second option a bit more, as putting notifiers here and there is IMHO ugly. Other parts in netfilter might need such a feature too, as netfilter modules might assign state to sockets (through setsockopt/getsockopt) which needs to be freed when the socket is closed. 2. receiving rewritten original address for datagram based protocols (UDP) As looking up a table when a packet is received is not atomic (the way it needs to be done when using simple NAT), I was thinking about attaching the original address information to the packet itself, which can be queried via an aux message with recvmsg(). As it is not possible to hook into aux message processing, I did this with a patch to ip_sockglue.c. The important parts of my patch is at the end of this message. I tried to be as general as possible, and made the NAT framework to save original addresses in IPCB(skb), which is returned in an IP_ORIGADDRS auxillary message when recvmsg() is called on a socket with IP_RECVORIGADDRS setsockopt enabled. Is this solution ok for you? 3. specifying outgoing source address for datagram based protocols (UDP) A similar problem applies to sending as well. To be atomic, I need to specify the outgoing source address at sendmsg() time using an aux message. The problem is again that it is difficult to hook into aux message processing, and the skb is not created until ip_build_xmit() time, therefore the skb cannot be used to store this information unless ip_build_xmit() itself is patched. Any idea to resolve this issue? And now my current patch against ip_sockglue.c diff -urN --exclude-from kernel-exclude linux-2.4.18-vanilla/net/ipv4/ip_sockglue.c linux-2.4.18-cttproxy/net/ipv4/ip_sockglue.c --- linux-2.4.18-vanilla/net/ipv4/ip_sockglue.c Wed Oct 31 00:08:12 2001 +++ linux-2.4.18-cttproxy/net/ipv4/ip_sockglue.c Fri May 24 02:44:44 2002@@ +-48,6 +48,7 @@ #define IP_CMSG_TOS 4 #define IP_CMSG_RECVOPTS 8 #define IP_CMSG_RETOPTS 16 +#define IP_CMSG_ORIGADDRS 32 /* * SOL_IP control messages. @@ -107,6 +108,20 @@ put_cmsg(msg, SOL_IP, IP_RETOPTS, opt->optlen, opt->__data); } +#if defined(CONFIG_IP_NF_NAT_NEEDED) + +void ip_cmsg_recv_origaddrs(struct msghdr *msg, struct sk_buff *skb) +{ + struct in_origaddrs ioa; + + ioa.ioa_srcaddr.s_addr = IPCB(skb)->orig_srcaddr; + ioa.ioa_srcport = IPCB(skb)->orig_srcport; + ioa.ioa_dstaddr.s_addr = IPCB(skb)->orig_dstaddr; + ioa.ioa_dstport = IPCB(skb)->orig_dstport; + put_cmsg(msg, SOL_IP, IP_ORIGADDRS, sizeof(ioa), &ioa); +} + +#endif void ip_cmsg_recv(struct msghdr *msg, struct sk_buff *skb) { @@ -135,6 +150,12 @@ if (flags & 1) ip_cmsg_recv_retopts(msg, skb); + if ((flags>>=1) == 0) + return; +#if defined(CONFIG_IP_NF_NAT_NEEDED) + if (flags & 1) + ip_cmsg_recv_origaddrs(msg, skb); +#endif } int ip_cmsg_send(struct msghdr *msg, struct ipcm_cookie *ipc) @@ -167,6 +188,19 @@ ipc->addr = info->ipi_spec_dst.s_addr; break; } +#if defined(CONFIG_IP_NF_NAT_NEEDED) + case IP_ORIGADDRS: + { + struct in_origaddrs *ioa; + + if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct in_origaddrs))) + return -EINVAL; + ioa = (struct in_origaddrs *) CMSG_DATA(cmsg); + + /* FIXME: where to store addresses so NAT might pick it up? */ + break; + } +#endif default: return -EINVAL; } -- Bazsi PGP info: KeyID 9AF8D0A9 Fingerprint CD27 CFB0 802C 0944 9CFD 804E C82C 8EB1