Методы обхода NAT и идея

Итак, я был в процессе обхода NAT.

Сценарий следующий: у меня есть два телефона Android, и я хочу соединить их (сокеты) с помощью HTTP-сервера (оба устройства находятся за NAT).

Пока все хорошо, оба клиента подключаются к HTTP-серверу, HTTP-сервер записывает их IP-адрес и порты.

однако есть небольшая проблема, поскольку я использую Java HttpDefaultClient(), он будет менять порт каждый раз, когда я отправляю запрос от клиента на сервер. Хорошо, это звучит как простая проблема: давайте просто используем Socket() для фактического поддержания действительного TCP-соединения с сервером.

общедоступный сокет (адрес InetAddress, int port, InetAddress localAddr, int localPort) выдает IOException

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

Теперь, когда у меня есть IP и порт оппонента (он также находится за NAT), теоретически я могу разорвать соединение с СЕРВЕРОМ и использовать тот же локальный порт, который я уже использовал для фактического размещения клиентского сервера?

если, и теперь наступает часть, где у меня есть вопрос: 1) Если я отброшу сокет HTTP-сервера, поймет ли это NAT и удалит сопоставление портов? (это плохо) 2) Как на самом деле работает передача симметричного конуса nat? 3) библиотеки STUN работают как-то иначе?


person user1327407    schedule 01.05.2012    source источник


Ответы (3)


Не все NAT работают одинаково, но вы можете рассчитывать на несколько вещей: 1) если ваш клиент думает, что он находится на порте X, NAT транслирует это на другой порт 2) NAT обычно пропускает пакеты, которые являются ответом на исходящие пакеты.

STUN пытается угадать с помощью сервера, каков фактический исходящий порт, а затем передать адрес + порт другому клиенту. Это не очень надежно. TURN просто направляет все через сервер. Это более надежно, хотя требует ресурсов ЦП и пропускной способности сервера.

Если вы можете использовать существующий код для обхода NAT, вы избавите себя от многих проблем. В противном случае сделайте что-то вроде TURN через сокеты ИЛИ используйте что-то вроде Urban Airship. Я также использовал бинарные SMS, но это был особый случай.

person Yusuf X    schedule 01.05.2012

С большинством (но не всеми) NAT в наши дни вы можете предположить некоторую согласованность и предсказуемое поведение сопоставления портов. (То есть использование одного и того же локального порта для разных подключений к серверу сопоставляется с одним и тем же локальным портом в NAT). Но похоже, что вы хотите выполнить обход NAT по TCP, что является более сложной проблемой, чем UDP.

Основная проблема заключается в том, что большинство NAT также действуют как брандмауэры. Они не разрешат входящее соединение с удаленного ip:port. Я считаю, что хитрость заключается в том, чтобы сделать одновременное соединение с обеих сторон.

Подробнее о пробивке отверстий TCP можно прочитать здесь: http://en.wikipedia.org/wiki/TCP_hole_punching

person selbie    schedule 08.05.2012

Я думаю, что вы столкнулись с парой проблем, связанных с Nats. Я действительно заставил это работать некоторое время назад (создание однорангового соединения Android с использованием стороннего сервера (моего) и общедоступного сервера STUN.

Я настоятельно рекомендую вам прочитать RFC5389 - Обход Nat. Это сложно. Я также предлагаю вам использовать что-то вроде библиотеки JStun или реализовать свою собственную, как это сделал я.

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

Я предполагаю, что вы находитесь за nat, поэтому запрошенный вами внутренний порт был сопоставлен с другим внешним портом.

Теперь, когда у меня есть IP и порт оппонента (он также находится за NAT), теоретически я могу разорвать соединение с СЕРВЕРОМ и использовать тот же локальный порт, который я уже использовал для фактического размещения клиентского сервера?

Пока нет, большинство NAT записывают не только порты, через которые клиенты установили соединения, но и IP-адреса, к которым они подключались, поэтому они блокируют трафик с других IP-адресов. Например, Phone1 находится на IP-a и подключается к серверу с ip-a через порт-b. nat переводит порт-b в порт-c. С точки зрения серверов телефон находится на IP-a на порту-c. Он передает эту информацию на phone2. Nat будет блокировать все коммуникации с phone2 до тех пор, пока phone1 не отправит данные на phone2 с порта-b.

1) Если я отключу сокет HTTP-сервера, поймет ли это NAT и удалит сопоставление портов? (это плохо) 2)

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

person 8bitwide    schedule 18.06.2012