2013-04-05 7 views
2

У меня есть странная проблема. У меня есть успешно работающее приложение C++ (boost asio) P2P, которое работает на большинстве NAT. Проблема заключается в том, что, когда я даю начальный номер начального порта, как 1000, он проверяет, является ли 1000 свободным другим приращением на единицу, и выбирает порт и начинает квитирование. Но когда у меня есть 10000, 20000 или любой другой огромный номер порта, дырокол не работает на ограниченном конусе NAT.Выбор номера порта для пробивки отверстий UDP

Как это возможно? Я почти уверен, что это не имеет никакого отношения к коду. и в последнее время он не работает на одном из кофейных NAT одного из моих друзей, но он работал во многих других NAT с полным конусом. Что может быть причиной? Есть ли что-то, что мне не хватает в том, как ведет себя NAT?

+1

[RFC 5389] (http://tools.ietf.org/html/rfc5389) предупреждает об использовании STUN в качестве * полного решения обхода NAT. У него нет полных ссылок на почему, но каковы бы ни были причины, возможно, это относится к вам. Особенно см. Главу 2. –

+1

На самом деле проблема в том, что STUN (или TURN) не используются для начала. @Navin - как ваши конечные точки обнаруживают свои сопоставления портов? Если вы не используете что-либо похожее на STUN и TURN, как вы получаете сопоставление ip/port для совместного использования с конечной точкой при создании P2P? – selbie

+0

@artlessnoise Я не пользуюсь службой STUN, я использую свой собственный сервер, чтобы получить конечную точку – Navin

ответ

3
  1. Во многих реализациях NAT, существует правила защиты в месте, которые предотвращают один хост от связывания большого процента портов на интерфейсе WAN, например, как описано here.

  2. В зависимости от маршрутизатора записи таблицы NAT имеют разные сроки службы, и всегда существует ограничение на количество портов, которые могут быть выделены для одного клиента (я видел числа от 128 до 4096).

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

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

Я понимаю, что это не «волшебная пуля», но надеюсь, что это как-то поможет вам.

+0

Спасибо, я работаю над этим – Navin

3

Не пытайтесь самостоятельно выбирать номер порта. Операционная система может делать это быстрее и лучше, чем ваш код.

Привяжите гнездо к порту 0 и дайте OS выбрать номер порта для вас. Вы не указали, какой язык программирования, но обычно он включает вызов getsockname() после вызова bind(), чтобы узнать, какой локальный порт будет использоваться. Java и .NET имеют эквивалентные API для выполнения того же самого.

Далее следуют все остальные шаги здесь: https://stackoverflow.com/a/8524609/104458

+0

Язык программирования C++ и boost сокеты используются для переносимости. Я попытался это сделать, но у меня возникла проблема с подключением к NAT с ограниченным доступом. Поэтому после очень долгого утомительного дня я узнал, что если я дам номер порта, то он будет работать. Так что я пробую от 1000 до 10000, я знаю, что это странно, но работает – Navin

0

Не уверен, если это поможет, но вы пробовали, имеющие один экземпляр клиентского приложения, начиная с 1001, а другой, начиная с 1000, то и прирост по 1.

В то время как 1000 потерпит неудачу на клиенте B, клиент A уже пробовал 1001 и так пробил это отверстие, так что, надеюсь, это сработает, правильно? Теоретически это звучит хорошо в моей голове.

Смежные вопросы