Туннелирование (компьютерные сети). Где актуально использование PMTUD

IP protocol был разработан для самых различных типов подключений, и хотя максимальная длина для IP datagram составляет 64K, большинство подключений (transmission links) используют меньший максимальный размер для IP-пакета или MTU.
MTU, Maximum Transmission Unit - максимальный размер блока в байтах, который может быть передан на канальном уровне сетевой модели OSI.

Значение MTU зависит от типа подключения. Дизайн IP сетей допускает возможность фрагментирования IP пакетов в том случае когда MTU меньше размера пакета, - в этом случае принимающая станция вновь собирает искомый пакет из фрагментов.

На рисунке отображен заголовок IP пакета и то, как он инкапсулируется в датаграмму второго уровня.
Здесь важно отметить, что в поле FLAGS включает в себя три бита, один из которых "don"t fragment" (DF) bit , который определяет разрешено данный пакет фрагментировать или нет.

Вопросы с IP фрагментированием

Хотя фрагментация пакета выполняется достаточно быстро, обратная сборка исходного пакета требует значительных ресурсов: затрат памяти, вопросы быстродействия.
В случае потери одного из фрагментов вся датаграмма должна быть передана заново.
Фрагметы очень тяжело обрабатывать на брендмауэрах (с 4-го по 7 уровень), при неправильной последовательности они будут забракованы.

TCP MSS и избегание дефрагментации


TCP Maximum Segment Size (MSS) - определяет максимальный размер датаграммы TCP/IP, которую будет принимать данный хост.
Датаграмма TCP/IP может быть фрагментирована на уровне IP.
Значение MSS отсылается внутри TCP header только в сегментах TCP SYN. Каждая сторона TCP соединения объявляет другой стороне свое значение MSS.
Вопреки распространенному мнению, значение MSS не согласовывается между хостами, - у каждого хоста они могут оставаться разными, только отсылающий хост отдает сегменты размером не больше, чем требует принимающий хост.

Таким образом TCP MSS позволяет избежать фрагментации на уровне двух участников сессии TCP. Но TCP MSS не может обработать тот случай, когда по пути между хостами есть меньший MTU.

PMTUD

PMTUD (Path Maximum Transmission Unit Discovery) - был разработан для избегания фрагментации по пути между хостами. PMTUD используется для автоматического определения минимального MTU вдоль пути пакета между хостами.

PMTUD поддерживается только TCP, UDP и другие протоколы не поддерживают PMTUD.

Хост отсылает нефрагментированный пакет с установленным DF bit . Если маршрутизатор пытается отдать пакет на link, с меньшей MTU чем этот пакет, маршрутизатор дропнет этот пакет и возвратит сообщение ICMP "Destination Unreachable", с кодом "fragmentation needed and DF set" (type 3, code 4). Когда Хост-источник получает эту информацию, он понижает MSS и затем пересылает TCP сегмент заново.

Наиболее часто встречающаяся проблема с PMTUD - это среда в которой не пропускается сообщения ICMP

Где актуально использование PMTUD

Как уже было сказано, PMTUD нужен в случаях, когда по пути от хоста А к хосту Б встречаются линки с меньшими значениями MTU.
Наиболее общие примеры:
- PPPoE (часто используемый вместе с ADSL) использует 8 bytes для своего заголовка. Это уменьшает эффективное значение MTU для Ethernet до 1492 (1500 - 8).
- Туннельный протоколы GRE, IPsec, and L2TP также используют пространство для своих заголовков, что также уменьшает эффективное MTU на исходящем интерфейсе.

Вообще Path MTU Discovery (RFC 1191) осуществляется всеми клиентами включая Windows 2000/2003/XP/7/8.
Для нормальной работы PMTUD необходимо, чтобы пропускался протокол ICMP, в частности должны пропускаться сообщения ICMP "unreachable" и "time-exceeded".

Для проверки можно использовать утилиту mturoute.exe. Утилита отрабатывает аналогично PMTUD и возвращает значение MTU, которое необходимо использовать на данном хосте.

Текущее значение MTU можно увидеть через команды:
Windows 7, Windows Vista: netsh interface ipv4 show subinterfaces
Windows XP: netsh interface ip show interface

Значения MTU для локальной машины можно поменять и вручную (хотя и не рекомендуется)
Adjusting IP MTU, TCP MSS, and PMTUD on Windows and Sun Systems
Также можно использовать утилиту Set MTU, поставляемой с Cisco Systems VPN Client.

Что такое туннель

Туннель - это логический интерфейс на маршрутизаторе, который обеспечивает инкапсуляцию полезных пакетов внутрь транспортного протокола.

Туннель состоит из основных компонентов:
- Passenger protocol
- Carrier protocol . Протокол, осуществляющий инкапсуляцию:
GRE
IP in IP tunnels
- Transport protocol . Протокол отвечающий за маршрутизацию encapsulated protocol. В нашем случае это IP.


На приведенном рисунке IP у нас выступает как transport protocol и как passenger protocol .

Инкапсуляция трафика дает следующие преимущества:

  • Endpoints могут использовать private addresses
  • Позволяет строить VPN поверх WAN сетей
  • Возможность использования шифрования

Исходя из того, что наиболее "тяжелый" вариант - это одновременное использование GRE и IPsec, рекомендации будут следующие:
- PMTUD позволяет установить на GRE интерфейсе оптимальное значение MTU и включается на туннельном интерфейсе командой tunnel path-mtu-discovery
- Обеспечьте нормальную работу PMTUD, при этом на обоих целевых хостах должна успешно выполняться mturoute.exe
- Также рекомендуется одновременно использовать и команду ip mtu 1400 . В этом случае ip mtu будет обеспечивать пространство для GRE + IPSec, в случае же более низких значениях MTU по пути, IP MTU бует подкорректировано динамически. Значение 1400 рекомендовано, т.к. оно покрывает большинство возможных комбинаций GRE + IPSec.
- Следует использовать ip tcp adjust-mss 1360 на туннельном интерфейсе. Это позволит маршрутизатору уменьшить значение TCP MSS в TCP SYN Packet. Что позволить двух конечным хостам генерировать достаточно малые пакеты. (1360 = 1400 - 20(TCP) - 20 (IP))

Общий конфиг для туннельного интефейса DMVPN + IPSec будет выглядеть:
interface Tunnel200
description ### DMVPN TUNNEL HUB
ip address 10.5.0.1 255.255.255.0
no ip redirects
ip mtu 1400
tunnel path-mtu-discovery
ip nbar protocol-discovery
ip hold-time eigrp 1 35
no ip next-hop-self eigrp 1
ip flow ingress
ip flow egress
ip nhrp authentication baurus
ip nhrp map multicast dynamic
ip nhrp network-id 200
ip tcp adjust-mss 1360
no ip split-horizon eigrp 1
delay 100000
tunnel source 87.237.40.107
tunnel mode gre multipoint
tunnel key 123
tunnel protection ipsec profile DMVPN

Я ищу программное обеспечение для туннелирования RDP или другого двоичного TCP-трафика через туннель HTTPS. Поскольку многие клиенты имеют только HTTP/S, разрешены (только порт 80 и 443 открыты в брандмауэре).

Но есть необходимость пересылать RDP (и другие протоколы) с машин в DMZ на клиентов.

Есть ли какое-либо программное обеспечение с открытым исходным кодом или корпоративное программное обеспечение для этой проблемы?

Плохие решения

Если бы было возможно, что клиент туннеля не будет выделенным сервером, а java-апптом флэш-памяти, запущенным в браузере клиентов, он будет соответствовать 100% моим потребностям.

3 ответов

Существует огромное количество проектов, которые туннелируют TCP через HTTP (S). Вам нужно будет немного поработать, чтобы выбрать тот, который наилучшим образом соответствует вашим потребностям (и, вероятно, немного измените его).

    Если вы находитесь в мире Windows, я настоятельно рекомендую взглянуть на службу SSTP VPN в Windows 2008/2008R2/2012. Он использует порт 443 и может быть совместно с IIS (на 443). Он работает как прелесть в Windows Vista/7/8. Я слышал о Mac OSX решениях, но еще нет.

    Однако есть хорошее старое решение SSH.

    Если на linux просто установите openssh-сервер. Если в окнах получить и установить сервер OpenSSH (например, copSSH из itefix https://www.itefix.no/). Измените порт, который будет использовать 443 вместо значения по умолчанию 22.

    На стороне клиента можно использовать Putty (

Кстати, всё что здесь описано, делалось, если не сказано дополнительно, под altlinux sisyphus. И всё ещё работает на моих машинах:)

1. Вводная: для чего вообще нужны туннели?

1.1. Небольшое описание

Вообще туннель, это по сути отдельный виртуальный провод, протянутый от одного peer"а к другому.
Чем это хорошо: между peer"ами могут идти море маршрутизаторов, но в туннеле они не видны . Для машин-peer"ов туннель является физической средой передачи, а значит противоположный конец туннеля можно прописывать в таблицу маршрутизации. В итоге трафик, завёрнутый в туннель, может выходить где-нибудь в америке (смех смехом, а при спутниковом доступе так и происходит), а возвращаться обсолютно другим маршрутом - маршрут возврата зависит от ip-источника. В этом туннели очень похожи на прокси.

1.2. Отличия туннелей от прокси:

  • Прокси кроме всего прочего кешируют. Туннель - это просто среда передачи, так что ни о каком кешиваронии не может быть и реси. Проводам наплевать на информацию, по ним передаваемую. Их задача - передать.
  • Туннели в OS, с ними работающей, представляются как отдельный интерфейс, а значит для работы с ними достаточно настроить tcp/ip протокол (маршруты, firewall), когда для прокси надо настроить каждую программу.

Схожесть:

  • Возможность организации аутентификации, шифрации трафика
  • Возможность изменения маршрута трафика (в прокси это реализуется через иерархию.)

1.3. Пример применения

Например задача: исходящий трафик посылать по земле, ответы принимать через спутник. (Для Настройки спутника см. Sky Star 2 )
То есть, трафик исходит с вашего интернет-интерфейса, идёт по одному маршруту к назначению, а приходит по другому и на другой интерфейс.


Как происходит маршрутизация? Трафик в одну сторону дойдёт по ip-назначению. Обратно он будет идти также по ip-назначения, только он будет уже вашим ip (при ответе ip сменяться местами). Значит надо послать пакет с ip-источником от провайдера, что зарулит трафик к вам. Какие могут быть здесь проблемы: провайдер не будет выдавать тысячи ip каждому, чтобы они ставили его для ответа. Да и те же продукты от MS тяжело будет таким образом отстроить.


Какая тут на самомо деле проблема: маршруты не прохдят через спутникового оператора, они могу идти как угодно. Если бы они проходили через него, то с помощью SNAT можно ответ получать на оператора а затем на пользователя. SANT там делается (не совсем удобно: в итоге с одного ip качают тысячи поьзователей, что не на всех сайтах разрешается:)


Вот для организации прохождения всего наземного трафика через спутникового оператора самое то использовать либо прокси, либо туннели. Поднимаем туннель, указываем его маршрутом по умолчанию - и всеь трафик будет сначала идти оператору, а потом куда надо. Ответ тоже пройдёт через него, а далее по спутнику.


Меня тут просили организовать success story по работе и настройке туннелей. Ну что ж, вот вам романы: :)

1.4. Типы туннелей

Есть два типа туннелей:

  • сетевого уровня (то есть уровня ip протокола)
  • транстпортного уровня (работающие на tcp либо udp)

Ну, если постараться, можно сваять туннель и прикладного уровня: через http протокол например через тот же прокси. google it: httptunnel, proxytunnel. Но, как и ssh port-forwaring, это не туннели Хотя иного без них никуда:)


Где-то тут наверное можно прислонить и vlan, только с ними я пока не сталкивался, знаю лишь что ьам в существующей сетевой стреде организуется дополнительная вирутуальная. В отличие от туннелей позволяет организовать не только соединение точка-точка, но и реальную сеть с broadcast"ами и всем остальным. Рабоет на сетевом уровне


Есть туннели PPPoE - point-to-point over ethernet. Что это такое я так пока и не понял, наверное потому что опять не использовал. Куда их отнести - понятия не имею. Жду подсказки:)

2. Туннели сетевого уровня

2.1. Что ето такое

Это ipip и ip_gre туннели. Может и ещё что-то есть: я с ними пока не работал. Как они выглядят вживую:
# tcpdump -t proto gre -n IP 192.168.0.2 > 192.168.0.1: IP 192.168.2.42.58974 > 81.176.64.123.http: . 955:2391(1436) ack 1 win 1460 IP 192.168.0.1 > 192.168.0.2: IP 81.19.70.1.http > 192.168.2.42.58972: . ack 594 win 8760


Если посмотреть, то видно, что IP повторяется два раза, ip заголовки тоже. В принципе туннели так и работают: в ip пакет вместо tcp пакета (или udp, icmp, или что там ещё есть) заворачивается ещё один ip пакет, а в поле «протокол» в пакете вместо 6 для tcp, 1 для icmp ставится 47 для gre и 94 для ipip (номера протоколов находятся в файле /etc/protocols. если поискать под offtopic"ом, то там тоже наверняка найдтся такой файлик: services есть, почему бы и не быть protocols:)


точно также , только туннельный ip пакет со всеми своими данными заворачивается в tcp пакет. То есть организуется обычное подключение и в tcp поток льется ip траффик.

2.2. Настройка

Ну, это наверно проще поискать.
Вкратце ручками это делается следующим образом:
modprobe ip_gre ip tunnel add mode gre local remote # создать девайс ip addr add dev # добавить адрес ip link set up # включить
ну, и осталось добавить нужные вам маршрутизаторы.
Для ipip тоже самое, только меняется mode

2.3. IPSEC туннель

ipsec, как я понял, может работать в двух режимах: простая шифрация нужного трафика (скажем от одного порта к дргому), и в туннельном, в котором нужно будет прописать отдельную подсеть.


Вообще ipsec это отдельный разговор , я взялся за него только недавно, поэтому пока оставим так. пусть кто-нить опишет - буду благодарен. Всё равно мне его ещё реализовывать.

3. Туннели транспортного уровня

Туннели транспортного уровня работают точно также как и сетевого , только туннельный ip пакет со всеми своими данными заворачивается в tcp пакет. То есть организуется обычное подключение и в tcp поток льется ip траффик. Для udp, как всегда, подключение надо организовывать самому. Но принцип тот же.


В принципе туннель можно сделать хоть через icmp протокол, благо в ip заголовке указывается полная длина пакета с icmp + какие надо прописать данные. а ведь icmp пакеты обычно пропускаются на маршрутизаторах... Хотя могу обрадовать - никто не мешает в firewall"е настроить блокировку на длину icmp пакета:))


Какие есть реализации:

  • pptp, поддерживается MS
  • pppoe (точно здесь должен быть?)
  • ppp over ssh
  • vtund

Требует написания:)

3.1. PPTP

3.2. PPPoE

Туннель, в котором пакеты протокола PPP прокидываются внутри пакетов Ethernet, т.е. обычно ниже уровня IP. Позволяет слегка уменьшить накладные расходы, если между точками работает сеть Ethernet. Однако не маршрутизируется, как туннели поверх IP.
http://www.roaringpenguin.com/slides/pppoe-slides.pdf
http://www.roaringpenguin.com/pppoe/als-pppoe-paper.pdf
Есть модификация PPPoA (поверх ячеек протокола ATM, обычно используется в ADSL наряду с PPPoE).
Не путать с термином Po E (Power over Ethernet) — это тоже туннель, но для электропитания по витой паре)

3.3. PPP over SSH

Прекрасно настраивается по . Когда у меня встала задача выйти через прокси в irc, imap мне как раз пришлось настроить

Сети операторов связи могут также предоставлять услуги виртуальных частных сетей на основе техники туннелирования. Эта техника уже рассматривалась нами на частном примере туннелирования трафика IPv6 через 1Р\4-сеть. Так как техника туннелирования весьма распространена, здесь мы рассмотрим ее с общих позиций.

Туннелирование у или инкапсуляция, - это нестандартный (отличающийся от принятого в модели OSI порядка) способ инкапсуляции пакетов некоторого протокола двух объединяемых сетей или узлов в пакеты протокола транзитной сети на ее границе и передача пакетов объединяемых сетей через транзитную сеть. Туннелирование применяется в тех случаях, когда транзитная сеть либо не поддерживает протокол объединяемых сетей, либо стремится изолировать транзитную сеть от объединяемых сетей.

Данное описание подходит к стандартной схеме, описанной в модели OSI, если под протоколом объединяемых сетей понимать протокол IP, а под протоколом транзитной сети - любой протокол канального уровня, например Ethernet. Действительно, IP-пакеты могут инкапсулироваться на границе сети в кадры Ethernet и передаваться в этих кадрах через транзитную сеть Ethernet в неизменном виде. А при выходе из транзитной сети IP-пакеты извлекаются из кадров Ethernet и дальше уже обрабатываются маршрутизатором.

Для того чтобы понять, в чем нестандартность инкапсуляции, сначала заметим, что в этом процессе принимают участие три типа протоколов:

  • протокол-пассажир;
  • несущий протокол;
  • протокол инкапсуляции.

При стандартной работе составной сети, описанной в модели OSI (и повсеместно применяемой на практике), протоколом-«пассажиром» является протокол IP, а несущим протоколом - один из протоколов канального уровня отдельных сетей, входящих в составную сеть, например Frame Relay или Ethernet. Протоколом инкапсуляции также является протокол IP, для которого функции инкапсуляции описаны в стандартах RFC для каждой существующей технологии канального уровня.

При туннелировании протоколом-пассажиром является протокол объединяемых сетей, это может быть протокол канального уровня, не поддерживаемый транзитной сетью, или же протокол сетевого уровня, например протокол IPv6, отличный от протокола сетевого уровня транзитной сети.

На рис. 1 показан пример сети, в которой трафик сетей Frame Relay передается по туннелю через транзитную IP-сеть, канальный уровень которой эту технологию не поддерживает, так как построен на технологии Ethernet,

Рис. 1. Туннелирование трафика Frame Relay через ІР-сеть

Таким образом, протоколом-пассажиром является протокол а несущим протоколом - протокол IР. Пакеты протокола-пассажира помещаются в поле данных пакетов несущего протокола с помощью протокола инкапсуляции. Инкапсуляция FR-кaдpoв в IР-пакеты не является стандартной операцией для IР-маршрутизаторов. Это дополнительная для маршрутизаторов функция описывается отдельным стандартом и должна поддерживаться пограничными маршрутизаторами транзитной сети, если мы хотим организовать такой туннель.

Инкапсуляцию выполняет пограничное устройство (обычно маршрутизатор или шлюз), которое располагается на границе между исходной и транзитной сетями. Пакеты протокола-пассажира при транспортировке их по транзитной сети никак не обрабатываются. Извлечение пакетов-пассажиров из несущих пакетов выполняет второе пограничное устройство, которое находится на границе между транзитной сетью и сетью назначения. Пограничные маршрутизаторы указывают в IP-пакетах, переносящих трафик туннеля, свои IP-адреса в качестве адресов назначения и источника.

В связи с популярностью Интернета и стека TCP/IP ситуация, когда несущим протоколом транзитной сети обычно выступает протокол IP, а протоколом-пассажиром - некоторый канальный протокол, является очень распространенной. Вместе с тем применяются и другие схемы инкапсуляции, такие как инкапсуляция IP в IP, Ethernet в MPLS, Ethernet в Ethernet. Подобные схемы инкапсуляции нужны не только для того, чтобы согласовать транспортные протоколы, но и для других целей, например для шифрования исходного трафика или для изоляции адресного пространства транзитной сети провайдера от адресного пространства пользовательских сетей.

Есть расхожее мнение, что сетевые туннели выгоднее делать на основе протоколов низкого уровня с минимальными размерами заголовков и очень простым протоколом. Считается, что TCP как несущий протокол создает много проблем. Так ли это?

Использование TCP стало столь привычным, что большинство просто не задумывается о заложенных в этот протокол механизмах и во всех случаях полагается на «интеллект» системы. Одновременно с этим, если встречаются какие-то сведения, объясняющие что-то в его поведении, или теории, построенные на основе, так сказать, «упрощенных» представлений, то у многих просто недостает знаний правильно оценить полученную информацию. Что приводит к появлению технологических мифов. Один из которых, порожденный статьей Олафа Титца (Olaf Titz), здесь и попробуем опровергнуть. К сожалению, в России все, что написано на иностранном языке да еще размещено на зарубежном сайте, воспринимается как святое откровение. Хотя многие далее вынесенного в ее заголовок тезиса «Why TCP Over TCP Is A Bad Idea» и не читают. Чтобы уравнять шансы тех, кто имеет затруднения с английским языком, предложим дословный технический перевод упомянутого опуса . В переводе не использовались никакие литературные экстраполяции, чтобы максимально точно донести идеи автора и ни в коем случае не исправить на этапе перевода что-то из многочисленных его ошибок. Разберем текст этой статьи.

Суть проблемы

Итак, первое, что по мнению Олафа, мешает эффективной работе TCP в качестве туннеля, это повторные передачи. Если отбросить туманные рассуждения о насыщении канала (meltdown) из-за мифического фиксированного тайм-аута, которого нет в TCP, то в «сухом остатке» в первом разделе статьи лишь утверждение об экспоненциальном росте тайм-аута, если, цитирую, «сегмент задерживается сверх тайм-аута». Рассмотрим подробнее. Автор упорно не желает использовать общепринятую терминологию и предпочитает изъясняться как колдун-друид. Но так как в тексте упоминается RFC2001, то можно воспользоваться ссылкой и попытаться догадаться, на что намекает Олаф Титц. Единственный показатель, имеющий в RFC2001 экспоненциальный рост, – это CWND (congestion window). Но окно насыщения, или CWND, связано с пропускной способностью прямой зависимостью. Автор же намекает, что задержки растут по экспоненте и это якобы приводит к снижению темпа передачи. Задержки – это RTT (round trip time), или время обращения, на основании которых высчитывается RTO (retransmission time out), или таймер повтора. Об этом нет ничего в RFC2001. Но по другим документам можно узнать, как это происходит. Например, в RFC793 , упоминаемом также в статье, описан метод расчета RTO для каждого текущего пакета. Так вот, там используется показатель SRTT (smooted round trip time), или взвешенное время обращения. Подчеркиваю – взвешенное! Где тут Олаф «раскопал» экспоненту? Конечно, можно догадаться, что автор спутал расчет RTO при задержке с расчетом RTO при потере! Вот, если бы сегмент вообще пропал и от получателя нет никаких ответов, тогда алгоритм TCP на самом деле требует произвести повторы с экспоненциальным замедлением. Но, не смущаясь мелкими деталями, Олаф связывает увеличение периодов проверки на обрыв соединения с борьбой с насыщением, то есть с тем самым meltdown, который, как ружье со стены в известной пьесе, если упомянуто в первом акте, то далее обязательно «выстрелит». Таким образом, поскольку экспоненциального роста задержек передачи в TCP нет, то измышления первой части обсуждаемой статьи не имеют отношения к реализации TCP в нашей с вами Вселенной.

Рассуждения Олафа, где он считает, что трафик TCP в Интернете регулируется тайм-аутами, просто выкинем, как не соответствующие реальности и потому не актуальные. Конечно, можно было бы везде, где в тексте встречается «timeout», при переводе подставить «таймер», что сильно приблизит многие рассуждения к действительному положению дел, но тогда пришлось бы исправить и многое другое. Но, как уже было сказано выше, перевод сделан самым безжалостным способом.

Второе, что смутило Олафа Титца – это взаимодействие транспортного TCP и транспортируемого. Для ясности обратимся к схеме инкапсуляции, которая обсуждается в . Скопируем ее в переводном варианте и добавим немного комментариев.

Автор утверждает, что эти два потока TCP (см. рис. 1) могут иметь разные таймеры. Дословно: «может так случиться, что соединение нижнего уровня имеет медленные таймеры, возможно как остаток с периода медленного или ненадежного основного соединения». То есть автор предположил, что вложенное TCP успело разогнаться, а несущее тем не менее оставалось медленным. Это просто невозможно, так как противоречит законам сохранения, действующим в нашей Вселенной. Надо признать, что именно здесь Олафа «понесло». Он увлеченно живописует, как внутренний слой, такой быстрый и такой «несчастный», будет, не получая подтверждений, посылать пакет за пакетом и тем самым – вот оно, старое ружье выстрелило – создаст «внутренний meltdown-эффект». Здесь замечу, что термин «внутренний meltdown-эффект» изобретен просто «на ходу». Жаль разочаровывать Олафа, но после неподтверждения пакета и в отсутствие вообще всяких подтверждений TCP начинает процедуру медленного старта, в ходе которой поток TCP снова будет искать предельную передающую возможность среды, постепенно увеличивая скорость передачи, начиная с самых минимальных значений. Иначе говоря, TCP не снижает темп передачи, а вообще прекращает ее и затем возобновляет снова со стартовых значений. И это, кстати, дает гарантию, что внутренний TCP никогда не будет работать быстрее внешнего, того, что образует туннель. Так как, если параметры внутреннего TCP приведут к тому, что он разгонится быстрее туннельного, то после же столкновения он сбросится снова к состоянию медленного старта и снова начнет «догонять» туннельный TCP.

Давайте представим, что реально может случиться изза потерь сегментов (именно так и следует далее их называть, а не пакетами) в таком туннеле. Во-первых, просто обрыв связи будет обработан и тем и другим TCP соответственно и в пределах перечисленных RFC. А вот с повторами, и правда, могут возникнуть некоторые проблемы. Покажем на схеме (рис. 2), что будет происходить, если в пути потеряется сегмент с данными.

Предположим, что пропал сегмент D4. Тогда оба стека протоколов получат повторный ACK с последним принятым номером и согласно алгоритму Fast Retransmission, или быстрой повторной передачи, пропущенный пакет будет повторен. На рисунке изображена ситуация, когда оба стека имеют одинаковый RTT и, значит, близкие RTO. Тогда транспортный TCP сформирует повтор пропавшего сегмента T44 и точно так же добавит в поток сегмент T7-4, содержащий сегмент с данными D4, повторенный в транспортируемом TCP. Это самый худший вариант развития событий. Иначе говоря, если потери канала составляют 10%, то из полезной емкости канала будет изъято уже 20%. Но, как уже замечено, это предельно плохой вариант. Поскольку RTT туннеля и RTT транспортируемого TCP на практике не совпадают, то, скорее всего, реальные потери полосы будут гораздо меньше.

Может показаться, что в этих рассуждениях упущена ситуация, когда будет потерян не сегмент с данными, а его подтверждение. Но если это произойдет, все случится точно так же, как и на рис. 2.

Для TCP нет разницы между потерянным сегментом и потерянным подтверждением, если и те и другие высылаются не так, как рассуждает Олаф, а сериями в пределах размера CWND. Но, с другой стороны, теперь уже для TCPтрафика происходит теоретическое учетверение потерь, то есть из полезной емкости канала будет изыматься уже 40%. Хотя это лишь «на бумаге», то есть снова здесь приведен самый плохой вариант.

Теперь, глядя на рис. 2, ответьте, в каком TCP надо запретить повторы? Олаф Титц делает вывод, что повторы надо запретить в верхнем транспортируемом TCP. На самом деле, повторы следует запретить в нижнем туннельном TCP.

Во-первых, потому что туннель это одно TCP-соединение, а вложенных может быть множество.

Вовторых, потому что туннель создается на специальном хосте, а внутренние потоки соединяют разные клиентские компьютеры со стандартным TCP-стеком. И, наконец, втретьих, кроме TCP есть еще много разных протоколов, сегменты c которыми все-таки очень не бесполезно восстановить при потере, а отличить их от TCP может только стек туннеля. Но такое расширение TCP-туннелей пока не реализовано. Здесь лишь рассматривается гипотетическая возможность. Но ничего не мешает в практической ситуации для пробы запретить повторы через параметры sysctl линуксового ядра на тех хостах, между которыми поднят туннель, и проверить действенность такой настройки.

Итак, и вторая часть рассуждений о проблемах TCP не выдерживает элементарной проверки. Быть может, в разделе «Практический опыт» нам откроется истина? Рассмотрим и его повнимательнее.

В практической части статьи содержится информация, которая может стать разгадкой всех проблем Олафа Титца. Оказывается, у автора этой статьи, цитирую, «использовалась волоконно-оптическая связь, которая страдала частыми потерями пакетов, иногда 1020%». Странная связь! Вероятно, на карманных фонариках. Последннее конечно шутка, но тем не менее это позволяет точно определить условия применения тезисов автора упомянутой статьи. Обратимся к RFC 2001 . Там однозначно установлено, что все алгоритмы TCP рассчитаны при допущении, что потери в канале составляют менее 1%. Вероятно, у Олафа были проблемы с кабельщиком. Быть может, суровому монтеру не понравилась его прическа и он решил таким путем выразить свое возмущение. Олаф утверждает, что, создав CIPE , смог решить проблемы и обеспечить надежную работу на канале с потерями до 20%. И если не проверить утверждения автора с помощью тестов с туннелем на подобном канале, то получится, что здесь предлагается рассуждения Олафа Титца заменить рассуждениями Алексея Барабанова. Лишь опыт позволит рассудить, на чьей стороне правда (или правдоподобность). Поскольку нет простой возможности создать искусственную линию связи с характеристиками, похожими на те, что создали так много проблем Олафу, то заменим реальные, обычно модулированные, помехи случайными. И дополнительно ограничим их 10-процентными. Думаю, что эта замена, не помешает понять суть происходящих процессов, так как на практике и 10% и 20% значительно больше указанного в RFC 1%, и отличаются лишь временем, затраченным на проведение эксперимента, поскольку чем больше потери, тем меньше скорость передачи.

Тестовая сеть

Проверку будем проводить путем передачи тестового массива псевдослучайных данных в одном направлении через TCP- и UDP-туннели. Это, конечно, примитивная модель взаимодействия, но только так можно в чистом виде попытаться определить зависимость характеристик канала и свойств полученного потока данных. Дополнительно в центре маршрута ограничим полосу, например до 10 Мбит, и внесем случайные потери в трафик. Конечно, 10 Мбит значительно выше типичной скорости канала, предоставленного ISP для подключения к Интернету. Но иначе придется уменьшить объем пересылаемых данных, чтобы в приемлемое время провести эксперимент. Перечислим элементы, которые нужны для организации таких проверок. Во-первых, хост-отправитель и хост-получатель трафика. Во-вторых, два хоста, между которыми проложен туннель. Поскольку «удаленный» конец туннеля может совпадать с хостом-получателем, то, кроме перечисленных трех хостов, нужен еще один, где будет эмулироваться «узкое место» в сети. Итого, достаточно будет 4 компьютера соединить последовательно. Строго говоря, хост-отправитель можно совместить с «ближним» концом туннеля. Но надо учесть, что вход в туннель тоже является своего рода ограничителем трафика, или шейпером, поэтому пусть будут в тестовой сети четыре компьютера, которые назовем wstovert, wsalekseybb, wskostja и server. Общий вид полученной сети представлен на рис. 3, и дальнейший комментарий будем вести согласно изображенной там схемы.

Все компьютеры включены в общую сеть 192.168.0.0/24, объединены общей кабельной системой с помощью коммутатора 1 Гбит и обмениваются данными по протоколу 1000BaseTX, то есть значительно выше проверяемых скоростей передачи, что позволит максимально снизить систематическую ошибку. На эту сеть наложены две виртуальные сети. Первая из них, с адресом 192.168.10.0/24 включает wstovert, wsalekseybb и server, а вторая – с адресом 192.168.11.0/24 – только server и wskostja. Практически все компьютеры могут резолвить адреса друг друга с помощью arp и обмениваться пакетами через общий коммутатор. Но нам ведь нам надо обеспечить передачу трафика между компьютерами так, будто они включены последовательно один за другим. Поэтому с помощью правил маршрутизации и преобразования адресов заставим трафик от wstovert проходить до wskostja через wsalekseybb и server так, как указывает стрелка на рис. 3. Для этого на каждом компьютере укажем статический маршрут до следующей по ходу движения стрелки на рис. 3 сети через соседний компьютер, а на том включим NAT так, чтобы заменять в таком маршруте адрес отправителя на собственный. Окончательно должно получиться так:

# traceroute 192.168.11.2

traceroute to 192.168.11.2 (192.168.11.2), 30 hops max, 40 byte packets

1 192.168.10.2 0.000 ms 0.000 ms 0.000 ms

2 192.168.10.1 0.566 ms 0.086 ms 0.088 ms

3 192.168.11.2 0.145 ms 0.170 ms 0.241 ms

Поскольку главный вопрос заключается в изучении поведения инкапсулированного трафика, то в тестовой сети настроим также и туннель. Воспользуемся программным обеспечением, которое позволит поднять туннель, как на основе UDP-транспорта, так и TCP. По этой причине CIPE не подходит. Выберем OpenVPN . Тем более что согласно сравнительной таблице этот проект рекордсмен в разделе Popularity. Туннельная сеть образует виртуальное соединение между wsalekseybb и wskostja, определенное как сеть 192.168.12.0/24. Для станции wsalekseybb настройки OpenVPN в режиме клиента TCP-туннеля будут производиться согласно следующему файлу конфигурации:

# cat /etc/openvpn/test.conf

proto tcp-client

tcp-queue-limit 1000

remote 192.168.11.2

dev tun

port 5000

tcqueuelen 1000

secret /etc/openvpn/static.key

ifconfig 192.168.12.1 192.168.12.2

route 192.168.12.0 255.255.255.0 192.168.12.1

Для станции wskostja все аналогично, меняются лишь адреса, протокол на tcp-server и удаляется строка remote, что переводит туннель в состояние прослушивания. В режиме UDP на обоих концах протокол просто переключается в udp и удаляется параметр tcp-queue-limit. И теперь путь между wstovert до wskostja проходит через туннель.

# traceroute 192.168.12.2

Таким образом, можно, отправляя трафик со станции wstovert до станции wskostja, осуществлять на промежуточном хосте server нужные манипуляции в соответствии с исследуемой моделью канала.

Для работы создадим на всех участвующих в экспериментах хостах специального пользователя tovert и разместим в его домашних директориях в файле.ssh/authorized_keys2 специально подготовленные ключи, чтобы можно было выполнять необходимые действия в автоматическом режиме с одной из станций. И для удобства разрешим через sudo выполнение пользователем tovert команд с привилегиями суперпользователя без ввода пароля.

На wstovert подготовим файл с данными, которые будут посылаться в тестовых сеансах:

# ssh tovert@wstovert "dd if=/dev/urandom of=~/100M.bin bs=1024 count=102400"

Симуляцию TCP-трафика будем создавать с помощью команды, отправляющей 100 Мб из файла на целевой хост. В качестве слушателя TCP используем sshd, который перешлет все принятые данные в /dev/null, чтобы не помешала буферизация. Причем для сокращения затрат на загрузку файла с диска каждую тестовую отправку будем предварять локальным копированием в /dev/null:

# dd if=/home/tovert/100M.bin bs=1024 count=102400 >>/dev/null

# dd if=/home/tovert/100M.bin bs=1024 count=102400 | ssh [email protected] "cat - >>/dev/null"

Симуляция UDP-трафика будет производить утилитой netcat, точно так же предварительно произведя локальное копирование:

# dd if=/home/tovert/100M.bin bs=1024 count=102400 >>/dev/null

# dd if=/home/tovert/100M.bin bs=1024 count=102400 | netcat -vu -w 1 192.168.12.2 22222

На приемной стороне UDP-трафик будет приниматься специальным слушателем и подсчитываться:

# netcat -vlnu -s 192.168.12.2 -w 15 -p 22222 | wc -c

В точке прохождения трафика через хост server включим ограничитель полосы типа HTB (Hierarchical Token Buckets) на 10 Мбит со следующей конфигурацией:

qdisc htb 1: r2q 10 default 0 direct_packets_stat 0

class htb 1:1 root rate 10Mbit ceil 10Mbit burst 14704b cburst 14704b

Sent 0 bytes 0 pkts (dropped 0, overlimits 0)

Tokens: 9191 ctokens: 9191

class htb 1:10 parent 1:1 prio 0 rate 10Mbit ceil 10Mbit burst 14704b cburst 14704b

Sent 0 bytes 0 pkts (dropped 0, overlimits 0)

Lended: 0 borrowed: 0 giants: 0

Tokens: 9191 ctokens: 9191

filter parent 1: protocol ip pref 1 fw

filter parent 1: protocol ip pref 1 fw handle 0xa classid 1:10

Так что фильтр будет направлять в шейпер только трафик, помеченный маркером 10 (0xa). Весь непомеченный трафик будет проходить в обход шейпера, так как в HTB не указан поток по умолчанию. Метиться будут лишь пакеты, направляемые на виртуальный адрес wskostja:

# traceroute 192.168.11.2

Тут проницательный читатель заметит, что недостает еще эмулятора помех для обратного трафика. Но какой может быть обратный трафик у UDP? И внося еще помехи для пакетов, движущихся в обратную сторону, мы явно ухудшаем характеристики всех TCP-соединений, которые принципиально всегда интерактивны, в отличие от UDP. Скажите несправедливо? Ну и пусть! Нам нечего бояться. Сделаем так:

# iptables -n -L OUTPUT

Chain OUTPUT (policy ACCEPT)

target prot opt source destination

DROP all -- 192.168.12.2 0.0.0.0/0 random 10%

ACCEPT all -- 192.168.12.2 0.0.0.0/0

Чуть выше уже было замечено, что это очень грубая имитация линии с потерями. Дело в том, что потери являются функцией линии передачи, а не числа переданных пакетов, как в нашем случае. Но даже такая модель позволит понять, что же происходит с трафиком в ненадежных сетях.

Теперь все окружение построено. Договоримся о точках, где будут сниматься данные. В условиях эксперимента будет тип трафика, тип туннеля, объем отправленных с wstovert данных. Скорость передачи нам сообщит команда dd на wstovert. Объем данных, поступивших в туннель, и число уничтоженных на входе пакетов узнаем через ifconfig tun0 на wsalekseybb. Статистика шейпера на server покажет, сколько данных и пакетов прошло через ограничитель трафика, сколько пакетов было уничтожено. На счетчиках iptables на wskostja узнаем, сколько данных добралось до назначения и сколько было уничтожено как имитация потерь в линии связи. И для UDP после отключения слушателя netcat получим объем реально полученных данных, подсчитанный командой wc.

С примерами некоторых скриптов, использованных для настроек, можно ознакомиться в архиве .

Передача TCP в туннелях

Сначала проверим самую главную версию, что трафик TCP внутри TCP-туннеля якобы плохо передается, а вот внутри туннеля UDP напротив очень хорошо. Для этого поднимем туннель OpenVPN сначала в режиме TCP, затем в режиме UDP, и в каждом состоянии проведем тестовую пересылку без потерь, с потерями 10% и с двухсторонними потерями. Полученные числа соберем в таблицу. К сожалению, так как используется высокоскоростная сеть, тестовый файл невелик, а время не позволяет делать сотни прогонов и затем производить сглаживание результатов, то в таблицу 1 будут занесены наиболее показательные данные из 23 прогонов на каждом условии и дополнительно указан возможный разброс.

Таблица 1. Передача TCP-трафика в туннелях

Протокол передачи данных

Режим туннеля

Передано в tun0, Мб

Скорость передачи, Мбайт/сек

Шейпер, передано Мб

Шейпер, передано пакетов

Шейпер, число задержек

Потери, %

Идеальный трафик шейпера / трафик шейпера

103.9

81218

100951

103.9

0.177 (до 0.188)

152585

5504

1.14

117.2

0.0736

157852

4318

10+10

1.16

103.9

144877

144581

103.9

0.18 (до 0.19)

161677

7995

1.11

117.1

0.0791

164227

6281

10+10

1.13

Колонка 5 не выявила никакого преимущества UDP-туннелей в скорости. Средний разброс показателей +/5%. То есть независимо от несущего протокола внутренний TCP рано или поздно подстраивался под условия передачи и находил примерно одинаковый максимум. А вот показатели колонки 6 имеют более интересную интерпретацию. Итак, в идеальных условиях на шейпере насчитано 112 Мб, как в TCP-туннеле, так и в туннеле UDP. Но, как только включаем уничтожение 10% трафика, туннель UDP ведет себя пропорционально потерям и добавляет уничтоженное повторной пересылкой дополнительных 10% объема 112*11=123,2, что примерно равно полученным 124 Мб на счетчике шейпера (все индексы в колонке 10). Туннель TCP реагирует на уничтожение трафика предсказанным способом – выполняет дублирование повторов, и трафик на шейпере возрастает, но, как это тоже было предсказано, не на полные 20%, а лишь на 14%. Как только включаем уничтожение обратного трафика, то потери еще выше, но опять не 40%, как при полных повторах, и не 20%, а всего лишь 16%! Если сопоставить показатели трафика через туннельный интерфейс (колонка 4) и через шейпер (колонка 6), то использование TCP-транспорта добавляет только 4% к переданному объему по сравнению с применением UDP-туннеля. То есть, 10% трафика «честно» пропадает в линии передачи, а погрешности двойного дублирования не превышают 4%. Замечу, туннель достаточно условен, сетка высокоскоростная, и расхождения RTT минимальны, что показала и утилита traceroute выше по тексту. И все равно не получается полного удвоения или учетверения. В условиях реального туннеля, где RTT будут различаться больше, скорости будут ниже, а потери, скорее всего, будут меньше, разница в условиях прохождения TCP-трафика через TCP- и UDP-туннель станет совсем незаметной.

Другими словами, никакого существенного ухудшения TCP внутри TCP в нашем эксперименте замечено не было. Но если нет ухудшения при работе через TCP-туннель, то, быть может, надо искать улучшение при работе через UDP-туннель? И если проверка TCP-трафика не выявила преимущества одного над другим, то может, стоит проверить, как передается UDP-трафик в таких туннелях.

Передача UDP в туннелях

Передача UDP-трафика – это весьма условное понятие. Фактически это более похоже на ветер. И поэтому понятие «скорость передачи» теряет всякий смысл. В тестовых проверках скорость случайным образом определялась в диапазоне от 13 до 29 Мбайт/сек. Но если на пути такого «ветра» встречается участок с меньшей полосой пропускания, недостаточной, чтобы передать все имитированные пакеты, то излишки просто уничтожаются. Как показали прогоны трафика через туннель OpenVPN вместе с шейпером, настроенным на большие предельные скорости, чем 10 Мбит/сек, сам туннель является скрытым ограничителем полосы. При настройках, согласно, указанным выше, туннель в режиме UDP ограничивает полосу скоростью 5,9 Мбайт/сек, а в режиме TCP даже еще ниже 2,9 Мбайт/сек. Вероятно, это связано с тем, что туннель организован как программа, работающая не в пространстве ядра, а в пользовательском пространстве. Но, так или иначе, потери UDP-трафика начнутся сразу же на входном интерфейсе туннеля, даже если в нем не настроен собственный шейпер. Второй барьер для UDP будет создавать ограничитель трафика, имитирующий «узкое место», взведенный в нашем случае после хоста server. Ну и, наконец, в тестах с потерей трафика дополнительную убыль пакетов UDP обеспечит фильтрация на входе wskostja. Обратный трафик «портить» не будем, так как это не скажется существенно на выводах. Результаты тестов сведены в таблице 2.

Таблица 2. Передача UDP-трафика в туннелях

Протокол передачи данных

Объем отправленных данных, Мб

Режим туннеля

Передано в tun0, Мб

Потеряно в tun0 пакетов

Шейпер, передано Мб

Шейпер, передано пакетов

Шейпер, уничтожено пакетов

Потери, %

Реально прибыло, Мб

Отправлено / прибыло

75375

1.94

1406

1.73

1.04

75195

2.29

1729

1.867

1.12

72744

4490

1611

3.125

1.69

70678

5.02

6441

2611

4.08

1.96

Судя по колонке 4, неявный шейпинг самого туннеля привел к тому, что в режиме TCP «пролетело» в интерфейс в два раза меньше пакетов, чем в режиме UDP. Ну и как следствие, окончательно попало в точку назначения (колонка 10) меньше в режиме TCP, чем в UDP. Поскольку туннель TCP, кроме всего прочего, может подстраиваться под реальную пропускную способность туннеля, то в TCP-режиме на шейпере после server нет потерь, а в UDP они присутствуют. Но самые интересные результаты дает расчет отношения трафика, реально отправленного через туннель, и того, что был получен в точке назначения. И в том и в другом режиме работы туннеля это соотношение подчиняется правилу, что трафик в проверке работы с потерями выше трафика в идеальном случае примерно на величину потерь. Например, для TCP 1,04*1,1=1,14 приблизительно равно 1,12, полученному в эксперименте. Или для UDP – 1,69*1,1=1,86 приблизительно равно 1,86, что показал тестовый прогон. Но вот само базовое соотношение пропорции доставки неутешительно для UDP. Получается, что в идеальном случае для TCP-туннеля доставляются практически все пакеты – коэффициент 1,04 , а вот в туннеле UDP лишь не более чем два из трех – коэффициент 1,69. Здесь еще раз видно, что полученные результаты могут носить лишь оценочный характер. Ясно же, что коэффициент передачи TCP-туннеля должен в идеальном случае равняться единице. Но реальные значения счетчиков интерфейсов интерпретируют по-разному пакеты, их заголовки и даже константы пересчета байт в килобайты. Однако общий смысл ясен: UDP-туннель совсем не способствует полноте доставки данных до получателя. Главная причина в том, что UDP-поток не может подстраиваться под фактическую ширину канала по маршруту роутинга. И именно этим объясняется присутствие специальной опции ограничения канала на входе туннеля OpenVPN. В настоящих настройках она не применялась, а в реальной жизни ее использование позволит сократить расходы на оплату трафика, который в противном случае будет «порезан» одним из маршрутизаторов уже после того как «провернутся» счетчики ISP. Обращаю внимание, в OpenVPN такая опция есть, а вот в CIPE отсутствует, что вообще не свидетельствует в пользу этого проекта.

Итак, трафик UDP тоже не приобретает ничего хорошего от завертывания его в туннель UDP. Быть может, никакого особого улучшения связи из-за применения CIPE и не происходило? Быть может, все это лишь проказы шаловливого кабельщика? Сейчас трудно разобраться, но безымянного кабельщика надо поблагодарить. Ведь именно из-за его работы Олаф Титц, как Колумб, «поплыл в Индию, а прибыл в Америку», то есть не важно, о чем он там думал, когда создавал CIPE, но, безусловно, что его инициатива подтолкнула многих других разработчиков сходных программных средств.

Практические выводы

Без этой части статья не будет выглядеть завершенной. Если такие выводы были у Олафа, то почему бы и здесь им не появиться. Поскольку в процессе практической проверки никаких особых выгод от использования UDP-туннелей не замечено, то вопрос, что использовать, переходит в плоскость экспертных оценок. Перечислю их, и пусть читатели сами решат, подходят ли им такие рекомендации.

Во-первых, современные сети являются в большей степени TCP-сетями. Они приспособлены для транспортировки именно такого трафика. Системы ограничения полос взаимодействуют с потоками TCP-трафика и путем накопления и торможения сегментов в очередях заставляют отправителей TCP замедлять трафик без потерь. Технология предотвращения перегрузки RED (Random early detection) работает только в отношении TCP-потоков. Разрабатываются дополнительные функциональные расширения, ориентированные на управление именно TCP-трафиком в первую очередь. Например, явное уведомление о перегрузке, или ECN, предложенное в RFC 3168 , реализовано как расширение формата TCP. И в том же RFC более половины его содержания посвящено проблеме, как транзитный маршрутизатор сможет управлять с помощью ECN трафиком, завернутым в IPsec. Отдельно там же сказаны и «добрые» слова в отношении других не-TCP-туннелей. Про UDP-туннели слов нет, поскольку UDP как достойный транспорт не рассматривается вообще. Конечно, если очень озаботиться, то в Интернете можно разыскать документ «A proposal for the use of ECN bits with UDP flows». Но предлагаю попробовать найти зарегистрированный RFC на эту же тему. Или попытаться его дождаться.

Во-вторых, если в вашей сети ситуация «не на высоте» и вопрос стоит не о соответствии последним технологическим новациям, а просто об удовлетворительном уровне работы, то и здесь следует предпочесть TCP-транспорт. Очень часто проблемы сетевого взаимодействия связаны с потерями UDP-пакетов. Например, замедленный резолвинг сетевых адресов может доставить много неприятностей. На ненадежных подключениях к Интернету браузеры могут или не открывать запрошенные ресурсы или делать это лишь со второго раза. И учитывая, что UDP-трафик самый «беззащитный», то даже на проводных сетях в условиях сильной загруженности будет происходить вытеснение UDP-пакетов в первую очередь. Завернув UDP-трафик в TCP-туннель, можно сделать его более надежным и предсказуемым. И часы у ваших компьютеров будут корректироваться чаще, и DNS будет работать стабильнее. А если в такой туннель завернуть ICMP, то и мониторинг внешних ресурсов также будет стабильнее.

Нет, решительно невозможно обнаружить никаких аргументов против туннелирования в TCP. Быть может, на дату написания статьи все обстояло иначе? Ну, разве что RFC 3168 было в стадии утверждения. А все остальные механизмы регулирования TCP были реализованы задолго до рождения столь оригинальной мысли о неприемлемости туннелирования трафика внутри TCP. Конечно, не стоит забывать о таком эффекте, как вытеснение TCP-потока (TCP-starvation/UDP-dominance) именно за счет его управляемости. То есть, если два типа трафика смешиваются в одной полосе регулирования, то TCP-трафик, поддающийся регулирующему воздействию, будет уступать полосу UDP. Быть может, это и послужило причиной того, что TCP-туннель у Олафа Титца не работал как надо. Но тогда, кроме признания известного недружелюбного кабельщика, надо согласиться с существованием нерадивого сотрудника ISP. Мне кажется, это уже слишком. http://mia.ece.uic.edu/~papers/volans/table.html .

  • Примеры скриптов – http://www.barabanov.ru/arts/tcp/tovert.tgz .
  • RFC 3168 –


  • Есть вопросы?

    Сообщить об опечатке

    Текст, который будет отправлен нашим редакторам: