Шрифт:
IPv4 и IPv6 определяют минимальный размер буфера сборки( minimum reassembly buffer size) — максимальный размер дейтаграммы, который гарантированно поддерживает любая реализация. Для IPv4 этот размер равен 576 байт, для IPv6 он увеличен до 1500 байт. Например, в случае IPv4 мы не знаем, может ли данный пункт назначения принять дейтаграмму в 577 байт. Поэтому многие приложения IPv4, использующие UDP (DNS, RIP, TFTP, BOOTP, SNMP) предотвращают возможность генерирования приложением IP-дейтаграмм, превышающих этот размер.
Для протокола TCP определен максимальный размер сегмента( MSS, maximum segment size). MSS указывает собеседнику максимальный объем данных TCP, которые собеседник может отправлять в каждом сегменте. Параметр MSS мы видели в сегментах SYN на рис. 2.5. Цель параметра MSS — сообщить собеседнику действительный размер буфера сборки и попытаться предотвратить фрагментацию. Размер MSS часто устанавливается равным значению MTU интерфейса минус фиксированные размеры заголовков IP и TCP. В Ethernet при использовании IPv4 это будет 1460, а в Ethernet при использовании IPv6 — 1440 (заголовок TCP для обоих протоколов имеет длину 20 байт, но заголовок IPv4 имеет длину 20 байт, а заголовок IPv6 — 40 байт).
16-разрядное поле MSS ограничивает величину соответствующего параметра на уровне 65 536. Это хорошо для IPv4, поскольку максимальное количество данных TCP в дейтаграмме IPv4 равно 65 495 (65 535 минус 20-байтовый заголовок IPv4 и 20-байтовый заголовок TCP). Но в случае увеличенного объема полезных данных дейтаграммы IPv6 используется другая технология (см. документ RFC 2675 [9]). Прежде всего, максимальное количество данных TCP в дейтаграмме IPv6 без увеличения объема полезных данных равно 65 515 байт (65 535 минус 20-байтовый заголовок IPv6). Следовательно, значение MSS, равное 65 535, считается особым случаем, обозначающим «бесконечность». Это значение используется только вместе с параметром увеличения объема полезных данных, что требует размера MTU, превышающего 65 535. Если TCP использует параметр увеличения объема полезных данных и получает от собеседника объявление размера MSS, равного 65 535 байт, предельный размер дейтаграммы, посылаемой им, будет равен просто величине MTU интерфейса. Если оказывается, что этот размер слишком велик (например, в пути существует канал с меньшим размером MTU), при обнаружении транспортной MTU будет установлено меньшее значение MSS.
SCRIPT устанавливает параметр фрагментации равным наименьшей транспортной MTU для всех адресов собеседника. Сообщения, объем которых превышает эту величину, разбиваются на более мелкие, которые могут быть отправлены в одной IP-дейтаграмме. Параметр сокета
Отправка по TCP
Приняв все вышеизложенные термины и определения, посмотрим на рис. 2.15, где показано, что происходит, когда приложение записывает данные в сокет TCP.
Рис. 2.15. Этапы записи данных в сокет TCP и буферы, используемые при этой записи
У каждого сокета TCP есть буфер отправки, и мы можем изменять размер этого буфера с помощью параметра сокета
TCP помещает данные в буфер отправки сокета и отправляет их собеседнику TCP, основываясь на всех правилах передачи данных TCP (главы 19 и 20 [111]). Собеседник TCP должен подтвердить данные, и только когда от него придет сегмент ACK, подтверждающий прием данных, наш TCP сможет удалить подтвержденные данные из буфера отправки сокета. TCP должен хранить копию данных, пока их прием не будет подтвержден адресатом.
TCP отправляет данные IP порциями размером MSS или меньше, добавляя свой заголовок TCP к каждому сегменту. Здесь MSS — это значение, анонсированное собеседником, или 536, если собеседник не указал значения для MSS. IP добавляет свой заголовок, ищет в таблице маршрутизации IP-адрес назначения (соответствующая запись в таблице маршрутизации задает исходящий интерфейс, то есть интерфейс для исходящих пакетов) и передает дейтаграмму на соответствующий канальный уровень. IP может выполнить фрагментацию перед передачей дейтаграммы, но, как мы отмечали выше, одна из целей параметра MSS — не допустить фрагментации; а более новые реализации также используют обнаружение транспортной MTU. У каждого канального соединения имеется очередь вывода, и если она заполнена, пакет игнорируется, и вверх по стеку протоколов возвращается ошибка: от канального уровня к IP и затем от IP к TCP. TCP учтет эту ошибку и попытается отправить сегмент позже. Приложение не информируется об этом временном состоянии.
Отправка по UDP
На рис. 2.16 показано, что происходит, когда приложение записывает данные в сокет UDP.
Рис. 2.16. Отправка данных через сокет UDP
На этот раз буфер отправки сокета изображен пунктирными линиями, поскольку он (буфер) на самом деле не существует. У сокета UDP есть размер буфера отправки (который мы можем изменить с помощью параметра сокета
UDP просто добавляет свой 8-байтовый заголовок и передает дейтаграмму протоколу IP. IPv4 или IPv6 добавляет свой заголовок, определяет исходящий интерфейс, выполняя функцию маршрутизации, и затем либо добавляет дейтаграмму в очередь вывода канального уровня (если размер дейтаграммы не превосходит MTU), либо фрагментирует дейтаграмму и добавляет каждый фрагмент в очередь вывода канального уровня.
Если приложение UDP отправляет большие дейтаграммы (например, 2000-байтовые), существует гораздо большая вероятность фрагментации, чем в случае TCP, поскольку TCP разбивает данные приложения на порции, равные по размеру MSS, а этому параметру нет аналога в UDP.