Эта статья представляет собой вольный перевод одной из записей в блоге разрабочиков DC++.

С разрешения автора (а также для наглядности и интереса ради) я расцветил её ссылками и дополнил некоторыми личными изысканиями.


Введение

В настоящее время по крайней мере один пользователь из пары соединяющихся должен находиться в активном режиме. Механизм «обхода» NAT будет полезен в случае, когда активный режим не настроен ни у одной из сторон. Обычно это происходит по причине блокировки входящих соединений брандмауэром или устройством NAT.

Если оба клиента в активном режиме

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

Если один из клиентов в пассивном режиме

Посредством хаба пассивный клиент A отправляет команду $RevConnectToMe активному клиенту B, который затем отвечает командой $ConnectToMe.


В качестве сервера S в случае выше выступает DC хаб

Если оба клиента в пассивном режиме на ADC хабе

Находящиеся за разными NAT клиенты A и B присоединились к хабу S.


Так соединение с хабом выглядит со стороны клиента A

Хаб принимает подключения на порт 1511. Клиент A осуществляет исходящие соединения из своей приватной сети через порт 50758. Хаб, в свою очередь, видит адрес устройства NAT, работает с ним и транслирует клиентам соответственно их идентификаторам.

Клиент A отправляет серверу S сообщение с просьбой помочь соединиться с клиентом B.

Hub: [Outgoing][178.79.159.147:1511] DRCM AAAA BBBB ADCS/0.10 1649612991

Будучи также в пассивном режиме, клиент B, получив эту команду, должен сообщить свой приватный порт, используемый для соединения с хабом посредством NAT.

Hub: [Incoming][178.79.159.147:1511] DNAT BBBB AAAA ADCS/0.10 59566 1649612991

После получения этой информации клиент A сразу же пытается установить соединение с клиентом B и сообщает свой собственный приватный порт.

Hub:		[Outgoing][178.79.159.147:1511]	 	D<b>RNT</b> AAAA BBBB ADCS/0.10 <b>50758</b> 1649612991

В чём интерес? Интерес в смещении конечной точки одного и того же соединения путём создания нового подключения на публичный адрес через уже используемый приватный порт.


Бинго!

Безусловно, при этом NAT клиента B имеет полное право отклонить первый запрос на соединение от клиента A, но уже его собственный запрос устремляется в «дыру», созданную этим самым соединением, и связь-таки устанавливается.


Иллюстрация, подходящая ко всему процессу с оговоркой, что протокол не использует публичные порты, открытые сессией NAT?S, а также приватные адреса.

Эпилог

На момент написания (оригинальной) статьи примерно половина DC клиентов работает в пассивном режиме. Это означает, что четвёртая часть всех возможных соединений не может быть осуществлена.

В дальнейшем DC++ сможет «обходить» NAT, используя существующие соединения A?S и B?S для установления прямого соединения клиент?клиент, даже если A и B находятся в пассивном режиме.