Incomplete TCP Initial-Handshake
I am irritated about the following scenario:
I am running a MVC application on an IIS 10 Webserver. While calling the URI, it takes about 10 seconds until the application starts to get called (IDLE time). Having no real explanation for the occuring idle, I started to dig deeper using wireshark and stumble across the following phenomenon: The Initial TCP Handshake is incomplete (Missing ACK) 1. Client -> Server (SYN) 2. Server -> Client (SYN, ACK) 3. Client -> Server (ACK never reaches the server)
The topology is as described below.
- Client -> Gateway -> Router -> Server1 -> Server2
Note: The Client is redirected to Server2 by Server1. Thus the page load time sums up to ~20seconds. The first 10s are reached by hitting Server1, and the next 10s by being redirected to Server2.
I used wireshark on client-side as well as on server side. The server resends the SYN,ACK tuple two times, after about 10s IDLE time, the connection is established nonetheless. Looking at the appropriate RFC, this behavior is normal (the ACK is sent by client indirectly while sending the data). The ACK never reaches the router, so where could it get possibly lost? And why does it get lost EACH time? Could it be some router (Mikrotik) setting, like No-ACK? Is the missing ACK the reason for the 10s IDLE delay?
Edit:
I updated the topology information above. I did anonymize the wireshark traces, they can be found at the following URIs:
Due to the anonymization process in TraceWrangler, the IP addresses vary from trace to trace in the following way:
- Client IP: 192.168.248.249 <=> 172.23.147.181 <=> 192.168.201.209 <=> 10.206.108.221
- Router IP: 10.194.30.227 <=> 172.17.84.111
- Server1 IP: 172.31.124.208 <=> 10.100.24.4
- Server2 IP: 172.20.78.56 <=> 192.168.204.149
You may use the following filters to get a clear glimpse on the initial handshake:
Filter Client: (((ip.dst ==192.168.248.249) && (ip.src ==10.194.30.227)) || ((ip.dst ==10.194.30.227) && (ip.src ==192.168.248.249))) && (tcp.flags.syn==1 ) || (tcp.flags == 0x0010 && tcp.seq==1 && tcp.ack==1)
Filter Router: (tcp.flags.syn==1 ) || (tcp.flags == 0x0010 && tcp.seq==1 && tcp.ack==1)
Filter Server1: (((ip.dst ==172.31.124.208) && (ip.src ==192.168.201.209)) || ((ip.dst ==192.168.201.209) && (ip.src ==172.31.124.208)) || ((ip.dst ==172.31.124.208) && (ip.src ==172.20.78.56)) || ((ip.dst ==172.20.78.56) && (ip.src ==172.31.124.208))) && (tcp.flags.syn==1 ) || (tcp.flags == 0x0010 && tcp.seq==1 && tcp.ack==1)
Filter Server2: (((ip.dst ==10.100.24.4) && (ip.src ==10.206.108.221)) || ((ip.dst ==10.206.108 ...
No idea, but if you have admin access to the Mikrotik, you can ask it to capture (sniff in their terminology) at both client-facing and server-facing interface simultaneously. The sniff files are standard pcap or pcapng files which you can then analyse using Wireshark.
This way you should see whether the client actually ever sends that standalone ACK to the wire/air and whether the Mikrotik forwards it.
Can you share us the traces from client and server side? https://blog.packet-foo.com/2016/11/t...
Thanks for your great suggestions, I followed the instructions and updated my post above with the appropriate traces.