Подтвердить что ты не робот

Алгоритм перфорации отверстий UDP

Может ли кто-нибудь дать пример прорезывания отверстий UDP?

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

Мне нужна функция такая, что при вызове функции дырка была бы пробита, и будущие коммуникации будут двигаться легко - если этого не слишком много, чтобы спросить:)

4b9b3361

Ответ 1

Короткий ответ: это невозможно сделать надежно.

Длительный ответ:

"Отверстие отверстий" относится к запуску автоматических правил NAT маршрутизатора, чтобы разрешить входящий трафик. Когда вы отправляете пакет UDP, маршрутизатор (обычно) создает временное правило, сопоставляющее исходный адрес и порт с адресом и портом назначения и наоборот. UDP-пакеты, возвращаемые с адреса назначения и порта (и не других), передаются исходному адресу и порту (и никакому другому). Это правило будет отключено через несколько минут бездействия.

Чтобы это работало, когда оба конечных точки за NAT или брандмауэрами потребовали, чтобы оба конечных пункта отправляли пакеты друг другу примерно в одно и то же время. Это означает, что обеим сторонам необходимо знать все другие общедоступные IP-адреса и номера портов, а также передавать их друг другу другими способами.

Невозможно напрямую определить свой собственный публичный IP-адрес, если он находится за NAT (он будет видеть только его частный адрес, например 192.168.x.x). Но поскольку вы предполагаете, что вовлеченные люди знают друг друга по IP-адресам, эти люди могут просто ввести другой адрес.

Но реальный улов заключается в том, что программа также не может напрямую определить, какой номер порта используется маршрутизатором на публичной стороне. Ваша программа может быть привязана к 12345 на локальном компьютере, но маршрутизатор может сопоставить это практически с любым портом с публичной стороны. (Представьте себе, что два компьютера в вашей локальной сети отправляются из порта 12345, очевидно, маршрутизатору придется сопоставить один из них с другим номером.) Поэтому, даже если вы и люди, возможно, знаете, к какому номеру локального порта вы привязаны, чтобы узнать номер порта, который маршрутизатор покажет миру.

Ответ 2

В сетевой библиотеке Lidgren встроена эта функциональность. После добавления библиотеки в приложение вы должны создать экземпляр NetServer, подключиться к двум NetClients и вызвать NetServer.Introduce().

Ссылка на Lidgren: https://github.com/lidgren/lidgren-network-gen3