Как файлы помещают во фреймы Ethernet
Допустим, я скачиваю браузером картинку PNG с фотографией ветки сакуры с веб-сайта из Японии. Она ведь не умещается в одном фрейме. Как выглядит каждый фрейм в нашем случае и сколько их всего будет?
На каждом этапе перемещения данных по стеку TCP/IP каждый протокол добавляет свой заголовок и передает на следующий уровень абстракции (см. Рисунок 1). Заголовок протокола TСP, потом заголовок протокола IP, потом еще заголовок протокола Ethernet и затем считается контрольная сумма всего созданного из этих заголовков и данных фрейма (FCS). Причем на каждом уровне абстракции мы используем еще и разные названия для наших структур данных: фрейм, кадр, датаграмма, пакет, сегмент. И в вершине всего находится транзакция — на уровне приложений, согласно модели OSI ISO. Транзакцией может быть DNS запрос и ответ, HTTP запрос и ответ, SQL запрос и ответ, или запрос и ответный видеопоток от youtube или IP телефонии. Именно в транзакциях в секунду измеряют производительность NGFW, ведь его уровень абстракции — именно уровень приложений.
Рисунок 1. Одна сторона добавляет заголовки при передаче картинки PNG по HTTP, а другая сторона удаляет эти заголовки. Одна сторона разделяет данные файла на фреймы, другая сторона собирает данные в файл из фреймов.
При этом программа, реализующая стек TCP/IP в операционной системе делит данные полученные от вышестоящего приложения на сегменты и добавляет заголовок минимум 20 байт. И какой же максимальный кусочек данных с уровня приложений мы можем отправить в одном фрейме? Этот параметр называется TCP Maximum Segment Size (MSS) — максимальная длина сегмента данных TCP, и он, в свою очередь, зависит от максимально возможной длины фрейма. Maximum Transmission Unit (MTU) — максимальная длина фрейма, которая может быть передана без фрагментации. Она 1500 у фреймов Ethernet, и 9000 в случае с jumbo фрейм. Значение MSS — это длина фрейма минус длина заголовков. Если внутри фрейма сегменты TCP, то MSS = MTU — 40 = 1460 (ориентируйтесь на длины заголовков из Рисунка 2).
Обычно конкретное значение MSS определяется во время «TCP-рукопожатия» с целевым хостом исходя из значений MTU. Однако промежуточный маршрутизатор (например, имея канал с меньшим MTU) может подслушивать TCP SYN пакеты и подменять значения MSS, анонсируемые конечными устройствами. Такое может быть, если где-то посередине есть VPN канал. В результате конечные узлы «договорятся» о меньших MSS и пакеты не придётся фрагментировать.
В итоге все эти заголовки и данные объединяются в единый фрейм для передачи и в сумме длина фрейма 1518 байт. И ваши файлы, голос и видео в виде нарезанных кусочков перемещаются в поле Payload:
Рисунок 2. Формат фрейма (кадра) Ethernet Ethernet MTU — максимальный размер фрейма для данной среды передачи. Обычно 1500 байт. TCP MSS — максимальный размер сегмента данных TCP. Обычно MSS = MTU-40 = 1460
Также для визуализации схемы передачи фреймов (кадров) по сети возьму картинку и рекомендую статью Артема Санникова
Рисунок 3. Заметьте, что в заголовке фрейма адрес получателя идет первым, а в IP заголовке первым идет уже адрес источника.
Если мы хотим скачать картинку PNG с web-сервера, сколько нам нужно фреймов?
Рекомендую запустить wireshark и посмотреть как это будет выглядеть на вашем компьютере. Например, на скриншоте ниже видно, что картинка PNG размером 22Кб уместилась в 16 сегментах TCP:
Рисунок 4. Как выглядит в Wireshark передача PNG картинки размером 22Кб по HTTP в 16 фреймах.
Посмотрите в Wireshark как расположены заголовки друг за другом, какой в вашей TCP сессии MSS и какие еще поля есть, например, номер последовательности и TTL.
Сколько фреймов займет SSL транзакция?
Рисунок 5. Как выглядит в Wireshark SSL транзакция SSL. Транзакцию разбили на 44 фрейма.Я знаю, что дотошные люди хотят знать про MTU с VLAN, QinQ, MPLS
Иногда люди задаются вопросом:, а как меняется MTU между свитчами и роутерами при наличии тегов VLAN. А никак) Остается 1500. Стандарт 802.3AC разрешает максимальный размер фрейма 1522, чтобы добавить информацию о VLAN тегах 802.1q и битах COS 802.1p. А вот при QinQ нужно уже увеличивать MTU до 1504. Приобщу для понимания картинку из более подробной статьи.
Вообще есть огромное количество IEEE 802.3 стандартов для Ethernet. Например, стандарт 802.3AS, где максимальный размер фрейма уже 2000 (но не MTU).
Самое важное, знать, что как только размер MTU превышает возможности среды передачи, то фреймы фрагментируются. И это плохо влияет на скорость передачи. Лучше так не делать. Если вы не знаете какой MTU вам нужно использовать, то вы можете протестировать ваше соединение и найти MTU при котором начинается фрагментация:
ping 10.20.1.11 -M do -s "$((1500-20-8))" -c 1 > MTU_validation.txt
-M do: (возвращает ошибку, если пакет ping фрагментирован. Здесь написан вариант ping для linux, где используются ICMP пакеты. В Windows используйте ключи -f -l)
-s packetsize: размер данных:
1500 = тот MTU, который хотите использовать
20 = размер IP заголовка
8 = размер ICMP заголовка
Протокол TCP регулирует значение MSS, чтобы исключить фрагментацию.
Статья написана для тех, кто изучает сетевые технологии и их безопасность. Запустите у себя на компьютере wireshark и посмотрите как у вас выглядят сетевые соединения.
В продолжение рекомендую прочитать статью «Что меняется внутри фрейма Ethernet при передаче от роутера к роутеру?»