Jan Fan     About     Archive     Feed     中文博客

Why We Need Three-Way Handshake in TCP

Today I go over the concepts about TCP, and pay special attention to the Three-way handshake, the necessary actions before our hosts start to communicate over TCP.

In this post I am gonna make a clear illustration on why three-way handshake is important, besides we will have a network packet capture experiment with tools, tcpdump and wireshark, to give a vivid demonstration of how three-way handshake works.

!--more--

What is Three-way Handshake?

TCP's three way handshaking technique is often referred to as “SYN-SYN-ACK” (or more accurately “SYN, SYN-ACK, ACK”)

We use a packet capture experiment to demonstrate this. We capture the packets sent to or received from Baidu.

First we need the ip address of Baidu

$ dig www.baidu.com

tcpdump is a network sniffer tool, used to capture all packets on our network interface.

on OS X(on Linux you may need to change the interface name en0 into eth0), exec

$ sudo tcpdump -i en0 -w test.dat src 180.97.33.108 or dst 180.97.33.108

Then we will have the packets in our file test.dat

Finally we use wireshark to read and analyse the packets. wireshark is a network packet analysis tool, used to visually represent the packets we captured.

See the following pic, the 1, 7, 8 rows are respectively the “SYN, SYN-ACK, ACK”. After this three steps, you and the server can begin to talk freely. wireshark

Why We Need Three-way Handshake?

Why we need to make this so-called three-way shake? We will have to start the story with the reliable data transfer service in TCP.

Reliable TCP is built on unreliable IP protocol, which is the best effort protocol, i.e., the packets transferred over it may get lost. Besides, the packets are actually transferred with bits one by one, during which some bits may flip, i.e., the data may be corrupted.

For clear illustration, we will begin with a simple situation, and then go close to the real conditions step by step.

Transfer with Data Corruption

Suppose Amy and John(two hosts) would like to communicate over TCP.

In this example, John has no idea that the packet is corrupted.

 Amy          John
  |    data     |
  | ---error--> |
  |             |

If Amy not only send the data, but also the checksum of the corresponding data, John is able to detect the corruption. But John still can receive the correct packet since Amy doesn’t resend it.

 Amy              John
  |  data+checksum  |
  | -----error----> |
  |                 |

Only if Amy gets the feedback about the packet she sends, she can resend the packet or start sending the new packet.

 Amy              John
  |  data+checksum  |
  | -----error----> |
  |  ack+checksum   |
  | <-------------- |
  |  data+checksum  |
  | ----resend----> |

So far we have one last question - what is the ack? If we use a boolean variable - 0 or 1, standing for error and correct packet - Amy can only send one packet at a time.

For more efficiency, we need Amy to send multiple packets at one time. Then we have to make pairs to inform Amy which packet is corrupted. We take 2 packets for example.

 Amy               John
  |  data1+checksum  |
  | -----error-----> |
  |  data2+checksum  |
  | ----no error---> |
  |   ack1+checksum  |
  | <------0-------- |
  |   ack2+checksum  |
  | <------1-------- |
  |  data1+checksum  |
  | ----resend-----> |
  |   ack1+checksum  |
  | <------1-------- |

We have to mark the packet and ack with the same sequence number to make them a pair, and different packets use different sequence number.

Here comes the key point - we use SYN to stand for the sequence number of packet, and ACK for ack.

Of course in general, we make SYN == ACK within a specific pair , but we can also take into consideration the order of packets sent and the length of the packet data, in where each ACK still uniquely refers to one SYN, i.e., John can tell which packet is corrupted.

 Amy                     John
  | SYN(0)+data1+checksum  |
  | ------length(3)------> |
  | ACK(0+3)+ checksum     |
  | <--------------------- |
  | SYN(3)+data2+checksum  |
  | ------length(5)------> |
  | ACK(3+5)+ checksum     |
  | <--------------------- |

Up to now, the transfer with error is done, and The Three-way handshake is also explained half its way :-). You will know it soon.

Transfer with Delay

Some IP datagram(encapsulated from segment of TCP) may be transfered with more delay than others, mostly caused by the Queuing when the network gets busy.

Does the order of packets arrival matter?

Amy      John
 |  data1  |
 | ------> |
 |  data3  |
 | ------> |
 |  data2  |
 | ------> |

John has no idea the order of packets, i.e., he can’t recover the correct data from a sequence of packets.

But with the SYN sequence number we mention above, John can make the packets in order again, since the SYN sequence number is always increasing in order.

 Amy                     John
  | SYN(0)+data1+checksum  |
  | ------length(3)------> |
  | SYN(8)+data3+checksum  |
  | ------length(2)------> |
  | SYN(3)+data2+checksum  |
  | ------length(5)------> |

However, one question remains - which is the first packet? Though John knows the smaller one is ahead, but which is the smallest one?

Maybe we can make a convention to use a specific initial number, such as 0, as the first sequence number.

But ask all hosts to use the same isn is not easy?(or for other reasons? welcome to point it out :( ) We can create a new bit - SYN BIT to indicate this is the first packet. Then Amy can use a random isn as the SYN sequence number. This also explain why we need to do three-way handshake before communication.

 Amy                     John
  | SYN_BIT+SYN(0)+data1+checksum  |
  | ----------length(3)----------> |
  | SYN(8)+data3+checksum          |
  | ----------length(2)----------> |
  | SYN(3)+data2+checksum          |
  | ----------length(5)----------> |

Transfer with Loss

Fine, now we get into the last problem - data loss - the routers along the way may discard the packet when the network is crowded and it’s buffer is full.

Unlike the corruption, John can’t even receive the packet when data loss happens. That means, John has no choice to ask Amy to resend the packet.

 Amy      John
  |  data1  |
  | -loss-> |

One solution is that Amy resend the packet after a timeout, determined by RTT.

 Amy      John
  |  data1  |
  | -loss-> |
  |  data1  |
  | ------> |
  |  ack1   |
  | <------ |

But timeout may cause the order of packets to change.

 Amy      John
  |  data1  |
  | -loss-> |
  |  data2  |
  | ------> |
  |  ack2   |
  | <------ |
  |  data1  |
  | ------> |
  |  ack1   |
  | <------ |

So we still need SYN flag to order the packets for John as that of the delay situation above.

Summary

Based on the requirements(no corruption, reorderable packets, no packet loss) to build a reliable TCP protocol, we all lead to the same solution - SYN and ACK sequence number, which is also the key point of three-way handshake.

With the understanding of these, it’s much easier for you to understand the Sliding Window Protocol, such as Go-Back-N and Seletive Repeat. Hope this tutorial could help you.

Comments

comments powered by Disqus