Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I can verify that the connection is up:

$ netstat -tn | grep "192.168.2.110"
tcp  0  0 192.168.2.100:10444  192.168.2.110:52639  ESTABLISHED

is there a way to check how long this tcp port connection was up (connected)?

(No, I don't have access to app logs)

share|improve this question

You can try the following:

  1. get the PID (say $pid) of the program by adding the -p option to netstat.

  2. identify the proper line in the /proc/net/tcp file by looking at the local_address and/or rem_address fields (note that they are in hex format, specifically the IP address is expressed in little-endian byte order), also make sure that the st is 01 (for ESTABLISHED);

  3. note the associated inode field (say $inode);

  4. search for that inode among the file descriptors in /proc/$pid/fd and finally query the file access time of the symbolic link:

    find /proc/$pid/fd -lname "socket:\[$inode\]" -printf %t
    

That is a grunt work... here's a script (stub) to automatize the above points, it requires the remote address and it prints the socket uptime in seconds:

function suptime() {
    local addr=${1:?Specify the remote IPv4 address}
    local port=${2:?Specify the remote port number}
    # convert the provided address to hex format
    local hex_addr=$(python -c "import socket, struct; print(hex(struct.unpack('<L', socket.inet_aton('$addr'))[0])[2:10].upper().zfill(8))")
    local hex_port=$(python -c "print(hex($port)[2:].upper().zfill(4))")
    # get the PID of the owner process
    local pid=$(netstat -ntp 2>/dev/null | awk '$6 == "ESTABLISHED" && $5 == "'$addr:$port'"{sub("/.*", "", $7); print $7}')
    [ -z "$pid" ] && { echo 'Address does not match' 2>&1; return 1; }
    # get the inode of the socket
    local inode=$(awk '$4 == "01" && $3 == "'$hex_addr:$hex_port'" {print $10}' /proc/net/tcp)
    [ -z "$inode" ] && { echo 'Cannot lookup the socket' 2>&1; return 1; }
    # query the inode status change time
    local timestamp=$(find /proc/$pid/fd -lname "socket:\[$inode\]" -printf %T@)
    [ -z "$timestamp" ] && { echo 'Cannot fetch the timestamp' 2>&1; return 1; }
    # compute the time difference
    LANG=C printf '%s (%.2fs ago)\n' "$(date -d @$timestamp)" $(bc <<<"$(date +%s.%N) - $timestamp")
}

(Edit thanks to Alex for the fixes)

Example:

$ suptime 93.184.216.34 80
Thu Dec 24 16:22:58 CET 2015 (46.12s ago)
share|improve this answer
    
This recipe displays age of process that created TCP connection, not connection itself. – myroslav Dec 24 '15 at 13:17
    
@myroslav are you sure? It works against this Node.js script. – cYrus Dec 24 '15 at 15:33
    
I'd tested your new script with TCP connections opened by my Firefox on Fedora 22 64-bit, and I'm getting definitely not "uptime" numbers. When new socket opens, it is getting "random" uptime, usually the time of "youngest" ESTABLISHED socket. – myroslav Dec 25 '15 at 23:23
    
@myroslav I'm using Debian (3.16.0-4-amd64) here, the only thing I notice is that the time reported is actually about 3 seconds late with respect to the socket creation. Maybe there are some system-dependent behaviors involved... – cYrus Dec 26 '15 at 11:21

The script by cYrus worked for me but i had to fix it a bit (to get rid of a "L" in the hex address and to make port a 4 digit hex):

--- suptime.orig    2015-08-20 15:46:12.896652464 +0200
+++ suptime 2015-08-20 15:47:48.560074728 +0200
@@ -7,8 +7,8 @@
     hex_addr=$(python -c "
 import socket, struct;
 print hex(struct.unpack('<L',
-socket.inet_aton('$addr'))[0])[2:].upper().zfill(8)")
-    hex_port=$(python -c "print hex($port)[2:].upper()")
+socket.inet_aton('$addr'))[0])[2:10].upper().zfill(8)")
+    hex_port=$(python -c "print hex($port)[2:].upper().zfill(4)")
     inode=$(awk '$3 == "'$hex_addr:$hex_port'" {print $10}' /proc/net/tcp)
     time=$(find /proc/$pid/fd -lname "socket:\[$inode\]" -printf %A@)
     LANG=C printf '%.2fs' $(bc <<<"$(date +%s.%N) - $time")
share|improve this answer

This questions was helpful to me, but I found using lsof instead of netstat let me avoid all the HEX stuff:

For a process ${APP} run by user ${USER}, the following returns all the open sockets to the IP address ${IP}:

PEEID=$(sudo pgrep -u ${USER} ${APP}) && for i in `sudo lsof -anP -i -u logstash | grep ${IP} | awk '{print $6}'` ; do echo "${device} time" ; sudo find /proc/${PEEID}/fd -lname "socket:\[${device}\]" -printf %t 2> /dev/null  ; echo  ;  done

The lsof contains the PID too, but I am not sure how to get it and the device number.

This was tested on Amazon Linux.

share|improve this answer

I haven’t seen netstat give that information. A combination of netstat and ps commands should be helpful.

  • Get pid of the socket with netstat.
$ sudo netstat -plan | grep "198.252.206.25"

tcp        0      0 192.168.0.14:41558      198.252.206.25:80       ESTABLISHED 2679/chromium-brows
  • Check process details with ps.
$ sudo ps -eo uid,pid,etime | grep 2679

UID   PID     ELAPSED
1000  2679       44:31

The third value here is the total time the socket has been running.

To understand ps output better I am pasting the headings.

$  sudo ps -eo uid,pid,etime | head

UID   PID     ELAPSED
0     1       52:37
share|improve this answer
1  
if you do this on the sever side, this will give you how long the server was running. I am interested in how long the connection is up. Say the server started last month but the client connected only 2 days ago. In this case, on the server I get "one month" but I am looking for "2 days". – hidralisk Mar 14 '13 at 23:12
    
This will in fact tell you how long the connection is up. I think only detailed logging will be able to tell how long the client was connected to the socket. This is definitely a lead. – paintbox Mar 15 '13 at 6:31
    
This will give you how much time the process has been up, not the socket. – fons Dec 9 '15 at 19:58

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.