Что такое масштабирование окна TCP?

Опубликовано: 16 Сентября, 2022

В заголовке TCP поле размера окна имеет размер 16 бит. Используя это поле, пользователи TCP (клиент или сервер) могут объявить другому конечному пользователю максимум 2· 16 = 65536 байт или 64 КиБ в качестве размера буфера. Но современные конечные устройства (например, телефоны, планшеты, ПК и т. д.) имеют гораздо больше памяти в своих буферах. Этого 16-битного поля было достаточно при первоначальном проектировании TCP в 1980-х годах. Но сегодня память дешевле, а сеть очень быстрая, поэтому ситуация иная. Следовательно, если конечная точка имеет более 64 КиБ памяти в своем буфере для соединения TCP, как она передает эту информацию одноранговой конечной точке, используя то же самое 16-битное поле размера окна?

Есть два возможных решения:

1. Увеличьте поле размера окна с 16 бит до 30 бит. Но это практически невозможно. Невозможно обновить это поле на всех устройствах, использующих TCP по всему миру.

2. Измените определение размера окна. Используйте масштабный коэффициент для передачи 30-битного размера окна, используя только 16-битное поле в заголовке TCP. Это называется масштабированием окна.

Заголовок TCP:

Что такое масштабирование окна TCP?

Он решает проблему масштабируемости с помощью « окна получателя », « объявленного окна » или « пользовательского буфера » без увеличения размера поля « окно » (которое составляет 16 бит) в заголовке TCP. Он расширяет «определение» поля Window до 32 бит, а затем использует «коэффициент масштабирования» для переноса этого 32-битного значения в 16-битное поле окна TCP-заголовка. Масштабный коэффициент задается в новой опции TCP под названием « Масштаб окна ».

В заголовке TCP есть поле параметров, которое было разработано с учетом всех будущих оптимизаций TCP. Масштабирование окна также использует эту опцию. Сначала клиент передает свой коэффициент масштабирования серверу в пакете SYN. Когда сервер получает коэффициент масштабирования клиента в пакете «SYN»; затем он отправляет свой коэффициент масштабирования, используя то же поле опции в пакете « SYN+ACK », который является пакетом подтверждения для запроса на соединение, сделанного клиентом. Существует строгое ограничение, согласно которому параметр «Масштаб окна», полученный в любом другом пакете (кроме SYN-пакета, отправленного клиентом первым), должен игнорироваться сервером (сервер не должен первым делиться своим коэффициентом масштабирования).

Let say client sends SYN packet to server and says that its scaling factor = 2 and receives scaling factor of receiver in ‘SYN+ACK’ packet from receiver.

Now in next packet sender tells its window size = 200 bytes. 

Then Server will calculate the real buffer size available at client as: window_size * 22 = 800 bytes.

Client first finds its real buffer size = 800 bytes then it right shifts(reduces) this value 2 times and stores in window size in header and shares with server.

When server receives scaling factor and window size then it left shifts(multiplies) this value 2 times to get real value of client buffer size.

Следует отметить один момент, когда клиент передает серверу свой коэффициент масштабирования в пакете SYN, тогда этот коэффициент масштабирования не применяется к этому пакету. Он будет применим только тогда, когда сервер примет его и поделится своим коэффициентом масштабирования в пакете SYN+ACK. Коэффициент масштабирования применяется к следующему пакету и далее, как только клиент и сервер заранее знают коэффициент масштабирования друг друга. В следующем пакете они не отправляют коэффициент масштабирования в каждом пакете.

Можем ли мы изменить коэффициент масштабирования окна?

Вполне возможно обновить коэффициент масштабирования окна. Когда клиент снова свяжется с сервером в будущем, он может снова указать свой коэффициент масштабирования окна серверу, и в качестве отвечающего сервера он также передаст свой коэффициент масштабирования окна в пакете SYN+ACK. А что, если TFO включен? Да, тогда клиент также может поделиться своим обновленным коэффициентом масштабирования окна с сервером в самом пакете SYN вместе с запросом GET. В ответ на это сервер также поделится своим текущим коэффициентом масштабирования окна в пакете ACK вместе с данными для запроса GET. Еще один способ — обновить коэффициент масштабирования окна. Клиент должен сначала удалить свои файлы cookie. Когда файлы cookie удаляются, происходит первоначальное трехстороннее рукопожатие, а затем сам клиент может поделиться своим новым коэффициентом масштабирования окна.

Масштабный коэффициент задается в новой опции TCP под названием « Масштаб окна ». "сдвиг. cnt» содержит значение масштабирования. Если сдвиг. cnt = 2, то значение поля размера окна сдвигается влево 2 раза, чтобы получить реальный размер буфера. Следовательно, Масштабный коэффициент = 2 shift.cnt . Смена. cnt' ограничен 14. Таким образом, максимальный размер окна, который может быть объявлен с помощью этой опции, составляет 2 30 = 1 ГиБ.

16 bits can be stored in window size field. Maximum of 14 bits can be stored in shift.cnt variable. Thus total bits advertised = 16+14 = 30

Если «сдвиг. cnt» больше 14, TCP зарегистрирует ошибку, но по-прежнему будет использовать «14» вместо большего значения, указанного в параметре «Масштаб окна». Запомнить! коэффициент масштабирования применяется только к полю «Размер окна» заголовка TCP, а не к «переменным», в которых хранятся «значения окна» на локальных компьютерах.

Командные строки Linux:

Проверка настройки по умолчанию масштабирования окна TCP в ядре Linux

$ sysctl net.ipv4.tcp_window_scaling

Ожидаемый результат (это означает, что масштабирование окна TCP включено):

$ net.ipv4.tcp_window_scaling = 1

Отключить масштабирование TCP-окна (не рекомендуется, но попробуйте изучить и снова включить)

$ sudo sysctl -w net.ipv4.tcp_window_scaling=0

Ожидаемый результат:

$ net.ipv4.tcp_window_scaling = 0