Существует IGD-PCP IWF specification, который пытается решить подобную проблему, хотя и предполагает поддержку PCP на вашем «маршрутизатор 1», а не UPnP. Итак, давайте попробуем подойти к этой проблеме с чистой теоретической точки зрения с помощью двух простых маршрутизаторов UPnP/NAT.
Есть несколько различных шаги от UPnP связи в соответствии с UPnP Device Architecture version 2.0:
- адресации
- открытие
- Описание
- управления
- троеборье
- презентация
Адресация для нас малоинтересна, давайте предположим, что DHCP повсюду и будем делать с ней. Событие и Презентация также практически бесполезна в нашем случае. Таким образом, главное, что нужно беспокоиться, это открытие, описание и управление.
Discovery работает через обмен сообщениями SSDP. SSDP использует UDP для его транспорта с номером порта 1900 (по умолчанию) и широко известным многоадресным адресом.
Описание начинается с URL-адреса, предоставленного устройством на этапе обнаружения, контрольная точка (то есть ПК в нашем случае) должна выдавать HTTP-запрос GET на этот URL-адрес, а это означает, что он использует TCP в качестве транспортного протокола с IP-адресами устройств адрес (одноадресная рассылка).
Управление начинается с URL-адреса, предоставленного устройством в его описании, и использует SOAP поверх HTTP поверх TCP, что в свою очередь также означает одноадресный IP-адрес для нас.
Итак, что все это означает для двойного NAT, так это то, что в этапах описания и управления взаимодействием UPnP у нас возникают проблемы с общением с ПК на маршрутизатор 1, поскольку все это всего лишь стандартный TCP с одноадресными IP-адресами. Но чтобы перейти к этапу описания, нам нужно иметь URL-адрес маршрутизатора 1, поэтому давайте подробнее рассмотрим, как этот URL-адрес приобретается обычным способом.
Существует два основных механизма для обнаружения рекламы (когда устройство периодически осуществляет многоадресную рассылку некоторой информации об этом) и поиск (когда контрольная точка отправляет многоадресное поисковое сообщение, а устройство отвечает на него с одноадресной ответом). Очевидно, что по умолчанию наш ПК за маршрутизатором 2 не может получать многоадресную рекламу с маршрутизатора 1, а маршрутизатор 1 не может получать сообщения с многоадресной рассылкой с ПК, поэтому у нас есть проблема, и теперь возникает вопрос, есть ли возможность связь без многоадресной передачи.
К счастью, та же архитектура документе говорится:
Кроме того, контрольная точка разрешено одноадресно сообщение обнаружения для определенного IP адреса на порту 1900 или на порт, указанный с помощью дополнительного SEARCHPORT.UPNP .ORG (что заменяет порт 1900 для этого использования), поиск UPnP-устройства или услуги на этом конкретном IP-адресе.
...
Все устройства должны прослушивать входящие однонаправленных поиска сообщений на порт 1900 или, если это предусмотрено, то номер порта, указанный в поле заголовка SEARCHPORT.UPNP.ORG и должен отвечать, если какой-либо из их корневых устройств , встроенные устройства или службы соответствуют критериям поиска в сообщении об обнаружении.
А это значит, что если вы знаете маршрутизатор 1 IP-адрес (от маршрутизатора 2 стороны, конечно), вы можете (и самое главное, разрешается спецификацией к) общаться с ним с однонаправленным UDP сообщений и что также NAT-friendly, поэтому не нужно делать что-то с ПК за маршрутизатором 2.
Осталось только одно IP-адрес маршрутизатора 1. К сожалению, нет простого стандартного способа сделать это, но у вас есть как минимум два варианта: tracerouting (как угодно) и грубое принудительное сканирование IP (скорее всего, потенциальный набор IP-адресов для маршрутизатора 1 ограничен).
Теперь вы можете общаться с маршрутизатором 1, но есть еще одна второстепенная вещь, которую вы всегда должны помнить при общении с ней — в любых внутренних сообщениях UPnP вы должны использовать IP-адрес маршрутизатора 2 (как видно со стороны маршрутизатора 1) и его портов. Как и в параметре NewInternalClient
параметра AddPortMapping
на маршрутизаторе 1, вы должны использовать маршрутизатор 2 IP. Это, BTW, ставит вопрос о маршрутизаторе 2 IP, но вы можете получить это через Router 2 UPnP ExternalIPAddress
переменная WANIPConnection
service (эта услуга required for IGDs to implement).
Итак, подведем итоги:
- это технически можно сделать, хотя я сомневаюсь, что любая стандартная библиотека будет делать это для вас
- две вещи которые вам нужны:
- Router 2 " внешний "IP, и вы получите это через
ExternalIPAddress
переменная WANIPConnection
Служба UPnP
- Маршрутизатор 1« внутренний »IP (со стороны маршрутизатора 2), для которого требуется трассировка или сканирование
- данный маршрутизатор 1 IP вам просто нужно использовать однонаправленной передачи сообщений на этапе обнаружения вместо многоадресного
- все остальное просто должно работать, только с оговоркой использования маршрутизатора 2 «внешний» IP вместо ПК IP в UPnP сообщения
Я не думаю, что это возможно. В любом случае, скайп, похоже, не работает таким образом, они просто (ab) используют свою «внеполосную» связь через сервер skype и тип UDP без подключения: в основном они сообщают обеим сторонам адреса/порта, другой участник используется. Затем обе стороны пытаются подключиться друг к другу - эта попытка потерпит неудачу, но она заставит локальный брандмауэр думать, что он должен разрешить UDP-трафик на этот addres/port. После того, как этот процесс повторяется достаточно много раз, все брандмауэры на маршруте должны открыть отверстие, и попытка подключения будет успешной. – jku
Это означает, что нет возможности использовать UPNP в среде multiNAT. Я предполагаю, что вы говорите, это пробивка отверстий UDP. –