tcpip - How do I prevent Linux kernel from responding to incoming TCP packets?

06
2014-04
  • Jon

    For my application, I need to intercept certain TCP/IP packets and route them to a different device over a custom communications link (not Ethernet). I need all the TCP control packets and the full headers. I have figured out how to obtain these using a raw socket using socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP). This works well and allows me to attach filters to just see the TCP port I'm interested in.

    However, Linux also sees these packets. By default, it sends a RST when it receives a packet to a port number it doesn't know about. That's no good as I plan to send back a response myself later. If I open up a second "normal" socket on that same port using socket(PF_INET, SOCK_STREAM, 0) and listen() on it, Linux then sends ACK to incoming TCP packets. Neither of these options is what I want. I want it to do nothing with these packets so I can handle everything myself. How can I accomplish this?

  • Answers
  • artistoex

    iptables

    You can drop those packets at the OUTPUT chain of the FILTER table.

    The protocol

    RFC 793 (TCP) specifies the RST-sending behavior

    SEGMENT ARRIVES
    
      If the state is CLOSED (i.e., TCB does not exist) then [...]:
      An incoming segment not containing a RST causes a RST to be sent in response. 
    

    And linux obiviously implements it correctly.

    The sysctl interface

    It seems the behaviour is also not tweakable through the sysctl interface (see tcp(7)). In any event, that man page is definitely a good read if you haven't already come across it yet.

    Kernel code

    Depending on what you actually want to acheive, altering the kernel code directly might be an option.


  • Related Question

    Linux Kernel Packet Forwarding Performance
  • Bob Somers

    I've been using a Linux box as a router for some time now. Nothing too fancy, just enabling forwarding in the kernel, turning on masquerading, and setting up iptables to poke a few holes in the firewall.

    Recently a friend of mine pointed out a performance problem. Single TCP connections seem to experience very poor performance. You have to open multiple parallel TCP connections to get decent speed.

    For example, I have a 10 Mbit internet connection. When I download a file from a known-fast source using something like the DownThemAll! extension for Firefox (which opens multiple parallel TCP connections) I can get it to max out my downstream bandwidth at around 1 MB/s. However, when I download the same file using the built-in download manager in Firefox (uses only a single TCP connection) it starts fast and the speed tanks until it tops out around 100 KB/s to 350 KB/s.

    I've checked the internal network and it doesn't seem to have any problems. Everything goes through a 100 Mbit switch. I've also run iperf both internally (from the router to my desktop) and externally (from my desktop to a Linux box I own out on the net) and haven't seen any problems. It tops out around 1 MB/s like it should. Speedtest.net also reports 10 Mbits speeds.

    The load on the Linux machine is around 0.00, 0.00, 0.00 all the time, and it's got plenty of free RAM. It's an older laptop with a Pentium M 1.6 GHz processor and 1 GB of RAM. The internal network is connected to the built in Intel NIC and the cable modem is connected to a Netgear FA511 32-bit PCMCIA network card.

    I think the problem is with the packet forwarding in the router, but I honestly am not sure where the problem could be. Is there anything that would substantially slow down a single TCP stream?


  • Related Answers
  • Bob Somers

    The problem has been fixed. There was some sort of hardware issue (still no idea what) on the machine. After installing the same Linux distro and reconfiguring the firewall and packet forwarding the same way on a different machine, I'm no longer having the problem.

    Strange.

  • David Spillett

    This is most likely a per-stream performance issue at either the remote end or your ISP - each individual stream is being throttled, either deliberately (by your ISP) or just due to congestion (at the remote site, at your ISP, or anywhere in between).

    It is unlikely to be a fault at your end.

    As an example of how this works when the issue is congestion, imagine a web server with a 10000Kbyte/sec connection and no other limits/bottlenecks. If there are 100 active connections downloading large objects they'll each (ignoring variances caused by latency and congestion differences between each client and the server) get around 100Kbyte/sec on average. If you opened five connections instead of one, you would get something more like 480Kbyte/sec (10000/104*5) while each single stream gets something along the lines of 95Kbyte/sec (10000/104*1). Of course in this example you are the only one using multiple connections, which is unlikely to be the case in real life. And also this math only works if the traffic management under congestion results in a fair average rate given to each stream, again in real life there are many factors that will cause this to vary, and the traffic management may impose some per host limits on top of any explicit or implied per stream ones.