I have a caching application that runs in userspace and provides acceleration services to clients running on external hosts elsewhere in the network. Briefly put, my program watches network traffic and does deep packet inspection to generate accelerated replies to some client requests.
For reasons that are long and boring, I wanted to add some NAT functionality. As a proof of concept, I was hoping to put a front end on my application using iptables/netfilter. Mostly, it works great. I can NAT successfully, and I can forward traffic to my application using NFQUEUEs, allowing it to read them and do packet inspection.
However, when my cache attempts to generate a response back to the client, I have difficulty. I'm trying to feed internally generated response packets to the network via a raw socket so that they are sent back to the client. I find that the packets' TCP source port is being changed. The packet I hand to the raw socket has source port = 2049 (NFS), but what actually comes out has source port = 1024.
Upon further analysis, I suspect that my generated packets are running afoul of netfilter's connection tracking and NAT code. Netfilter thinks they are not part of the connection that I'm injecting them into, but they have the same tuple as that connection. So it thinks it's seeing a collision and does port forwarding. This is obviously a problem, as they're supposed to look to the client like they belong to the same connection.
Is there a good way to just skip the final NAT steps for some packets? Failing that, is there a way to programmatically tell netfilter that my packets belong to particular client connection, even though they come from a raw socket rather than the network?