How TCP TIME-WAIT Assassination works

How TCP TIME-WAIT Assassination works

  • Comments 1
  • Likes

Can a port be re-used before TIME-WAIT expires?

In a TCP conversation, the communicating peers use port numbers to communicate with each other. The way they uniquely identify the sessions is with a four tuple (Source IP address, Source Port, Destination IP address, Destination Port). The four tuple represents a unique socket over which full duplex communication works between the communicating peers.

From connection initiation to connection closure the socket transitions through different states. They are: LISTENING, SYN-SEND, SYN-RECEIVED, ESTABLISHED, FIN-WAIT1, FIN-WAIT2, LAST-ACK, CLOSING, CLOSED, TIME-WAIT, and CLOSE-WAIT.

All these socket states and their transitions are explained in the socket state diagram available on page 22 of RFC793: http://www.faqs.org/rfcs/rfc793.html

image

In the socket communication, the peer who initiates the FIN transitions through FIN-WAIT1, FIN-WAIT2 and TIME-WAIT. Once the socket is in TIME-WAIT, it waits for 2MSL (http://msdn.microsoft.com/en-us/library/ms819739.aspx). When the socket is in TIME-WAIT state, the socket is not used.

In a situation where the server side socket goes to a TIME-WAIT state and the client reconnects to the server within 2MSL (default TIME-WAIT time), there are 2 things that can happen:

  1. The server will not respond to the SYN packets from the client because the socket is in the TIME-WAIT state.
  2. The server may accept the SYN from the client and change the state of the socket from TIME-WAIT to ESTABLISHED. This is known as TIME-WAIT assassination, or incarnation of a previous connection.

The key to scenario ‘2’ above is that the ISN (Initial Sequence number) of the SYN sent needs to be higher than the highest sequence number used in the previous session. If the ISN is not as expected, the server will not respond to the SYN and the socket will wait for 2MSL before being available for use again.

Microsoft’s TCP/IP implementation employs this functionality. This feature allows the use of the available socket more quickly and increases performance. This is explained in RFC 1122 - Requirements for Internet Hosts - Communication Layers on Page 87: http://tools.ietf.org/html/rfc1122#page-87

Here’s a snippet from the RFC:

clip_image001

TCP TIME-WAIT Assassination works very well between Windows systems and may not work as expected when Windows is communicating with hosts running other TCP/IP implementations. RFC1337, Hazards of TIME-WAIT Assassination, discusses possible pitfalls: http://tools.ietf.org/rfc/rfc1337.txt

To demonstrate how TCP TIME-WAIT Assassination works, I used a tool on a Windows 7 system that always uses the same source port to connect to an IIS server running Windows server 2003 Standard Edition with Service Pack 2. I used Network Monitor to capture a network trace of this behavior. It is worth noting that the TCPTimedWaitDelay registry entry has not been changed from its default.

In the below trace:

  • F-no= Frame no
  • C = Client
  • S= Server
  • SRC= Source
  • DEST= Destination
  • SEQ-no= Sequence Number
  • ACK-NO= Acknowledgement number

image

  • The highlighted frames above show the source port 55000 and destination port 80 being re-used.
  • The client reconnects to the same server within 664ms and the server accepts the connection.
  • All Sequence numbers in the SYN packets are higher than the previous sequence number.
  • Since the server initiated a closure, the server side socket goes into the TIME-WAIT state.
  • If the TIME-WAIT Assassination was not working then the server would not accept the connection within such a short period.

With this article I have tried to explain how TCP TIME-WAIT assassination is implemented in Windows and how it is useful in situations where an application requires re-using the same source port immediately after it has been gracefully closed. If you have any questions on this or related to this then please feel free to post it and I will try to answer it.

- Kapil Thacker

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • [Don't know if my previous anonymous comment is being modded, so here we go again.]

    Your definition and example of "TIME_WAIT assassination" (TWA) is wrong -- basically the opposite of the real meaning. TWA is defined in RFC 1337, Section 1:

    TIME-WAIT state can be

      prematurely terminated ("assassinated") by an old duplicate data or

      ACK segment from the current or an earlier incarnation of the same

      connection.  We refer to this as "TIME-WAIT Assassination" (TWA).

    TWA thus refers to the disruption of the normal 2*MSL wait state so that a connection is _not reopenable_, even though 2*MSL has not expired, because undesirable packets are received that result in the connection being RST or otherwise dropped in the interim.

    If a connection is assassinated by a bad out-of-sequence packet, for example, then it won't ever get to accept a delayed in-sequence packet as in your example.  The title of RFC 1337 says it all: assassination is a "hazard" in TCP, not a benefit.

    I hope you will correct the misinformation/misdefinition in this post.