Протокол STUN
Идея STUN несложна – клиент отправляет на находящийся снаружи сервер зондирующие сообщения, используя транспорт UDP. В теле этих сообщений содержатся IP адреса и номера портов источника и приемника. Непременным условием работы сервера является использование им двух IP-адресов – дальше станет понятно, для чего.
Процесс определения типа NAT с использованием STUN протекает следующим образом. Допустим, наш клиент находится за NAT, его локальный адрес 192.168.0.111, публичный адрес NAT – 1.2.3.4, адреса сервера STUN – 11.22.33.1 и 11.22.33.2, номера портов 3478. Происходит следующее:
Клиент отправляет запрос на основной адрес сервера (11.22.33.1), при этом в теле отправленного запроса указаны адреса и порты: 192.168.0.111:1055 -> 11.22.33.1:3478. Эти же адреса и порты фигурируют в заголовке IP-пакета, содержащего запрос, но после прохождения NAT адрес источника изменится на 1.2.3.4, а номер порта в зависимости от реализации NAT может измениться или остаться неизменным. Если клиент не получает никакого ответа в течение тайм-аута, он делает вывод, что находится за блокирующим firewall, и завершает работу.
Сервер отвечает клиенту со своего адреса 11.22.33.1 сообщением, в теле которого также указаны адреса и порты: 11.22.33.1:3478 -> 1.2.3.4:1055. Если бы адрес, с которого клиент отправлял своё первое сообщение (192.168.0.111), и адрес в полученном от сервера сообщении (1.2.3.4) совпали, клиент сделал бы вывод, что на пути пакетов NAT отсутствует. В этом случае клиент и сервер обменялись бы еще парой запросов-ответов, на основании которых можно было бы определить, не находится ли по пути между ними firewall, блокирующий входящие пакеты UDP. Поскольку они не совпадают, очевидно, что на пути между клиентом и сервером находится NAT. В этом же сообщении сервер информирует клиента о своем альтернативном IP-адресе (11.22.33.2) и номере порта (3478).
После этого клиент отправляет второе зондирующее сообщение, в котором установлен специальный флажок, указывающий серверу, что клиент ожидает ответа с альтернативного IP-адреса сервера (11.22.33.2), и с другим номером порта источника. Если клиент получает ответ на этот запрос, делается вывод, что находящийся по пути между ними NAT относится к Full Cone типу.
Если ответ на предыдущий запрос не был получен, клиент повторяет свое первое зондирующее сообщение на альтернативный адрес STUN сервера. Если в полученном ответе адрес и номер порта отличаются от указанных в первом ответе, это означает, что этот запрос инициировал появление в таблице NAT новой записи. Такое поведение характерно исключительно для Symmetric NAT.
Если адрес и номер порта в полученном ответе остались такими же, какими они были в первом ответе, то NAT относится к типу Restricted Cone. Осталось установить, является ли он Address Restricted или Port Restricted. Для этого клиент отсылает четвертое сообщение, в котором установлен флажок, указывающий серверу, что он должен ответить, используя порт источника с другим номером. Если ответ был получен, NAT относится к Address Restricted Cone, если нет – то к Port Restricted Cone.