Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
How to close a running process's socket (incoherency.co.uk)
60 points by jstanley on April 9, 2015 | hide | past | favorite | 17 comments


This technique also works for reopening stdout to a log file for a long-running service which was started w/ >/dev/null.


Please expand on this a little.


Sure! after gdbing,

  call creat("/path/to/where/you/want/log")
  $1 = 3
  call dup2(3,1)
  $2 = 1
  call close(3)
  $3 = 0
Then start tailing /path/to/where/you/want/log


This is clever.


(Edit: Doh! Scooped by falsedan. His is shorter and probably more readable. :) In my defense, I tried it to make sure this works.)

What I found via SO [0] was in the context of routing things to dev/null instead of stdout, but you appear to be able to route to whatever you need to:

  ;; Setup: A bash scropt printed 'wat' every second, 
  ;;        redirected to /dev/null

  ;; Attach to the process in question using gdb:
  gknoy$ sudo gdb 15488

  ;; Use '1' as the open flag, for write-only
  (gdb) p dup2(open("/tmp/wat.log",1),1)
  $1 = 1
  (gdb) detach
  Detaching from program: /bin/bash, process 15488
  (gdb) quit

  gknoy$ cat /tmp/wat.log
  wat
  wat
  wat

0: http://stackoverflow.com/questions/593724/redirect-stderr-st...


A shutdown(O_RDWR) is safer, and AFAIK, reliably interrupts any blocking calls on the socket. Calling close is risky because another thread might just then decide to read or write to that file descriptor, which might be a completely different thing just opened.


I always thought that it would be quicker to use tcp_keepalive_time = <set timframe> in the header or oin your Perl program in order to not keep connection request open for an unrecognized timeperiod. Dont even have to use your shell to manually close the connection.


Doesn't help for something already running.


I thought this article was going to be about the blocking recv() with a closed socket "issue" in linux, but it wasn't.

For those that don't know, linux behaves differently than other unix in that a thread blocked in recv() will remain blocked in recv if another thread closes the underlying socket.

AKA, the article works because GDB is interrupting the recv() call (or the socket was marked nonblocking), not because simply closing a socket wakes up a blocked recv() in linux.


Yes exactly, and if I remember correctly (my C language memory is starting to fade these days), there is even a flag to reuse the same socket when the program open again (SO_REUSEADDR ?).


I always wondered why there is no standard unix tool to accomplish this.

Also useful would be a tool to close a TCP connection, regardless of the processes that have handles to it.


BSD's have tcpdrop(8):

     If	a connection to	httpd(8) is causing congestion on a network link, one
     can drop the TCP session in charge:

	   # sockstat -c | grep	httpd
	   www	    httpd      16525 3	tcp4 \
		   192.168.5.41:80	192.168.5.1:26747

     The following command will	drop the connection:

	   # tcpdrop 192.168.5.41 80 192.168.5.1 26747


You can achieve this for TCP by faking an RST (reset) packet that purports to be from the other end of the connection.

[EDIT]

These tools are a reasonable starting point.

http://linuxpoison.blogspot.co.uk/2008/10/tools-for-creating...


This sort of does what you want. But there must be some traffic even if it just keep alive.

  sudo tcpkill -9 -i eth0 host 1.2.3.4 and port 80
It is part of dsniff.


I've had much better luck with killcx:

http://killcx.sourceforge.net/

In particular, it sends a spoofed SYN packet to induce an ACK packet containing the sequence numbers necessary to send the RST. That means it doesn't rely on there being traffic already.


what about tcpkill (8) ?


That requires traffic on the socket to exist.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: