Когда трассировка wirehark выполняется на стороне клиента, она выглядит так:
---SYN--->
<-SYN-ACK-
---ACK--->
-HTTPGET->
Но когда трассировка wirehark выполняется для того же трафика на стороне сервера, это выглядит так:
---SYN--->
<-SYN-ACK-
-HTTPGET->
Где пакет HTTPGET выглядит как ACK для SYN-ACK, поскольку он имеет ту же последовательность и номер подтверждения, что и предыдущий пакет ACK.
То же самое происходит позже и наоборот:
Когда трассировка wirehark выполняется на стороне сервера, она выглядит так:
-HTTPGET->
<---ACK---
<-200-OK--
Но трассировка wirehark, взятая для того же трафика на стороне клиента, выглядит так:
-HTTPGET->
<-200-OK--
Где 200OK выглядит как ACK для HTTPGET, поскольку он имеет ту же последовательность и номер подтверждения, что и предыдущий пакет ACK.
Итак, мой вопрос, есть ли какой-либо известный сетевой элемент, который выполняет TCP-копирование как человек-посередине?
Я считаю, что это вызывает некоторые проблемы у обоих пиров, поскольку они, кажется, ждут «отсутствующего» ACK навсегда: Например:
* Дублирующий ACK для 200OK на стороне сервера, поскольку он ожидает третьего ACK в трехстороннем подтверждении связи TCP (которое было скопировано в последующий HTTPGET).
* Повторная передача HTTPGET на стороне клиента, поскольку исходный, не совмещенный ACK для него никогда не приходит.
Вот примеры трассировки: http://goo.gl/7V0pah
Посмотрев на множество изменений, происходящих с пакетами в пути, я наконец заметил одно, которое могло бы правдоподобно объяснить, почему клиент считает, что пакет данных с сервера не соответствует последовательности.
Посмотрите на опцию отметки времени, в частности посмотрите на поле значения отметки времени на пакетах от сервера к клиенту. Они исходят от сервера со значениями от 7236650 в SYN-ACK до 7246570 в последнем пакете.
Однако по получении на клиенте значение метки времени в пакете SYN-ACK было изменено на значение 1068916716. Остальные пакеты отправляются от сервера к клиенту без изменения значения метки времени.
Таким образом, с точки зрения клиентов, временная метка идет от 1068916716 до 7236708. Другими словами, она идет в обратном направлении, и это, безусловно, веская причина для клиента рассматривать пакет как неупорядоченный.
Итак, у вас есть предположение, что основная причина вашей проблемы - это искаженная временная метка в SYN-ACK.
Прежде чем прийти к такому предположению, я обнаружил много других интересных фактов из трассировки пакетов. Хотя эти другие точки данных не объясняют вашу проблему, они могут быть важными точками данных для дальнейшего исследования. Я использовал Wireshark для проверки захвата пакетов, но подойдет любой инструмент, который может декодировать все заголовки TCP.
0x5b1f
и просто увеличивая от этого значения до достижения 0x51d3
на последнем пакете. Однако на принимающей стороне первый пакет имеет другой IPID по прибытии. это 0xd5f5
. Также замечаю, что пакет с ID 0x51c2
задержался и прибыл после пакета с идентификатором 0x51c4
.0x0000
в пакете SYN-ACK, а затем идет от 0x2766
на втором пакете 0x2770
на последнем.0x2766
потерялся. Остальные идентификаторы поступают к клиенту по порядку.0x2767
, клиент отвечает ACK порядкового номера начального SYN-ACK
а не только что полученного пакета. И он игнорирует полученный ACK и продолжает повторно передавать запрос. Другими словами, клиент ведет себя так, как если бы он только что получил пакет, который не соответствует порядку. Если клиент сделал это только из-за потери ACK от сервера к клиенту, то это явно ошибка в стеке TCP на клиенте. Я подозреваю, что с этим пакетом что-то не так. Объявленный размер окна для этого пакета был увеличен при передаче от сервера к клиенту. Однако, поскольку окно далеко не полное, это вряд ли будет проблемой.У задействованных промежуточных ящиков нет никакого способа вернуть все свои изменения, если они обнаружены в сообщениях об ошибках ICMP. Таким образом, я уверен, что выборочное уменьшение TTL на пакетах перед их отправкой может быть использовано для определения того, какой маршрутизатор на этом пути искажает пакеты. (За исключением случаев, когда провайдер решил отбросить все соответствующие пакеты ICMP, так что вы не сможете отлаживать проблемы, и если это так, пора было бы искать другого провайдера.)