Это реализация протокола TCP, описанного в RFC793, RFC1122 и RFC2001,
с расширениями NewReno и SACK. Этот протокол предоставляет пользователю надежное
полнодуплексное потоковое соединение двух сокетов над
ip(7)
для соединений версий v4 и v6.
TCP гарантирует доставку данных в нужном порядке и повторно передает
потерявшиеся пакеты. Для выявления ошибок передачи протоколом генерируются и
проверяются контрольные суммы пакетов. TCP не сохраняет границы записей.
Только что созданный сокет TCP не имеет локального или удаленного адреса и не
является полностью определенным. Для создания исходящего соединения TCP с другим
сокетом TCP используйте
connect(2).
Для приема новых входящих соединений сперва подключите
bind(2)
сокет к порту и присвойте ему локальный адрес, а затем с помощью
listen(2)
переведите сокет в режим прослушивания. После этого может быть принят
новый сокет для каждого входящего соединения, используя
accept(2).
Сокет, для которого были успешно вызваны
accept
или
connect,
является полностью заданным и может передавать данные. Данные не могут быть
переданы через слушающий или еще не соединенный сокет.
Linux поддерживает высокопроизводительные расширения TCP RFC1323. Они включают
в себя: защиту против оболочек номеров последовательностей (PAWS),
масштабируемые окна и временные метки. Масштабирование окон позволяет
использовать большие (> 64Кб) окна TCP для поддержки соединений с большой
задержкой или высокой пропускной способностью. Для их использования
необходимо увеличить размеры буферов приема и передачи.
Это можно сделать глобально с помощью переменных sysctl
net.ipv4.tcp_wmem
и
net.ipv4.tcp_rmem,
или через индивидуальные сокеты, используя опции сокетов
SO_SNDBUF
и
SO_RCVBUF
в вызове
setsockopt(2).
Максимальный размер буферов сокета объявляется, используя механизмы
SO_SNDBUF
и
SO_RCVBUF
и ограничен глобальными вызовами sysctl:
net.core.rmem_max
и
net.core.wmem_max.
Заметим, что TCP в действительности размещает места в два раза больше, чем
размер буфера, запрошенный в вызове
setsockopt(2),
поэтому последующий вызов
getsockopt(2)
не возвратит тот же размер буфера, что был запрошен в вызове
setsockopt(2).
TCP использует это для административных целей и внутренних
структур ядра, а переменные sysctl отражают большие размеры,
по сравнению с действительными окнами TCP.
Для отдельных соединений размер буфера сокета должен быть
установлен в соответствии с вызовами
listen()
или
connect()
для нормальной работы.
Дополнительную информацию смотрите в
socket(7).
TCP поддерживает срочные данные. Срочные данные уведомляют принимающую сторону
о том, что частью потока данных является некоторое важное сообщение, которое
должно быть обработано как можно скорее. Для отправки
срочных данных укажите с помощью
send(2)
опцию
MSG_OOB.
При получении срочных данных ядро посылает сигнал
SIGURG
считывающему процессу или группе процессов,
заданным для сокета с помощью вызовов ioctl
SIOCSPGRP
или
FIOSETOWN.
Если запущена опция
SO_OOBINLINE ,
то срочные данные будут помещены в обычный поток данных
(и могут быть проверены с помощью ioctl-вызова
SIOCATMARK),
в противном случае они могут быть получены, только если для
sendmsg(2)
установлен флаг
MSG_OOB.
Linux 2.4 предлагает несколько изменений для улучшенной
пропускной способности и масштабирования, а также для
разрешения особых дополнительных возможностей, таких как
поддержка для пустого копирования (zerocopy) в
sendfile(2),
Explicit Congestion Notification, новое управление сокетами
TIME_WAIT, опции поддержки сокетов в рабочем состоянии
и поддержка расширений Duplicate SACK.
ФОРМАТЫ АДРЕСОВ
Протокол TCP построен поверх протокола IP (см.
ip(7)).
Форматы адресов, определенные в
ip(7),
относятся и к TCP. TCP поддерживает только межузловые соединения (point-to-point);
широковещательная и многоадресная передача не поддерживаются.
СИСТЕМНЫЕ ВЫЗОВЫ
Доступ к нижеприведенным переменным и вызовам sysctl можно получить
с помощью файлов
/proc/sys/net/ipv4/*
или через интерфейс
sysctl(2).
Кроме того, большинство вызовов sysctl IP относятся и к TCP; см.
ip(7).
tcp_abort_on_overflow
Включает сброс соединений, если слушающий сервис слишком медленно работает
и не может обработать существующие или принять новые соединения.
По умолчанию выключен. Это означает, что при переполнении соединение
будет повторно установлено. Включайте эту опцию _только_ если
вы действительно убеждены, что слушающий демон не может быть настроен
для более быстрой работы. Включение этой опции может нарушить
работу пользователей и клиентов вашего сервера.
tcp_adv_win_scale
Рассчитывает переполнение буфера по формуле bytes/2^tcp_adv_win_scale
(если tcp_adv_win_scale > 0) или bytes-bytes/2^(-tcp_adv_win_scale),
если оно <= 0. По умолчанию равно 2.
Буфер приема сокета - это пространство, разделяемое между приложением
и ядром. TCP поддерживает часть буфера в виде окна TCP, то есть размера
принимающего окна, предлагаемого другой стороне. Остаток пространства
используется как "буфер приложения", используемый для изолирования сети
от работ по расписанию и задержек приложения. По умочанию
tcp_adv_win_scale
равно 2, обозначая этим, что для буфера приложения используется
четверть всего пространства.
tcp_app_win
Эта переменная определяет, сколько байтов окна TCP зарезервировано
для буферизации.
Максимум из (window/2^tcp_app_win, mss) байтов в окне будет зарезервировано
для буфера приложения. Значение 0 обозначает, что ничего не зарезервировано.
По умолчанию равно 31.
tcp_dsack
Включает поддержку RFC2883 TCP Duplicate SACK.
По умолчанию включено.
tcp_ecn
Включает RFC2884 Explicit Congestion Notification.
По умолчанию выключено.
При активации может пропасть возможность установления соединений с некоторыми
узлами из-за старых маршрутизаторов (работающих с этой опцией некорректно)
по пути следования к узлу.
tcp_fack
Включает поддержку TCP Forward Acknowledgement.
По умолчанию включено.
tcp_fin_timeout
Указывает на количество секунд, в течение которых необходимо ждать
последний пакет FIN до принудительного закрытия сокета. Строго говоря,
это нарушение спецификации TCP, но оно необходимо для предотвращения
атак отказа доступа к сервисам (DoS).
Значение по умолчанию в ядрах 2.4 равно 80, и ниже 180 в ядрах 2.2.
tcp_keepalive_intvl
Количество секунд между отправками "оживляющих" (keep-alive) проверок.
По умолчанию равно 75 с.
tcp_keepalive_probes
Максимальное количество отправляемых "оживляющих" (keep-alive)
проверок перед тем, как соединение считается разорванным.
Значение по умолчанию равно 9.
tcp_keepalive_time
Количество секунд между отстутствием передаваемых данных и отправкой через
соединение "оживляющего" пакета. Значение по умолчанию - 10800 секунд (3 часа).
tcp_keepalive_time
Количество секунд бездействия, после которого по соединению начинает
передаваться "оживляющие" пакеты TCP. Эти пакеты будут отправляться,
только если включена опция сокета
SO_KEEPALIVE.
По умолчанию равно 7200 секунд (2 часа). Бездействующее соединение
разрывается примерно после 11 минут (9 пакетов, с интервалом 75 секунд)
при включенном режиме keep-alive.
Заметим, что механизмы отслеживания соединений более низкого уровня
и таймеры приложений могут быть гораздо короче.
tcp_max_orphans
Максимальное число безродных (orphaned, не присоединенных ни к одному
обработчику файлов) сокетов TCP, разрешенных в системе. Если превышается
это число, то безродные соединения сбрасываются и выводится предупредительное
сообщение. Данный лимит существует только для простейшего предотвращения
атак отказа в сервисе (DoS). Понижать этот лимит не рекомендуется. Сетевые
соединения могут требовать повышения этого числа, но заметим, что каждое
такое безродное соединение использует до 64Кб невыгружаемой памяти.
По умолчанию значение установлено равным значению параметра ядра NR_FILE.
Значение может изменяться в зависимости от количества памяти в системе.
tcp_max_syn_backlog
Максимальное количество запросов на соединения в очереди, все еще не
получивших подтверждения от клиентов. Если это число превышается, то
ядро начнет сбрасывать запросы. По умолчанию равно 256, при памяти больше
128Мб повышается до 1024, при памяти меньше 32Мб уменьшается до 128.
При значениях больше 1024 рекомендуется также изменить значение
TCP_SYNQ_HSIZE в include/net/tcp.h так: TCP_SYNQ_HSIZE*16<=tcp_max_syn_backlog,
а также необходимо будет после этого пересобрать ядро.
tcp_max_tw_buckets
Максимальное число сокетов в состоянии TIME_WAIT, разрешенное в системе.
Этот лимит существует только для предотвращения простейших атак DoS.
По умолчанию равно NR_FILE*2 и изменяется в зависимости от памяти в системе.
Если это значение превышено, то сокеты закрываются и выводится предупреждение.
tcp_mem
Вектор из 3 целочисленных значений: [low, pressure, high]. Эти границы
используются TCP для отслеживания использования памяти. По умолчанию
рассчитываются во время загрузки в зависимости от количества памяти системы.
low
- TCP не регулирует распределение своей памяти, если число страниц
ниже этого значения.
pressure
- когда количество размещенных TCP страниц превышает это значение, то
TCP изменяет свой метод использования памяти. Это состояние отменяется
при падении количества размещенных страниц ниже значения
low.
high
- вообще максимальное количество страниц, размещаемых TCP. Это значение
переопределяет все другие значения, указанные ядром.
tcp_orphan_retries
Максимальное количество попыток проверки другой стороны соединения при
разрыве связи с нашей стороны. По умолчанию равно 8.
tcp_reordering
Максимальное число пакетов, упорядоченных в потоке пакетов TCP без того,
чтобы TCP начало подразумевать потери пакетом и перешло в состояние
медленного запуска. По умолчанию равно 3. Не рекомендуется менять
это значение. Эта метрика упорядочивания пакетов предназначена для
минимизации повторных передач, обусловленных переупорядочиванием
пакетов в соединении.
tcp_retrans_collapse
При повторных передачах пробовать посылать полноразмерные пакеты.
Включено по умолчанию.
tcp_retries1
Определяет количество попыток повторной передачи пакетов по установленному
соединению без подключения к этому процессу других сетевых механизмов.
Как только превышено это число, то уровень сети обновляет маршрут перед
каждым повтором (если это возможно). По умолчанию спецификаций RFC
минимум равен 3.
tcp_retries2
Максимальное количество попыток повторной передачи пакетов TCP
по установленному соединению до того, как оно будет считаться разорванным.
По умолчанию равно 15, что соответствует времени примерно от 13 до 30 минут,
в зависимости от определенного у вас таймера повторной передачи.
RFC1122 определяет минимальную границу в 100 секунд.
tcp_rfc1337
Включает поведение TCP, совместимое с RFC 1337.
По умолчанию выключено. Если выключено, то: если RST принимается в
состоянии TIME_WAIT, то сокет закрывается немедленно, не дожидаясь
конца периода TIME_WAIT.
tcp_rmem
Вектор из 3 целочисленных значений: [min, default, max].
Эти параметры используются TCP для регулирования размером
буфера приема. TCP динамически корректирет размер буфера приема
от значений по умолчанию, указанных ниже, в диапазоне
этих переменных sysctl, в зависимости от количества памяти в системе.
min
минимальный размер буфера приема, используемый каждый сокетом TCP.
По умолчанию равен 4Кб, и может уменьшаться до PAGE_SIZE байтов
в системах с малым количеством памяти. Это значение используется
для того, чтобы размещения страниц памяти в режиме давления все
равно были разрешены. Не используется для привязки к размеру
буфера приема, объявленного через
SO_RCVBUF
для сокета.
default
размер буфера приема по умолчанию для сокетов TCP. Значение
переопределяет начальный размер убфера по умолчанию из общей переменной
net.core.rmem_default
для всех протоколов. По умолчанию равно 87380 байтов, может уменьшаться
до 43689 в системах с малым количеством памяти. Если желательны
большие размеры буферов приема, то это значение должно быть увеличено
(для воздействия на все сокеты). Для разрешения больших размеров окон TCP
должно быть включено
net.ipv4.tcp_window_scaling
(по умолчанию).
max
максимальный размер буфера приема, используемый каждый сокетом TCP.
Это значение не переопределяет глобальную переменную
net.core.rmem_max.
Не используется для ограничения размера буфера приема через
SO_RCVBUF
для каждого сокета. По умолчанию равно 87380*2 байтов, уменьшается до
87380 в системах с малым количеством памяти.
tcp_sack
Разрешить выборочные подтверждения TCP (TCP Selective Acknowledgements)
для RFC2018. Включено по умолчанию.
tcp_stdurg
Начать интерпретацию поля с указателем срочных данных TCP в строгом
соответствии с RFC793. По умолчанию используется совместимая с BSD интерпретация
указателя на неотложные данные, определяющая первый байт после неотложных
данных. В соответствии с RFC793 указатель должен определять последний байт
неотложных данных. Использование этой опции может привести к проблемам во
взаимодействии сетей.
tcp_synack_retries
Максимальное количество попыток повторной передачи сегмента SYN/ACK на
пассивном соединении TCP. Число должно быть меньше 255. По умолчанию равно 5.
tcp_syncookies
Включить TCP syncookies. Ядро должно быть собрано с включенной опцией
CONFIG_SYN_COOKIES.
Отправлять syncookies при переполнении. Возможность syncookies создана
для защиты сокета от атак переполнения SYN. Используйте ее в самую последнюю
очередь, а лучше вообще не используйте. Это является нарушением протокола
TCP и конфликтует со многими другими областями TCP, например с расширениями.
Может привести к проблемам в работе клиентов и релеев. Не рекомендуется
к использованию на загруженных работой серверах в качестве "быстрой помощи"
при перегрузках или некорректных настройках. В качестве рекомендуемой
альтернативы предлагаем посмотреть опции
tcp_max_syn_backlog,
tcp_synack_retries,
tcp_abort_on_overflow.
tcp_syn_retries
Определяет количество посылаемых удаленной стороне начальных
пакетов SYN до того, как будет возвращена ошибка. Значение
должно быть меньше 255. Значение по умолчанию равно 5,
что соответствует примерно 180 секундам.
tcp_timestamps
Разрешить временные метки TCP (RFC1323). Включено по умолчанию.
tcp_tw_recycle
Включает быстрый оборот сокетов TIME-WAIT. По умолчанию выключено.
Включать ее не рекомендуется, так как это может привести к проблемам
с трансляцией сетевых адресов NAT.
tcp_window_scaling
Разрешить изменение размера окна TCP (RFC1323).
По умолчанию включено. Эта возможность позволяет использовать большие
(> 64Кб) окна для соединений TCP, но она должна также поддерживаться
на другой стороне соединения. Обычно 16 битовый размер поля длины окна
в заголовке TCP ограничивает его размер до 64Кб. Если нужно обеспечить
больший размер окна, то приложение должно увеличить размер своих буферов
сокетов и включить опцию масштабирования окна. Если выключено
tcp_window_scaling
то TCP не будет согласовывать использование масштабирования окон с
другой стороной во время установки соединения.
tcp_wmem
Вектор из 3 целочисленных значений: [min, default, max].
Эти параметры используются TCP для управления размером буфера отправления.
TCP динамически корректирет размер буфера отправления от значений по
умолчанию, указанных ниже, в диапазоне этих переменных sysctl, в зависимости
от количества памяти в системе.
min
минимальный размер буфера отправления, используемый каждый сокетом TCP.
По умолчанию равен 4Кб. Это значение используется для того, чтобы размещения
страниц памяти в режиме давления все равно были разрешены. Не используется
для привязки к размеру буфера отправления, объявленного через
SO_SNDBUF
для сокета.
default
размер буфера отправления по умолчанию для сокетов TCP. Значение
переопределяет начальный размер убфера по умолчанию из общей переменной
net.core.wmem_default
для всех протоколов. По умолчанию равно 16Кб. Если желательны
большие размеры буферов приема, то это значение должно быть увеличено
(для воздействия на все сокеты). Для разрешения больших размеров окон TCP
должно быть включено
net.ipv4.tcp_window_scaling
(по умолчанию).
max
максимальный размер буфера отправления, используемый каждый сокетом TCP.
Это значение не переопределяет глобальную переменную
net.core.wmem_max.
Не используется для ограничения размера буфера приема через
SO_SNDBUF
для каждого сокета. По умолчанию равно 128Кб. Уменьшается до
64Кб в системах с малым количеством памяти.
ОПЦИИ СОКЕТОВ
Для считывания опций сокетов TCP используется вызов
getsockopt(2),
для установки -
setsockopt(2).
Значение аргумента, принадлежащего семейству сокетов, должно быть равно
SOL_TCP.
Кроме того, сокетам TCP доступны большинство опций сокета
SOL_IP.
Дополнительная информация приведена в
ip(7).
TCP_CORK
Если функция запущена, то не посылать частичные кадры.
Все поставленные в очередь частичные кадры будут отосланы,
когда выполнение этой опции будет остановлено.
Это является эффективным для подготовки заголовков перед вызовом
sendfile(2)
или для оптимизации пропускной способности. Эта опция не может совмещаться с
TCP_NODELAY.
Эта опция не должна использоваться, если код в итоге должен быть портируемым.
TCP_DEFER_ACCEPT
Позволяет слушающему просыпаться только при приходе данных на сокет.
Принимает целое значение (секунды), ограничивает максимальное количество
попыток TCP до закрытия этого соединения.
Эта опция не должна использоваться, если код в итоге должен быть портируемым.
TCP_INFO
Используется для сбора информации об этом сокете.
Ядро возвращает структуру struct tcp_info, как определено в файле
/usr/include/linux/tcp.h.
Эта опция не должна использоваться, если код в итоге должен быть портируемым.
TCP_KEEPCNT
Максимальное число проверок TCP, отправляемых до сброса соединения.
Эта опция не должна использоваться, если код в итоге должен быть портируемым.
TCP_KEEPIDLE
Время в секундах до того, как TCP начнет отправлять тестовые пакеты
на неактивном соединении, если для сокета включена опция SO_KEEPALIVE.
Эта опция не должна использоваться, если код в итоге должен быть портируемым.
TCP_KEEPINTVL
Время в секундах между отдельными проверками соединения.
Эта опция не должна использоваться, если код в итоге должен быть портируемым.
TCP_LINGER2
Время жизни безродных сокетов состояния FIN_WAIT2. Эта опция может
использоваться для переопределения общесистемного параметра sysctl
tcp_fin_timeout
на этом сокете. Не должно противоречить опции
SO_LINGER
уровня сокета
socket(7).
Эта опция не должна использоваться, если код в итоге должен быть портируемым.
TCP_MAXSEG
Максимальный размер сегмента для исходящих пакетов TCP.
Если эта опция установлена до возникновения соединения, то меняется также и
значение MSS, сообщаемое другой стороне в начальном пакете. Значения,
превышающие MTU интерфейса, игнорируются. TCP также будет определять
минимальную и максимальную границу поверх этих значений.
TCP_NODELAY
Если включено, то отменить выполнение алгоритма Nagle. Это означает,
что пакеты всегда отсылаются при первой же возможности, даже если к
отправке назначено небольшое количество данных. Если выключено,
то данные буферизуются и будут отправляться только после набора
достаточно большого количества данных, при этом не отправляются
постоянно небольшие пакеты с данными. Эта опция не может
использоваться одновременно с опцией
TCP_CORK.
TCP_QUICKACK
Включает режим quickack при установке или выключает при очищении.
В этом режиме все уведомления отправляются немедленно, а не с
некоторой задержкой в соответствии с обычными операциями TCP.
Этот флаг не постоянный, он только включает или выключает режим quickack.
Последующие операции с протоколом TCP будут по своему
включать/выключать этот режим в зависимости от своих внутренних
протоколов, настроек и факторов.
Эта опция не должна использоваться, если код в итоге должен быть портируемым.
TCP_SYNCNT
Устанавливает число повторных передач SYN, отправляемых TCP до
отмены попыток установки соединения. Не должно превышать 255.
Эта опция не должна использоваться, если код в итоге должен быть портируемым.
TCP_WINDOW_CLAMP
Определяет размер предлагаемого окна в это значение.
Ядро определяет минимальный размер в SOCK_MIN_RCVBUF/2.
Эта опция не должна использоваться, если код в итоге должен быть портируемым.
СИСТЕМНЫЕ ВЫЗОВЫ
Доступ к нижеприведенным ioctl можно получить через
ioctl(2).
Синтаксис следующий:
int value;error = ioctl(tcp_socket, ioctl_type, &value);
SIOCINQ
Возвращает количество несчитанных данных в очереди в буфере
приема. Аргументом является указатель на целое число.
Сокет должен быть в состоянии прослушивания LISTEN,
иначе возвратится ошибка (EINVAL).
SIOCATMARK
Возвращает истинное значение, если все срочные данные
уже получены программой пользователя. Используется совместно с
SO_OOBINLINE.
Аргументом является указатель на целое число, служащее результатом проверки.
SIOCOUTQ
Возвращает количество неотправленных данных в очереди буфера отправления,
в передаваемом указателе на целое число. Сокет не должен быть в состоянии
прослушивания LISTEN, иначе возвратится ошибка (EINVAL).
ОБРАБОТКА ОШИБОК
При возникновении сетевой ошибки TCP пытается отправить пакет повторно. Если в
течение некоторого времени этого сделать не удается, то возвращается либо
ETIMEDOUT
либо последняя ошибка, произошедшая в этом соединении.
Hекоторые приложения требуют более быстрого предупреждения об ошибках.
Это может быть выполнено с помощью уровня
SOL_IP
опции
IP_RECVERR
сокета. Если эта опция запущена, то все входящие ошибки немедленно передаются
программе пользователя.
Используйте эту опцию осторожно: она приводит к тому, что TCP становится более
чувствительным к сменам маршрутов и возникновению других условий, обычных для сети.
ЗАМЕЧАНИЯ
Если во время соединения произошла ошибка записи в сокет, то значение
SIGPIPE
устанавливается только при установлении опции
SO_KEEPALIVE.
TCP не имеет внепоточных данных; он имеет срочные данные. В Linux это
означает, что если другая сторона посылает новые внепоточные данные, то старые
срочные данные вставляются в поток в качестве обычных (даже если не
установлена опция
SO_OOBINLINE).
Это поведение отличается от поведения стеков BSD.
Linux по умолчанию использует совместимую с BSD интерпретацию указателя на
неотложные данные. Это противоречит RFC1122, но необходимо для
взаимодействия сетей. Положение можно изменить с помощью sysctl-вызова
tcp_stdurg.
НАЙДЕННЫЕ ОШИБКИ
EPIPE
Другая сторона неожиданно закрыла сокет, или была произведена попытка чтения
в отключенном сокете.
ETIMEDOUT
Другая сторона не подтвердила передачу данных через определенное время.
EAFNOTSUPPORT
Переданный в
sin_family
тип сокета не был типом
AF_INET.
Любые ошибки, определенные для
ip(7)
или общего уровня сокетов, могут быть возвращены и для TCP.
НАЙДЕННЫЕ ОШИБКИ
Hе все ошибки описаны.
IPv6 не описано.
ВЕРСИИ
Поддержка для Explicit Congestion Notification, файлов zerocopy sendfile,
поддержку переупорядочения и некоторые расширения SACK (DSACK)
были представлены в версии 2.4.
Поддержка для forward acknowledgement (FACK), циклам TIME_WAIT,
опции поддержки сокетов для каждого соединения и вызовы sysctl
были представлены в версии 2.3.
Значения по умолчанию и описатели переменных sysctl, указанные выше,
применимы для ядер 2.4 и выше.
АВТОРЫ
Это руководство было изначально написано Andi Kleen.
Затем было обновлено для ядер версии 2.4 благодаря Nivedita Singhvi,
с помощью Documentation/networking/ip-sysctls.txt от Alexey Kuznetsov.
RFC793 - спецификации TCP.
RFC1122 - требования TCP и описание алгоритма Nagle.
RFC1323 - для временных меток TCP и опций масштабируемых окон.
RFC1644 - для описания риска снятия TIME_WAIT.
RFC2481 - для описания Explicit Congestion Notification.
RFC2581 - некоторые алгоритмы управления TCP.
RFC2018 и RFC2883 - для SACK и расширений SACK.