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?
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.
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.