Monday, February 25, 2013

TCP Timestamp - Demystified

What controls you? Some may argue that it’s their jobs, their bosses or their parents but only a selected few will say time. In reality time controls all of us -- what/when/how we do anything is all dictated by time. We all understand how important time is and TCP is no exception which is why RFC 1323 implements a TCP option known as “TIMESTAMP”. This optional 10 byte (1B Kind + 1B Length + 4B TSVal + 4B TSecr) field allows us to time stamp at the TCP level which can be used for TCP RTT calculations and PAWS (Protect Against Wrapped Sequence numbers). I was curious about the TCP TIMESTAMP option so I took a packet capture to investigate it further. However, I was unable to determine how to interpret the fields or how to utilize it to calculate TCP RTT. So I did what most of you would have done – googled it. Much to my dismay, I couldn't really find anything other than RFCs and sites stating the same definition that is already published in the RFC. So I decided to write a blogtorial about it so my fellow searchers/googlers can easily understand on how to utilize TSVal and TSecr to calculate the TCP RTT.

Timestamp packet capture can be downloaded here.

Let’s get started.

First let me break down the TCP TimeStamp option in bytes and define the fields.

 +-------+-----+---------------------+-------------------+  
 |Kind=8 | 10  |  TS Value (TSval) |TS Echo Reply (TSecr)| = Total of 10Bytes  
 +-------+-----+---------------------+-------------------+  
   1B       1B            4B                   4B  

TSval = TimeStamp Value field and it is marked by the TCP sender with its local clock.
TSecr = TimeStamp Echo Reply field and it is set to the TimeStamp value received from the remote TCP sender. Keep in mind that this field is only valid when the ACK flag is set unless it’s sent with a value of 0.  (For example, this field is set to 0 in the initial SYN Packet when establishing a TCP connection).

As a side note remember that a TCP HEADER must be divisible by 32. So if the TCP header is 30 bytes after adding this option then there will be 2 more bytes PADDED with 0s to make the header length divisible by 32.

TimeStamp pseudocode () {

  #1 Client A  --> Server A - Initial SYN should contain TSVAL = Time Cx1 and TSECR = 0
  #2 Server A --> Client A - SYN + ACK should contain TSVAL = Time Cy1 and TSECR = Cx1
  #3 Client A  --> Server A - ACK should contain TSVAL = Cx2 and TSECR = Cy1
  #4 Server A --> Client A - Packet should contain TSVAL = Cy2 and TSEC = Cx2
  
  Cx2 - Cx1 = TCP RTT in ms

}

Got it? Maybe not -- I am sure that it is confusing but let’s us take a look at a wireshark capture and walk through the calculation. One thing I would like to point out is that the TSecr value is 0 only in the initial SYN packet.

Now let’s move on to the actual calculation of the TCP RTT. For this calculation we are going to be taking a look at Packet #4 and Packet #5.

Packet #4
Packet #5
Packet #4 – Server A (1.1.1.2) -> Client A (1.1.1.1) – TSVal=1965828, TSecr=1957100
Packet #5 – Client A (1.1.1.1) -> Server A (1.1.1.2) – TSVal=1957200, TSecr=1965828

TCP RTT between Packet #4 and Packet #5 is TSVal – TSecr = 1957200 – 1951200 = 100ms
Network RTT between Packet #4 and Packet #5 is listed in wireshark – 1.313 – 1.282 = 31ms

TCP RTT can be used to calculate RTTM (Round Trip Time Measurement) and it is used for PAWS (Protect Against Wrapped Sequence Number). Perhaps, I will post something on PAWS at a later time. 

Many more articles to come so stay tuned.

Please subscribe/comment/+1 if you like my posts as it keeps me motivated to write more and spread the knowledge.

Addendum:

Here is how to turn on TCP TimeStamp on Linux and Windows