简体   繁体   中英

Quitting client on localhost, without disconnecting a TCP connection to server on localhost (without FIN packet)

Original Question

I am connecting to a node.js TCP server (on localhost) with telnet and I am trying to explore keep-alive probes.

As a first test, I would like to connect to the server with telnet and kill the telnet session in a way that does not send a FIN packet. (Letting the server think the TCP socket is still 'healthy'.) Unfortunately I can't seem to find a clever way of testing this.

  • When I quit telnet from the telnet prompt, the socket's end event fires in node. It clearly got a FIN packet.
  • When I kill telnet's process, it also cleanly quits the connection with a FIN packet, before the process dies.

Do you know of a way to quit telnet without sending a FIN packet (preferably not involving a network cable that's disconnected / producing a physical networking fault.)

Improved question

I want to simulate a network fault using just localhost / loopback (without actually disconnecting any interfaces / network cables). I want to open a TCP connection between a client and a server, both on localhost. Then I want the client to "die" without letting the server know that it's gone. (Ie without sending a FIN packet.) This could happen in a real network, if a router goes down, for example.

Thanks to the comments below, I've learned that the kernel will collect any open ports/sockets owned by a process when the process dies (or is forcefully killed), like my telnet above, and will close them for the process by sending a FIN packet. So I need to trick the kernel into not closing an existing connection.

So how can I create a client process, keep it alive, but let it behave like a completely dead TCP connection?

Spoilers

  • (Answer 1 below: Use a raw socket (scapy), let it ignore any packets sent by the server after the initial connection & some test data. (After a certain time, for example.))
  • (Answer 2, Idea from colleague: configure iptables to cut off traffic between client and server. Actual iptables rule in comment below.)

Do you have to kill the client process? If so, just use netcat and let the processes run in the background. In bash:

for i in $(seq 5) do nc localhost 5001 &; sleep 1; done

This creates 5 TCP clients, with SYNs spaced 1 second. If you need to interact with one of the sessions, you can use

fg $PID

to return one of the netcat's back to the shell foreground.

Another option is an iptables rule:

iptables -A OUTPUT -p tcp --tcp-flags FIN -j DROP

Yet another option is to use a low level networking tool with raw sockets, such as Scapy. Here's the Python Documentation for Scapy . You'll be doing something similar to TCP SYN scanning, except you need to ACK the SYN-ACK that the server gives you. This will leave the server socket in a "connected" state and you can go on and do other things. The server may ACK you occasionally, but your test program won't care. It will only send SYNs and respond to SYN-ACKs

You need to disconnect the machine from the network. "Disconnecting" a process will always cause the OS/machine to properly close the socket.

The easiest way to disconnect the machine without physically unplugging the cable is simply to change the machine's IP address.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM