Ваше местоположение в сети:
Рубрика:

Соединение двух "серых" компьютеров

Разделы сайта:

Рассказывая про IP-адреса, я писал, что невозможно установить прямое соединение между двумя серыми IP-адресами, так как ни к одному из них нельзя обратиться напрямую. Теперь мне приходится признать, что я был неправ - существует малораспространенный трюк под названием UDP hole punching, позволяющий соединить два компьютера с серыми адресами. Конечно, без посредника не обойтись, но этот посредник нужен лишь на стадии установки соединения, дальше данные будут идти исключительно напрямую.

Сразу хочу предупредить - эта техника работает не всегда - если один из адресов находится за так называемым "симметричным NAT" или же за жестко настроенным прокси-сервером, то подобные действия будут пресечены. Но очень часто она может сработать.

Эта статья будет исключительно теоретической, если же вам нужны конкретные примеры использования UDP hole punching, то далеко идти не нужно - эту технологию использует Skype, сервисы типа Hamachi и TeamView, а также механизм туннелирования IPv6 трафика через IPv4 сети под названием Teredo. Обо всем этом я еще буду писать (и, соответственно, научу, как подобным способом повысить скорость раздачи в торрентах), но пока нужно привести теоретические обоснования...

Проблема

Проблема заключается в том, что к серому IP адресу невозможно просто так отправить запрос - он принадлежит зарезервированному диапазону типа 192.168.*.*, и запрос на такой адрес не пройдет ближайший маршрутизатор или фаервол. Допустим, теперь у нас есть пользователь A с подобным адресом, и он выходит в интернет через сетевое устройство N c реальным адресом. Что будет, если мы отправим запрос на устройство N? А ничего хорошего не будет - этот запрос до пользователя А не дойдет, если, конечно, на устройстве N не настроена "переброска портов" (подобное можно проделать, если сетевое устройство находится в вашем распоряжении, но мы сейчас рассматриваем более сложный случай).

udp1

Аналогичным образом, пользователь B у нас находится за сетевым устройством M, и мы к нему также не можем отправить запрос.

Работаем над решением

А теперь задумаемся. Данные-то до пользователя A доходить могут. Если пользователь A отправил запрос к серверу S, то ответ от сервера S все-таки вернется пользователю A, а не застрянет на сетевом устройстве N. Почему такое происходит? Устройство N запоминает исходящий порт P1 пользователя A и составляет временную запись в своих таблицах, что пакеты от A:P1 будут отправляться как пакеты N:P2 (какой-то другой порт), но и пакеты, приходящие на порт P2, нужно переправлять на устройство A и порт P1.

udp2

Вот этим устройством временных таблиц мы и попытаемся воспользоваться.

Решение

Пользователь А отправляет пакет с порта P1 на M, и неважно, какой порт. Пакет игнорируется устройством М, но на устройстве N появляется временная таблица соответствия A:P1 с P2. Аналогично, B отправляет пакет с порта P3 на M. Пакет игнорируется устройством N, но на устройстве M появляется временная таблица соответствия B:P3 с P4. A и B отправляют аналогичные пакеты на S, и S узнает порты P2 и P4. A и B связываются с S и сообщают ему порты P1 и P2, а он им сообщает все, что знает. Подготовка проведена.

Теперь A может отправлять пакет с A:P1 на M:P4 - и он будет переправлен на B. Аналогично, пакет с B:P3 на N:P2 может быть переправлен на A.

udp3

Это - UDP пакеты, гарантии доставки нет; с TCP подобный трюк провести не удастся. Но, например, в случае Скайпа и не требуется гарантия доставки. Другие же программы на основе UDP реализуют свой механизм проверки доставки и прекрасно работают. Если эта тема интересна, я к ней еще обязательно вернусь. Например, чтобы рассказыть, как использование IPv6 позволит улучшить работу вашего торрента даже если у вас лишь серый IPv4 адрес.

← Скорость мобильного интернетаОсновные платежные системы →
comments powered by Disqus