11 December 2015

Close and kill TCP sockets on Linux (and Windows)

Sometimes it can be good to test how a program will behave if a TCP socket/connection that the program has created is closed.

For Windows it can easily be done by using Microsoft Windows Sysinternals program TCPView by right clicking on a TCP connection and choose "Close Connection". I'm not sure how it is implemented but by using Wireshark capture while closing a TCP connection you can see that a RST TCP segment is sent to the from your host to the remote side.

But with Linux it is a bit tricker. Here is a script I created that can do it:

#!/bin/bash

#Syntax: ./killtcp.sh 5328 10.10.14.41 14001
#                     PID  IP          PORT

pid=$1
ip=$2
port=$3

file_descriptors=`lsof -Pnp $pid`

echo "$file_descriptors" |grep TCP | grep $ip:$port | while read file_descriptor
do
    handle=`echo $file_descriptor | cut -f4 -d' '`
    handle=${handle/[a-z]/}
    echo "call close($handle)" > gdb_debugger.txt
    sudo gdb -p $pid -batch -x gdb_debugger.txt
done


It uses lsof to find out the internal file descriptor handle(s) of the application. Then it writes gdb close commands to a file (file was the only way I could get it into gdb). Then it uses gdb to connect to the PID of the program with the TCP connection and forces a close on the file handle(s).

This is not the cleanest way to do it. It might crash your application!? But I have used it successfully on ssh and some java programs I wrote and it worked okay.