Я анализирую трафик между клиентом и веб-сервером Linux, работающим на блейд-сервере HP, иногда клиент застревает в ожидании дополнительных данных, когда веб-сервер закрывает соединение.
Веб-сервер запускает apache2, который по какой-то причине предпочитает запускать HTTP / 1.1 с закрытием соединения, а не разрешать клиенту отправлять несколько запросов по одному и тому же соединению и закрывать соединение, как стандартный HTTP / 1.1 (это другая история ... Но это оставляет сервер с несколькими тысячами сокетов TIME_WAIT вместо того, чтобы передавать это состояние клиенту) ...
В любом случае, иногда HTTP-запросы ломаются, но до сих пор не знаю, где именно. На стороне сервера все выглядит нормально, за исключением того, что клиент начинает посылать много пакетов RST между подтверждениями.
У меня есть записи tcpdump с веб-сервера и с NAT, через который проходит клиент, я бы заподозрил NAT, если бы он не был очень странным поведением на веб-сервере.
Когда веб-сервер обслуживает HTTP-запрос GET, первый исходящий пакет составляет 2960 байт в полезной нагрузке IP, 2974 байта на проводе. Это очень странно, поскольку на стороне клиента в NAT клиент получает два пакета по 1514 байт с полезной нагрузкой TCP 1460 байт.
Следующие и предстоящие пакеты, которые покидают интерфейс на веб-сервере, используют полезную нагрузку 1460 (1514 на проводе), которая находится в пределах MTU.
Я считаю, что некоторая магия творится в SLB (Cisco), который находится между веб-сервером и сетью, поэтому первый пакет DF 2960 проходит через SLB и волшебным образом разделяется в SLB с помощью некоторого расширенного перехвата L3.
Q1) Зачем стеку apache webserver / tcp даже пытаться протолкнуть пакет размером 2960 байт на интерфейс, для которого установлено значение MTU 1500?
Q2) Как он проходит через сеть, поступая к клиенту в виде двух пакетов?
Q3) Как веб-сервер узнает, что MTU следует уменьшить до 1460, даже если не приходит ICMP с установленным параметром «Требуется фрагментация», поскольку для всех пакетов установлен бит DF.
Не спрашивайте меня, почему я задаю эти вопросы, я просто парень из большой большой организации, пытающийся понять, почему иногда что-то не работает.
У меня есть несколько интересных журналов tcpdump, которые я могу опубликовать при необходимости, мне просто нужно заменить общедоступные IP-адреса и тому подобное ...
Если вы захватываете пакеты на сервере, вы можете увидеть, что TCP отправляет сегменты большего размера, чем MTU. Однако пакеты на проводе будут иметь размер только MTU. Вы можете проверить это, захватив на сетевом устройстве (коммутаторе) и т. Д. В качестве альтернативы захват пакетов на удаленном (клиентском) компьютере покажет, что каждый пакет имеет <= MTU.
Такое поведение связано с тем, что при включенном TSO / GSO сегмент TCP разбивается на пакеты размером MTU аппаратным обеспечением NIC. Поскольку tcpdump выполняет захват на программном уровне, он видит сегменты, превышающие MTU, которые отправляются на карту NIC для дальнейшей передачи.
Если вы отключите tso / gso для сетевого адаптера, вы увидите, что все исходящие пакеты будут иметь размер <= MTU (более вероятно, размер pMTU).
Q1: Я действительно не знаю, что apache знает, что он там делает. Он будет работать с TCP-соединениями, а все остальное оставит TCP-стеку операционной системы;)
Q2: фрагментация. Пакет отклоняется по пути, «отправить снова, меньше» отправляется обратно, сервер (не apache - это стек IP) отправляет его снова меньшего размера.
Q3: это не так. На самом деле, я не думаю, что apache имеет дело со стеком tcp вообще на более низком уровне, а MTU и т. Д. Намного ниже. За это отвечает стек TCP сервера, и если установлены правильные настройки (НЕ ТОЛЬКО «требуется фрагментация», но также правильный меньший размер - параметр, который вы смотрите на нем TCP MSS).
Технически это выглядит как неисправное оборудование и / или некоторая неработающая реализация TCP, поскольку параметр MSS в пакете SYN, кажется, содержит размер больше допустимого, ИЛИ компьютер-отправитель просто игнорирует значение MSS.
http://en.wikipedia.org/wiki/Maximum_segment_size является хорошей отправной точкой. Кажется, что обнаружение MTU не удается (или результат игнорируется), и тогда используется нестандартный размер.