Search code examples
tcpistiohandshake

TCP handshake involving more than two ports


I have an application deployed on a Kubernetes cluster. I am using Istio/Envoy in this deployment to control inbound/outbound traffics. I have collected some TCP packets using TCPdump for investigating some issue.

To my understanding, a TCP handshake should only involves a pair of 5-tuple (src-IP, src-Port, dst-IP, dst-Port, protocol). For example

IP: 198.168.1.100 Port: 52312 ----SYN----> IP: 198.168.1.101 Port: 80
IP: 198.168.1.100 Port: 52312 <--SYN ACK-- IP: 198.168.1.101 Port: 80
IP: 198.168.1.100 Port: 52312 ----ACK----> IP: 198.168.1.101 Port: 80

But in the packets I collected, what I don't understand is this:

10.X.X.X    127.0.0.1   TCP 76  33500 → 15001 [SYN] Seq=3333992218
X.X.X.X     10.X.X.X    TCP 76  80 → 33500 [SYN, ACK] Seq=2228273021 Ack=3333992219
10.X.X.X    127.0.0.1   TCP 68  33500 → 15001 [ACK] Seq=3333992219 Ack=2228273022

Notice the SYN ACK was returned from a port 80. First, I thought there could be missing packets and there was actually two handshakes, but looking at the sequence number and acknowledgment number, it seems to be single handshake.

If this is a single handshake, how would you explain this? Is there a technique that does the TCP handshake differently?


Solution

  • If this is a single handshake, how would you explain this? Is there a technique that does the TCP handshake differently?

    According to this blog:

    This is a single handshake, just there are 2 separate connections, first goes to envoy sidecar, then envoy sidecar as a middleman send it to your pod.

    So this is the magic: the connection is not established between client and server directly, but split into 2 separate connections:

    connection between client and sidecar

    connection between sidecar and server

    Those two connections are independently handshaked, thus even if the latter failed, the former could still be succesful.

    enter image description here

    Actual view of the two sides: a middleman sits between client and server


    If you're looking for more informations about the 15001 port itself you can visit istio documentation.

    It is explained in more details here.