Будет ли XMPP работать в среде NAT?

Сервер XMMP отправляет push-уведомления клиенту за NAT, используя общедоступную конечную точку (IP + порт), предоставляемую NAT клиенту. Но как долго эта конечная точка назначается этому конкретному клиенту с помощью NAT, что произойдет, если NAT назначит ту же конечную точку другому клиенту? Как можно решить эту проблему?


person metdos    schedule 29.09.2011    source источник


Ответы (2)


XMPP использует стандартное соединение TCP. NAT будут поддерживать ассоциацию до тех пор, пока соединение живо (если только они не будут разорваны).

Обновление: последнюю часть моего утверждения можно было бы немного расширить. Ужасно сломанные реализации NAT существуют. Как правило, это небольшой процент, но многие (наиболее?) популярные клиенты XMPP гарантируют, что они отправляют какие-либо сообщения проверки активности по незанятым соединениям.

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

Протоколы TCP Keepalive — хороший облегченный вариант, тем более что после их включения ОС автоматически обрабатывает их. Как их включить, будет зависеть от вашего языка и фреймворка, но на самом низком уровне вам нужно включить параметр SO_KEEPALIVE в сокете.

Есть две проблемы с поддержкой активности TCP. Во-первых, вы не можете управлять ими из своего приложения (если только вы не пишете код для конкретной платформы). Вторая проблема заключается в том, что некоторые реализации NAT настолько сломаны, что они также будут игнорировать сообщения поддержки активности TCP! Но мы надеемся, что сейчас вы опустились до очень небольшого процента.

Таким образом, другой вариант — сохранение активности с пробелами. Поскольку они связаны с передачей данных через поток, вы должны быть в безопасности даже от сломанных NAT, которые игнорируют сообщения поддержки активности.

Подтверждение активности пробела просто включает отправку символа пробела (' ') через поток XMPP в любое время, когда он не используется. XML и XMPP допускают неограниченное количество пробелов между элементами, и получатель их просто игнорирует.

Наконец, вы можете использовать полноценные эхо-запросы XMPP (XEP-0199). Они включают в себя завершение фактической строфы <iq/> 'get' для сервера, который затем должен ответить. Это гарантирует потоки данных в обоих направлениях, и даже самые неработающие реализации NAT должны поддерживать ваше соединение.

Хорошо, я должен упомянуть, что есть еще худший класс NAT. Я видел NAT, которые просто «забудут» о вашем отображении по целому ряду причин, в том числе при заполнении их таблицы сопоставления или сразу после таймера. Вы ничего не можете сделать, чтобы обойти это, они не работают ни с какими долгоживущими TCP-соединениями. Лучшее, что вы могли бы сделать на этом этапе, это использовать BOSH (по сути, XMPP вместо HTTP).

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

  • Если вы не отправляли никаких данных за 60 секунд, отправьте один символ пробела.
  • Если вы не получили никаких данных за 120 секунд, отправьте пинг XMPP на свой сервер.
  • Если сервер не отвечает на пинг в течение разумного промежутка времени, переподключитесь.

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

person MattJ    schedule 30.09.2011
comment
Это не правильно. Nats удаляет запись сопоставления после некоторого времени простоя. Обычно через 15-45 мин. - person tobias; 19.07.2013
comment
@tobias Некоторые будут, да. Как я уже сказал, они ужасно сломаны. Если вы считаете, что это утверждение неверно, укажите RFC, в котором говорится, что это не так. Тогда вы можете понизить мой ответ :) - person MattJ; 19.07.2013
comment
@tobias: я обновил свой ответ, добавив более подробную информацию о различных уровнях поломки и о том, как их обойти. - person MattJ; 19.07.2013
comment
Возможно, стоит упомянуть и XEP-0198. Некоторые NAT прерывают ваше соединение через некоторое время, и приятно иметь возможность быстро восстановить соединение и узнать, что вы пропустили. - person Joe Hildebrand; 19.07.2013
comment
Теперь ваш ответ более полный. Но причина этого не в том, что NAT сломан. Существуют RFC, в которых указано, что состояние сопоставления TCP/UDP сбрасывается после некоторого времени простоя. RFC4787 рекомендует отказаться от UDP через 5 минут. RFC5382 рекомендует удалять запись сопоставления TCP через 2 часа 4 минуты. - person tobias; 19.07.2013
comment
@tobias: ты выиграл. Это сумасшествие - из RFC5382: когда NAT отказывается от активного соединения, например, из-за истечения тайм-аута, NAT МОЖЕТ либо отправлять пакеты TCP RST на конечные точки, либо МОЖЕТ молча отказаться от соединения. Я потерял дар речи. - person MattJ; 19.07.2013

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

Вы должны иметь в виду, что NAT не является стандартизированным методом. Таким образом, существуют разные реализации. Предоставленные RFC в комментарии выше принадлежат рабочей группе BEHAVE.

person tobias    schedule 18.07.2013
comment
Вместо использования пробелов XMPP. Следует использовать эхо-запросы XMPP (XEP-0199). - person Flow; 19.07.2013
comment
Я очень не уверен в этом. Я думаю, что пинг/понг используется для обнаружения мертвых узлов. - person tobias; 19.07.2013
comment
XMPP Ping может служить той же цели, что и пробел: поддерживать активное TCP-соединение и предотвращать тайм-ауты NAT. Мы делаем это в (а)Smack. - person Flow; 19.07.2013
comment
Да, если интервал DPD находится в диапазоне требуемого интервала проверки активности. Я не могу найти источник, но я написал в списке рассылки, что Whitespace нацелен на поддержку активности и ping на DPD. Но вы правы, что пинг XMPP решает и то, и другое! - person tobias; 19.07.2013