1

I am reading how the TCP states work and especially the connection termination part.

All of the books or online material I read, shows that for the termination procedure these states are followed from the side initiated (active) the connection termination:

ESTABLISHED, FIN-WAIT-1, FIN-WAIT-2, TIME-WAIT, CLOSED

And these from the receiving (passive) side:

ESTABLISHED, CLOSE-WAIT, LAST-ACK, CLOSED

Now here comes the question: I have modprobed the nf_conntrack_ipv4 module to both sides to check the connection states in /proc/net/ip_conntrack.

To my surprise, when the connection is terminated, both the initiator (active) and the receiver (passive) goes to the TIME-WAIT state.

I would expect only the initiator to go through this state, and the receiver just close the connection.

Can someone explain why this is happening?

UPDATE: How do I perform this test

I have a virtual machine with IP 10.0.0.1 (Ubuntu 12.04) and I start two ssh connections to 10.0.0.2 (Debian 6) from it (10.0.0.2 is a VM as well). I check the ip_conntrack of both ends and this is what I get.

root@machine1:~# cat /proc/net/ip_conntrack | grep 10.0.0.1
tcp      6 431997 ESTABLISHED src=10.0.0.1 dst=10.0.0.2 sport=53925 dport=22 src=10.0.0.2 dst=10.0.0.1 sport=22 dport=53925 [ASSURED] mark=0 use=2
tcp      6 431944 ESTABLISHED src=10.0.0.1 dst=10.0.0.2 sport=53924 dport=22 src=10.0.0.2 dst=10.0.0.1 sport=22 dport=53924 [ASSURED] mark=0 use=2

root@machine2:~# cat /proc/net/ip_conntrack | grep 10.0.0.1
tcp      6 432000 ESTABLISHED src=10.0.0.1 dst=10.0.0.2 sport=53925 dport=22 packets=206 bytes=19191 src=10.0.0.2 dst=10.0.0.1 sport=22 dport=53925 packets=130 bytes=18177 [ASSURED] mark=0 secmark=0 use=2
tcp      6 431947 ESTABLISHED src=10.0.0.1 dst=10.0.0.2 sport=53924 dport=22 packets=16 bytes=4031 src=10.0.0.2 dst=10.0.0.1 sport=22 dport=53924 packets=17 bytes=3741 [ASSURED] mark=0 secmark=0 use=2

So far everything looks fine. Now I disconnect one of the ssh connections from machine2 and this is what I get:

root@machine1:~# cat /proc/net/ip_conntrack | grep 10.0.0.1
tcp      6 431989 ESTABLISHED src=10.0.0.1 dst=10.0.0.2 sport=53925 dport=22 src=10.0.0.2 dst=10.0.0.1 sport=22 dport=53925 [ASSURED] mark=0 use=2
tcp      6 117 TIME_WAIT src=10.0.0.1 dst=10.0.0.2 sport=53924 dport=22 src=10.0.0.2 dst=10.0.0.1 sport=22 dport=53924 [ASSURED] mark=0 use=2

root@machine2:~# cat /proc/net/ip_conntrack | grep 10.0.0.1
tcp      6 432000 ESTABLISHED src=10.0.0.1 dst=10.0.0.2 sport=53925 dport=22 packets=211 bytes=19547 src=10.0.0.2 dst=10.0.0.1 sport=22 dport=53925 packets=133 bytes=18925 [ASSURED] mark=0 secmark=0 use=2
tcp      6 115 TIME_WAIT src=10.0.0.1 dst=10.0.0.2 sport=53924 dport=22 packets=31 bytes=5147 src=10.0.0.2 dst=10.0.0.1 sport=22 dport=53924 packets=25 bytes=4589 [ASSURED] mark=0 secmark=0 use=2
2
  • Are you sure that you are seeing both the ends going into TIME_WAIT state ? Because I can see in my tests, that the end which first sends the FIN, only goes to TIME_WAIT state. Can you explain us how you are testing this thing ? Mar 10, 2013 at 17:51
  • Just added an example of how do I perform the test. Mar 10, 2013 at 19:06

2 Answers 2

2

The Linux TCP stack and conntrack have two different visions of the TCP connection. What you're seeing in /proc/net/ip_conntrack is different from what the kernel sees. The kernel state is stored in /proc/net/tcp and /proc/net/tcp6 and can be displayed with netstat.

As seen here: https://serverfault.com/questions/313061/netstat-and-ip-conntrack-connection-count-differ-by-order-of-magnitude-why both counts differ. I presume that if you look at netstat's output you will only see one end in TIME-WAIT

1
  • I guess that's the right answer :) Thank you! It works as expected if I check the states with "netstat -nat" Mar 12, 2013 at 17:51
0

This is to prevent a new connection getting stale segments still floating around in the 'net from the old connection messing it up.

3
  • I read this, but the question is about why I see the TIME-WAIT state to both ends. This state should only be there in the node initiated the connection termination and not the other one (according to what I read so far). Mar 10, 2013 at 15:41
  • TCP connections have data flowing in both directions.
    – vonbrand
    Mar 10, 2013 at 15:49
  • According to this en.wikipedia.org/wiki/File:TCP_CLOSE.svg one end will initiate the termination (active end) of a connection and only this will go through the TIME-WAIT state. The passive end should just close it. The same is what I see in different books as well. Do I miss something here? Mar 10, 2013 at 15:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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