Реализация фрагментации IP
Я работаю над приложением, которое генерирует сетевой трафик. Приложение имеет eth1
в смешанном режиме. Так что он напрямую обрабатывает весь входящий и исходящий трафик.
Одной из функций, которые я реализую, является фрагментация и дефрагментация IP. Входящие фрагменты должны быть повторно собраны, а исходящие пакеты должны быть фрагментированы, если их размеры превышают MTU 1500 байтов.
Один из простых способов проверить мое приложение - отправить ping
Команда на IP-адрес eth1
:
ping -c1 -s 20000 10.3.2.1
Это работает нормально.
Однако, как только размер пакета превышает ~53000 байт, он терпит неудачу. Согласно Wireshark, я получаю фрагменты до смещения фрагмента ~51000, а затем ничего, после чего следует таймаут повторной сборки.
Максимальный размер IP-пакета составляет 65535 байт. ping
Команда позволяет указать размер до 65507. Это на самом деле работает, если я пинг до eth0
(ОС контролируется).
При проверке приложения изнутри с помощью GDB все идет хорошо. Последовательность кода показывает, что фрагменты попадают в мое приложение, IP-пакет успешно повторно собирается, а затем снова фрагментируется, и фрагменты отправляются обратно отправителю. Даже для последнего фрагмента возвращаемое значение send(...)
(сокет API) равен размеру фрагмента, что свидетельствует об успехе.
У кого-нибудь есть идея, что может пойти не так?
Операционная система - Linux (на основе RTLinux).
3 ответа
Если пакеты правильно фрагментированы, то собираются на стороне клиента, но обратное не работает,
A -----> B
|
A <--x-- B
Я бы предложил сначала попытаться инвертировать роли (поскольку проблема находится на обратном пути) и проверить, могут ли на этот раз фрагментированные пакеты / повторная сборка быть выполнена A
A <----- B
|
?
В противном случае существует проблема в управлении пакетами от B до A, это может быть ограничение брандмауэра или любой маршрутизатор или коммутатор, который вы можете иметь между ними.
The maximum TCP segment you can have is 65,495 bytes.
Если вы касаетесь заголовков... это может быть граница, которую вы ищете:>
Кроме того, у вас есть постоянное окно для TCP или оно само адаптируется? Возможно, используется меньшее окно, и вы не можете отправить больше данных
решаемая
Проблема была в потере пакетов. IP-ответ был отправлен на коммутатор по гигабитной линии. Этот переключатель, в свою очередь, пересылал сообщения по линии 100 Мбит. Это означает, что пакеты поступили с большей скоростью, чем они оставили, что привело к быстрому увеличению использования памяти внутри коммутатора. Как только вся память была использована, у коммутатора не было другого выбора, кроме как начать отбрасывать пакеты.