Stun server что это

от admin

Просто о WebRTC

Большинство материала по WebRTC сосредоточено на прикладном уровне написания кода и не способствует пониманию технологии. Попробуем углубиться и узнать как происходит соединение, что такое дескриптор сессии и кандидаты, для чего нужны STUN и TURN сервера.

WebRTC

Введение

WebRTC – технология, ориентированная на браузеры, которая позволяет соединить два клиента для видео-передачи данных. Основные особенности – внутренняя поддержка браузерами (не нужны сторонние внедряемые технологии типа adobe flash) и способность соединять клиентов без использования дополнительных серверов – соединение peer-to-peer (далее, p2p).

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

Для того, чтобы понять это лучше, рассмотрим три ситуации: оба узла находятся в одной сети (Рисунок 1), оба узла находятся в разных сетях (один в приватной, другой в публичной) (Рисунок 2) и оба узла находятся в разных приватных сетях с одинаковыми IP адресами (Рисунок 3).

Рисунок 1: Оба узла в одной сети

Рисунок 2: Узлы в разных сетях (один в приватной, другой в публичной)

Рисунок 3: Узлы в разных приватных сетях, но с численно равными адресами

На рисунках выше первая буква в дву-символьных обозначениях означает тип узла ( p = peer, r = router). На первом рисунке ситуация благоприятная: узлы в своей сети вполне идентифицируются сетевыми IP адресами и поэтому могут подключаться к друг другу напрямую. На втором рисунке имеем две разные сети, у которых похожие нумерации узлов. Здесь появляются маршрутизаторы (роутеры), у которых есть два сетевых интерфейса – внутри своей сети и вне своей сети. Поэтому у них два IP адреса. Обычные узлы имеют только один интерфейс, через который они могут общаться только в своей сети. Если они передают данные кому-то вне своей сети, то только с помощью NAT внутри маршрутизатора (роутера) и поэтому видимы для других под IP адресом роутера – это их внешний IP адрес. Таким образом, у узла p1 есть внутренний IP = 192.168.0.200 и внешний IP = 10.50.200.5, причем последний адрес будет внешним также и для всех других узлов в его сети 1 . Похожая ситуация и для узла p2. Поэтому их связь невозможна, если использовать только их внутренние (свои) IP адреса. Можно воспользоваться внешними адресами, то есть адресами роутеров, но, так как у всех узлов в одной приватной сети один и тот же внешний адрес, то это довольно затруднительно. Это проблема решается с помощью механизма NAT

Что же будет, если мы все-таки решим соединить узлы через их внутренние адреса? Данные не выйдут за пределы сети. Для усиления эффекта можно представить ситуацию, изображенную на последнем рисунке – у обоих узлов совпадают внутренние адреса. Если они будут использовать их для коммуникации, то каждый узел будет общаться с самим собой.

WebRTC успешно справляется с такими проблемами, используя протокол ICE, который, правда, требует использования дополнительных серверов (STUN, TURN). Обо всем этом ниже.

Две фазы WebRTC

Чтобы соединить два узла через протокол WebRTC (или просто RTC, если связываются два iPhone‘a) необходимо провести некие предварительные действия для установления соединения. Это первая фаза – установка соединения. Вторая фаза – передача видео-данных.

Сразу стоит сказать, что, хоть технология WebRTC в своей работе использует множество различных способов коммуникации (TCP и UDP) и имеет гибкое переключение между ними, эта технология не имеет протокола для передачи данных о соединении. Не удивительно, ведь подключить два узла p2p не так-то просто. Поэтому необходимо иметь некоторый дополнительный способ передачи данных, никак не связанный с WebRTC. Это может быть сокетная передача, протокол HTTP, это может быть даже протокол SMTP или Почта России 2 . Этот механизм передачи начальных данных называется сигнальным. Передавать нужно не так много информации. Все данные передаются в виде текста и делятся на два типа – SDP и Ice Candidate. Первый тип используется для установления логического соединения, а второй для физического 3 . Подробно обо всем этом позже, а пока лишь важно помнить, что WebRTC даст нам некую информацию, которую нужно будет передать другому узлу. Как только мы передадим всю нужную информацию, узлы смогут соединиться и больше наша помощь нужна не будет. Таким образом, сигнальный механизм, который мы должны реализовать отдельно, будет использоваться только при подключении, а при передаче видео-данных использоваться не будет.

Итак, рассмотрим первую фазу – фазу установки соединения. Она состоит из нескольких пунктов. Рассмотрим эту фазу сначала для узла, который инициирует соединение, а потом для ожидающего.

  • Инициатор (звонящий – caller):
    1. Получение локального (своего) медиа потока и установка его для передачи ( getUserMediaStream )
    2. Предложение начать видео-передачу данных ( createOffer )
    3. Получение своего SDP объекта и передача его через сигнальный механизм (SDP)
    4. Получение своих Ice candidate объектов и передача их через сигнальный механизм (Ice candidate)
    5. Получение удаленного (чужого) медиа потока и отображение его на экране ( onAddStream )
  • Ожидающий звонка (callee):
    1. Получение локального (своего) медиа потока и установка его для передачи ( getUserMediaStream )
    2. Получение предложения начать видео-передачу данных и создание ответа ( createAnswer )
    3. Получение своего SDP объекта и передача его через сигнальный механизм (SDP)
    4. Получение своих Ice candidate объектов и передача их через сигнальный механизм (Ice candidate)
    5. Получение удаленного (чужого) медиа потока и отображение его на экране ( onAddStream )

Отличие лишь во втором пункте.

Несмотря на кажущуюся запутанность шагов здесь их на самом деле три: отправка своего медиа потока (п.1), установка параметров соединения (пп.2-4), получение чужого медиа потока (п.5). Самый сложный – второй шаг, потому что он состоит из двух частей: установление физического и логического соединения. Первая указывает путь, по которому должны идти пакеты, чтобы дойти от одного узла сети до другого. Вторая указывает параметры видео/аудио – какое использовать качество, какие использовать кодеки.

Мысленно этап createOffer или createAnswer следует соединить с этапами передачи SDP и Ice candidate объектов.

Далее будут рассмотрены некоторые сущности подробнее, а именно – медиапоток (MediaStream), дескриптор сессии (SDP) и кандидаты (Ice candidate).

Основные сущности

Медиа потоки (MediaStream)

Основной сущностью является медиа поток, то есть поток видео и аудио данных, картинка и звук. Медиа потоки бывают двух типов – локальные и удаленные. Локальный получает данные от устройств входа (камера, микрофон), а удаленный по сети. Таким образом у каждого узла есть и локальный, и удаленный поток. В WebRTC для потоков существует интерфейс MediaStream и также существует подинтерфейс LocalMediaStream специально для локального потока. В JavaScript можно столкнуться только с первым, а если использовать libjingle, то можно столкнуться и со вторым.

В WebRTC существует довольно запутанная иерархия внутри потока. Каждый поток может состоять из нескольких медиа дорожек (MediaTrack), которые в свою очередь могут состоять из нескольких медиа каналов (MediaChannel). Да и самих медиа потоков может быть тоже несколько.

Рассмотрим все по порядку. Для этого будем держать в уме некоторый пример. Допустим, что мы хотим передавать не только видео себя, но и видео нашего стола, на котором лежит листок бумаги, на котором мы собираемся что-то писать. Нам понадобится два видео (мы + стол) и одно аудио (мы). Ясно, что мы и стол стоит разделить на разные потоки, потому что эти данные, наверное, слабо зависят друг от друга. Поэтому у нас будет два MediaStream‘a – один для нас и один для стола. Первый будет содержать и видео, и аудио данные, а второй – только видео (Рисунок 4).

Рисунок 4: Два различных медиа потока. Один для нас, один для нашего стола

Сразу ясно, что медиа поток как минимум должен включать в себя возможность содержать данные разных типов — видео и аудио. Это учтено в технологии и поэтому каждый тип данных реализуется через медиа дорожку MediaTrack. У медиа дорожки есть специальное свойство kind, которое и определяет, что перед нами – видео или аудио (Рисунок 5)

Рисунок 5: Медиа потоки состоят из медиа дорожек

Как будет всё происходить в программе? Мы создадим два медиа потока. Потом создадим две видео дорожки и одну аудио дорожку. Получим доступ к камерам и микрофону. Укажем каждой дорожке какое устройство использовать. Добавим видео и аудио дорожку в первый медиа поток и видео дорожку от другой камеры во второй медиа поток.

Но как мы различим медиа потоки на другом конце соединения? Для этого каждый медиа поток имеет свойство label – метка потока, его название (Рисунок 6). Такое же свойство имеют и медиа дорожки. Хотя на первый взгляд кажется, что видео от звука можно отличить и другими способами.

Рисунок 6: Медиа потоки и дорожки идентифицируются метками

Так, а если медиа дорожки можно идентифицировать через метку, то зачем нам для нашего примера использовать два медиа потока, вместо одного? Ведь можно передавать один медиа поток, а дорожки использовать в нем разные. Мы дошли до важного свойства медиа потоков – они синхронизируют медиа дорожки. Разные медиа потоки не синхронизируются между собой, но внутри каждого медиа потока все дорожки воспроизводятся одновременно.

Таким образом, если мы хотим, чтобы наши слова, наши эмоции на лице и наш листочек бумаги воспроизводились одновременно, то стоит использовать один медиа поток. Если это не столь важно, то выгодней использовать разные потоки – картинка будет более гладкой 4 .

Если какую-то дорожку необходимо отключать во время передачи, то можно воспользоваться свойством enabled медиа дорожки.

В конце стоит подумать о стерео звуке. Как известно стерео звук – это два разных звука. И передавать их надо тоже отдельно. Для этого используются каналы MediaChannel. Медиа дорожка звука может иметь много каналов (например, 6, если нужен звук 5+1). Внутри медиа дорожки каналы, разумеется тоже синхронизированы. Для видео обычно используется только один канал, но могут использоваться и несколько, например, для наложения рекламы.

Резюмируя: мы используем медиа поток для передачи видео и аудио данных. Внутри каждого медиа потока данные синхронизированы. Мы можем использовать несколько медиа потоков, если синхронизация нам не нужна. Внутри каждого медиа потока есть медиа дорожки двух видов – для видео и для аудио. Дорожек обычно не больше двух, но может быть и больше, если нужно передавать несколько разных видео (собеседника и его стола). Каждая дорожка может состоять из нескольких каналов, что используется обычно только для стерео звука.

В самой простой ситуации видеочата у нас будет один локальный медиа поток, который будет состоять из двух дорожек – видео дорожки и аудио дорожки, каждая из которых будет состоять из одного основного канала. Видео дорожка отвечает за камеру, аудио дорожка – за микрофон, а медиа поток – это контейнер их обоих.

Дескриптор сессии (SDP)

У разных компьютеров всегда будут разные камеры, микрофоны, видеокарты и прочее оборудование. Существует множество параметров, которыми они обладают. Все это необходимо скоординировать для медиа передачи данных между двумя узлами сети. WebRTC делает это автоматически и создает специальный объект – дескриптор сессии SDP. Передайте этот объект другому узлу, и можно передавать медиа данные. Только связи с другим узлом пока нет 5 .

Для этого используется любой сигнальный механизм. SDP можно передать хоть через сокеты, хоть человеком (сообщить его другому узлу по телефону), хоть Почтой России. Всё очень просто – Вам дадут уже готовый SDP и его нужно переслать. А при получении на другой стороне – передать в ведомство WebRTC. Дескриптор сессии хранится в виде текста и его можно изменить в своих приложениях, но, как правило, это не нужно. Как пример, при соединении десктоп↔телефон иногда требуется принудительно выбирать нужный аудио кодек.

Обычно при установке соединения необходимо указывать какой-то адрес, например URL. Здесь в этом нет необходимости, так как через сигнальный механизм Вы сами отправите данные по назначению. Чтобы указать WebRTC, что мы хотим установить p2p соединение нужно вызвать функцию createOffer . После вызова этой функции и указания ей специального callback‘a будет создан SDP объект и передан в этот же callback. Все, что от Вас требуется – передать этот объект по сети другому узлу (собеседнику). После этого на другом конце через сигнальный механизм придут данные, а именно этот SDP объект. Этот дескриптор сессии для этого узла чужой и поэтому несет полезную информацию. Получение этого объекта – сигнал к началу соединения. Поэтому Вы должны согласиться на это 6 и вызвать функцию createAnswer . Она – полный аналог createOffer . Снова в Ваш callback передадут локальный дескриптор сессии и его нужно будет передать по сигнальному механизму обратно.

Стоит отметить, что вызывать функцию createAnswer можно только после получения чужого SDP объекта. Почему? Потому что локальный SDP объект, который будет генерироваться при вызове createAnswer , должен опираться на удаленный SDP объект. Только в таком случае возможно скоординировать свои настройки видео с настройками собеседника. Также не стоит вызывать createAnswer и createOffer до получения локального медиа потока – им будет нечего писать в SDP объект 7 .

Так как в WebRTC есть возможность редактирования SDP объекта, то после получения локального дескриптора его нужно установить. Это может показаться немного странным, что нужно передавать WebRTC то, что она сама нам дала, но таков протокол. При получении удаленного дескриптора его нужно тоже установить. Поэтому Вы должны на одном узле установить два дескриптора – свой и чужой (то есть локальный и удаленный).

После такого рукопожатия узлы знают о пожеланиях друг друга. Например, если узел 1 поддерживает кодеки A и B, а узел 2 поддерживает кодеки B и C, то, так как каждый узел знает свой и чужой дескрипторы, оба узла выберут кодек B (Рисунок 7). Логика соединения теперь установлена, и можно передавать медиа потоки, но есть другая проблема – узлы по-прежнему связаны лишь сигнальным механизмом.

Рисунок 7: Согласование кодеков

Кандидаты (Ice candidate)

Технология WebRTC пытается запутать нас своей новой методологией. При установке соединения не указывается адрес того узла, с которым нужно соединиться. Устанавливается сначала логическое соединение, а не физическое, хотя всегда делалось наоборот 8 . Но это не покажется странным, если не забывать, что мы используем сторонний сигнальный механизм.

Итак, соединение уже установлено (логическое соединение), но пока нет пути, по которому узлы сети могут передавать данные. Здесь не всё так просто, но начнем с простого. Пусть узлы находятся в одной приватной сети. Как мы уже знаем, они могут легко соединяться друг с другом по своим внутренним IP адресам (или быть может, по каким-то другим, если используется не TCP/IP).

Через некоторые callback‘и WebRTC сообщает нам Ice candidate объекты. Они тоже приходят в текстовой форме и также, как с дескрипторами сессии, их нужно просто переслать через сигнальный механизм. Если дескриптор сессии содержал информацию о наших установках на уровне камеры и микрофона, то кандидаты содержат информацию о нашем расположении в сети. Передайте их другому узлу, и тот сможет физически соединиться с нами, а так как у него уже есть и дескриптор сессии, то и логически сможет соединиться и данные «потекут». Если он не забудет отправить нам и свой объект кандидата, то есть информацию о том, где находится он сам в сети, то и мы сможем с ним соединиться. Заметим здесь еще одно отличие от классического клиент-серверного взаимодействия. Общение с HTTP сервером происходит по схеме запрос-ответ, клиент отправляет данные на сервер, тот обрабатывает их и шлет по адресу, указанному в пакете запроса. В WebRTC необходимо знать два адреса и соединять их с двух сторон.

Различие от дескрипторов сессии состоит в том, что устанавливать нужно только удаленных кандидатов. Редактирование здесь запрещено и не может принести никакой пользы. В некоторых реализациях WebRTC кандидатов необходимо устанавливать только после установки дескрипторов сессии 9 .

А почему дескриптор сессии был один, а кандидатов может быть много? Потому что расположение в сети может определяться не только своим внутренним IP адресом, но также и внешним адресом маршрутизатора, и не обязательно одного, а также адресами TURN серверов. Остаток параграфа будет посвящен подробному рассмотрению кандидатов и тому, как соединять узлы из разных приватных сетей.

Итак, два узла находятся в одной сети (Рисунок 8). Как их идентифицировать? С помощью IP адресов. Больше никак. Правда, еще можно использовать разные транспорты (TCP и UDP) и разные порты. Это и есть та информация, которая содержится в объекте кандидата – IP, PORT, TRANSPORT и какая-то другая. Пусть, для примера, используется UDP транспорт и 531 порт.

Рисунок 8: Два узла находятся в одной сети

Тогда, если мы находимся в узле p1, то WebRTC передаст нам такой объект кандидата — [10.50.200.5, 531, udp]. Здесь приводится не точный формат, а лишь схема. Если мы в узле p2, то кандидат таков – [10.50.150.3, 531, udp]. Через сигнальный механизм p1 получит кандидата p2 (то есть расположение узла p2, а именно его IP и PORT). После чего p1 может соединиться с p2 напрямую. Более правильно, p1 будет посылать данные на адрес 10.50.150.3:531 в надежде, что они дойдут до p2. Не важно, принадлежит ли этот адрес узлу p2 или какому-то посреднику. Важно лишь то, что через этот адрес данные будут посылаться и могут достигнуть p2.

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

Перейдем к более сложному случаю. Один узел будет находиться за роутером (точнее, за NAT), а второй узел будет находиться в одной сети с этим роутером (например, в интернете) (Рисунок 9).

Рисунок 9: Один узел за NAT, другой нет

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

Предположим, что веб-сервер соединен с интернетом напрямую, то есть имеет публичным IP* адрес. Пусть это будет узел p2. Узел p1 (веб-клиент) шлет запрос на адрес 10.50.200.10. Сначала данные попадают на роутер r1, а точнее на его внутренний интерфейс 192.168.0.1. После чего, роутер запоминает адрес источника (адрес p1) и заносит его в специальную таблицу NAT, затем изменяет адрес источника на свой(p1 r1). Далее, по своему внешнему интерфейсу роутер пересылает данные непосредственно на веб‑сервер p2. Веб-сервер обрабатывает данные, генерирует ответ и отправляет обратно. Отправляет роутеру r1, так как именно он стоит в обратном адресе (роутер подменил адрес на свой). Роутер получает данные, смотрит в таблицу NAT и пересылает данные узлу p1. Роутер выступает здесь как посредник.

А что если несколько узлов из внутренней сети одновременно обращаются к внешней сети? Как роутер поймет кому отправлять ответ обратно? Эта проблема решается с помощью портов. Когда роутер подменяет адрес узла на свой, он также подменяет и порт. Если два узла обращаются к интернету, то роутер подменяет их порты источников на разные. Тогда, когда пакет от веб‑сервера придет обратно к роутеру, то роутер поймет по порту, кому назначен данный пакет. Пример ниже.

Вернемся к технологии WebRTC, а точнее, к ее части, которая использует ICE протокол (отсюда и Ice кандидаты). Узел p2 имеет одного кандидата (свое расположение в сети – 10.50.200.10), а узел p1, который находится за роутером с NAT, будет иметь двух кандидатов – локального (192.168.0.200) и кандидата роутера (10.50.200.5). Первый не пригодится, но он, тем не менее, генерируется, так как WebRTC еще ничего не знает об удаленном узле – он может находиться в той же сети, а может и нет. Второй кандидат пригодится, и, как мы уже знаем, важную роль будет играть порт (чтобы пройти через NAT).

Запись в таблице NAT генерируется только когда данные выходят из внутренней сети. Поэтому узел p1 должен первым передать данные и только после этого данные узла p2 смогут добраться до узла p1.

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

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

Проблема в том, что, чтобы узнать своей внешний IP адрес, нужен узел находящийся в общей сети. Для решения такой проблемы используются дополнительные сервера, которые подключены к интернету напрямую. С их помощью также создаются заветные записи в таблице NAT.

STUN и TURN сервера

При инициализации WebRTC необходимо указать доступные STUN и TURN сервера, которые мы в дальнейшем будем называть ICE серверами. Если сервера не будут указаны, то соединиться смогут только узлы в одной сети (подключенные к ней без NAT). Сразу стоит отметить, что для 3g-сетей обязательно использование TURN серверов.

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

Рассмотрим этот процесс на примере.

Пример (работа STUN сервера)

STUN сервер будем обозначать через s1. Роутер, как и раньше, через r1, а узел – через p1. Также необходимо будет следить за таблицей NAT – ее обозначим как r1_nat. Причем в этой таблице обычно содержится много записей от разный узлов подсети – они приводиться не будут.

Итак, в начале имеем пустую таблицу r1_nat.

Internal IP Internal PORT External IP External PORT

Таблица 1: Пустая таблица NAT

В таблице 4 столбца. Она задает отображение первых двух столбцов на два последних, то есть каждой паре (IP, PORT), которая адресует узел во внутренней приватной сети, сопоставляется пара (IP, PORT) из внешней публичной сети.

Узел p1 отправляет пакет узлу s1 (STUN серверу). Ниже в таблице указаны четыре интересующие нас поля в заголовке транспортного пакета (TCP или UDP) – IP и PORT источника и приемника. Пусть адреса будут такими:

Src IP Src PORT Dest IP Dest PORT
192.168.0.200 35777 12.62.100.200 6000

Таблица 2: Заголовок пакета

Узел p1 отправляет этот пакет роутеру r1 (не важно каким образом, в разных подсетях могут быть использованы разные технологии). Роутеру необходимо сделать подмену адреса источника Src IP, так как указанный в пакете адрес заведомо не подойдет для внешней подсети, более того, адреса из такого диапазона зарезервированы, и ни один адрес в интернете не имеет такого адреса. Роутер делает подмену в пакете и создает новую запись в своей таблице r1_nat. Для этого ему нужно придумать номер порта. Напомним, что, так как несколько узлов внутри подсети могут обращаться к внешней сети, то в таблице NAT должна храниться дополнительная информация, чтобы роутер смог определить, кому из этих нескольких узлов предназначается обратный пакет от сервера. Пусть роутер придумал порт 888.

Измененный заголовок пакета:

Src IP Src PORT Dest IP Dest PORT
10.50.200.5 888 12.62.100.200 6000

Таблица 3: Роутер подменил адрес источника на свой

Где 10.50.200.5 – это внешний адрес роутера.

Таблица r1_nat:

Internal IP Internal PORT External IP External PORT
192.168.0.200 35777 10.50.200.5 888

Таблица 4: Таблица NAT пополнилась новой записью

Здесь IP адрес и порт для подсети абсолютно такие же, как у исходного пакета. В самом деле, при обратной передаче мы должны иметь способ полностью их восстановить. IP адрес для внешней сети – это адрес роутера, а порт изменился на придуманный роутером.

Настоящий порт, на который узел p1 принимает подключение – это, разумеется, 35777, но сервер шлет данные на фиктивный порт 888, который будет изменен роутером на настоящий 35777.

Итак, роутер подменил адрес и порт источника в заголовке пакета и добавил запись в таблицу NAT. Теперь пакет отправляется по сети серверу, то есть узлу s1. На входе, s1 имеет такой пакет:

Src IP Src PORT Dest IP Dest PORT
10.50.200.5 888 12.62.100.200 6000

Таблица 5: STUN сервер получил пакет

Итого, STUN сервер знает, что ему пришел пакет от адреса 10.50.200.5:888. Теперь этот адрес сервер отправляет обратно. Здесь стоит остановиться и еще раз посмотреть, что мы только что рассматривали. Таблицы, приведенные выше – это кусочек из заголовка пакета, вовсе не из его содержимого. О содержимом мы не говорили, так как это не столь важно – оно как-то описывается в протоколе STUN. Теперь же мы будем рассматривать помимо заголовка еще и содержимое. Оно будет простым и содержать адрес роутера – 10.50.200.5:888, хотя взяли мы его из заголовка пакета. Такое делается не часто, обычно протоколам не важна информация об адресах узлов, важно лишь, чтобы пакеты доставлялись по назначению. Здесь же мы рассматриваем протокол, который устанавливает путь между двумя узлами.

Итак, теперь у нас появляется второй пакет, который идет в обратном направлении:

Src IP Src PORT Dest IP Dest PORT
12.62.100.200 6000 10.50.200.5 888

Таблица 6: STUN сервер отправляет пакет с таким заголовком

Заголовок изменился очень просто – источник и приемник поменялись местами, что логично, так как направление пакета теперь другое.

Content
10.50.200.5:888

Таблица 7: STUN сервер отправляет пакет с таким содержимым

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

Далее, пакет путешествует по сети, пока не окажется на внешнем интерфейсе роутера r1. Роутер понимает, что пакет предназначен не ему. Как он это понимает? Это можно узнать только по порту. Порт 888 он не использует для своих личных целей, а использует для механизма NAT. Поэтому в эту таблицу роутер и смотрит. Смотрит на столбец External PORT и ищет строку, которая совпадет с Dest PORT из пришедшего пакета, то есть 888.

Internal IP Internal PORT External IP External PORT
192.168.0.200 35777 10.50.200.5 888

Таблица 8: Таблица NAT

Нам повезло, такая строчка существует. Если бы не повезло, то пакет бы просто отбросился. Теперь нужно понять, кому из узлов подсети надо отправлять этот пакет. Не стоит торопиться, давайте снова вспомним о важности портов в этом механизме. Одновременно два узла в подсети могли бы отправлять запросы во внешнюю сеть. Тогда, если для первого узла роутер придумал порт 888, то для второго он бы придумал порт 889. Предположим, что так и случилось, то есть таблица r1_nat выглядит так:

Internal IP Internal PORT External IP External PORT
192.168.0.200 35777 10.50.200.5 888
192.168.0.173 35777 10.50.200.5 889

Таблица 9: Таблица NAT

По порту 888 понятно, что нужный внутренний адрес это 192.168.0.200:35777. Роутер заменяет адрес приемника с

Src IP Src PORT Dest IP Dest PORT
12.62.100.200 6000 10.50.200.5 888

Таблица 10: Роутер подменяет адрес приемника

Src IP Src PORT Dest IP Dest PORT
12.62.100.200 6000 192.168.0.200 35777

Таблица 11: Роутер подменил адрес приемника

Пакет успешно приходит к узлу p1 и, посмотрев на содержимое пакета, узел узнает о своем внешнем IP адресе, то есть об адресе роутера во внешней сети. Также он знает и порт, который роутер пропускает через NAT.

Что же дальше? Какая от этого всего польза? Польза – это запись в таблице r1_nat. Если теперь кто угодно будет отправлять на роутер r1 пакет с портом 888, то роутер перенаправит этот пакет узлу p1. Таким образом, создался небольшой узкий проход к спрятанному узлу p1.

Из примера выше можно получить некоторое представление о работе NAT и сути STUN сервера. Вообще, механизм ICE и STUN/TURN сервера как раз и направлены на преодоления ограничений NAT.

Между узлом и сервером может стоять не один роутер, а несколько. В таком случае узел получит адрес того роутера, который является первым выходящим в ту же сеть, что и сервер. Иными словами, получим адрес роутера, подключенного к STUN серверу. Для p2p коммуникации это как раз то, что нам нужно, если не забыть тот факт, что в каждом роутере добавится необходимая нам строчка в таблицу NAT. Поэтому обратный путь будет вновь так же гладок.

TURN сервер – это улучшенный STUN сервер. Отсюда сразу следует извлечь, что любой TURN сервер может работать и как STUN сервер. Однако, есть и преимущества. Если p2p коммуникация невозможна (как например, в 3g сетях), то сервер переходит в режим ретранслятора (relay), то есть работает как посредник. Разумеется, ни о каком p2p тогда речь не идет, но за рамками механизма ICE узлы думают, что общаются напрямую.

В каких случаях необходим TURN сервер? Почему не хватает STUN сервера? Дело в том, что существует несколько разновидностей NAT. Они одинаково подменяют IP адрес и порт, однако в некоторые из них встроена дополнительная защита от “фальсификации”. Например, в симметричной таблице NAT сохраняются еще 2 параметра — IP и порт удаленного узла. Пакет из внешней сети проходит через NAT во внутреннюю сеть только в том случае, если адрес и порт источника совпадают с записанными в таблице. Поэтому фокус со STUN сервером не удается — таблица NAT хранит адрес и порт STUN сервера и, когда роутер получает пакет от WebRTC собеседника, он его отбрасывает, так как он “фальсифицирован”. Он пришел не от STUN сервера.

Таким образом TURN сервер нужен в том случае, когда оба собеседника находятся за симметричным NAT (каждый за своим).

Краткая сводка

Здесь приведены некоторые утверждения о сущностях WebRTC, которые необходимо всегда держать в голове. Подробно они описаны выше. Если какие-то из утверждений Вам покажутся не до конца ясными, перечитайте соответствующие параграфы.

  • Медиа поток
    • Видео и аудио данные упаковываются в медиа потоки
    • Медиа потоки синхронизируют медиа дорожки, из которых состоят
    • Различные медиа потоки не синхронизированы между собой
    • Медиа потоки могут быть локальными и удаленными, к локальному обычно подключена камера и микрофон, удаленные получают данные из сети в кодированном виде
    • Медиа дорожки бывают двух типов – для видео и для аудио
    • Медиа дорожки имеют возможность включения/выключения
    • Медиа дорожки состоят из медиа каналов
    • Медиа дорожки синхронизируют медиа каналы, из которых состоят
    • Медиа потоки и медиа дорожки имеют метки, по которым их можно различать
    • Дескриптор сессии используется для логического соединения двух узлов сети
    • Дескриптор сессии хранит информацию о доступных способах кодирования видео и аудио данных
    • WebRTC использует внешний сигнальный механизм – задача пересылки дескрипторов сессии (sdp) ложится на приложение
    • Механизм логического соединения состоит из двух этапов – предложения (offer) и ответа (answer)
    • Генерация дескриптора сессии невозможна без использования локального медиа потока в случае предложения (offer) и невозможна без использования удаленного дескриптора сессии в случае ответа (answer)
    • Полученный дескриптор надо отдать реализации WebRTC, причем неважно, получен ли этот дескриптор удаленно или же локально от той же реализации WebRTC
    • Имеется возможность небольшой правки дескриптора сессии
    • Кандидат (Ice candidate) – это адрес узла в сети
    • Адрес узла может быть своим, а может быть адресом роутера или TURN сервера
    • Кандидатов всегда много
    • Кандидат состоит из IP адреса, порта и типа транспорта (TCP или UDP)
    • Кандидаты используются для установления физического соединения двух узлов в сети
    • Кандидатов также нужно пересылать через сигнальный механизм
    • Кандидатов также нужно передавать реализации WebRTC, однако только удаленных
    • В некоторых реализациях WebRTC кандидатов можно передавать только после установки дескриптора сессии
    • NAT – механизм обеспечения доступа к внешней сети
    • Домашние роутеры поддерживают специальную таблицу NAT
    • Роутер подменяет адреса в пакетах – адрес источника на свой, в случае, если пакет идет во внешнюю сеть, и адрес приемника на адрес узла во внутренней сети, если пакет пришел из внешней сети
    • Для обеспечения многоканального доступа к внешней сети NAT использует порты
    • ICE – механизм обхода NAT
    • STUN и TURN сервера – сервера-помошники для обхода NAT
    • STUN сервер позволяет создавать необходимые записи в таблице NAT, а также возвращает внешний адрес узла
    • TURN сервер обобщает STUN механизм и делает его работающим всегда
    • В наихудших случаях TURN сервер используется как посредник (relay), то есть p2p превращается в клиент-сервер-клиентную связь.
    Сноски:

    Так как у всех узлов в этой сети один и тот же роутер. ↩

    Этот шуточный пример всегда полезно держать в голове, чтобы различать коммуникацию в технологии WebRTC от сигнальной коммуникации ↩

    Очень упрощенно. На деле SDP — это единственные данные которые передаются, а кандидаты это его часть. ↩

    На синхронизацию всегда тратится дополнительное время. ↩

    Во времена Vanilla Ice кандидаты передавались внутри SDP, поэтому связь уже есть. ↩

    Можно только согласиться, отказаться нельзя. В случае отказа нужно просто игнорировать запрос на соединение. ↩

    Тем не менее, в некоторых реализациях это возможно. Но в том лишь случае, если есть доступ к настройкам видео. Браузеры не могут обращаться к камере до получения медиа потока. ↩

    Например, при соединении ftp-клиента с ftp-сервером сначала устанавливается TCP-соединение (для протокола прикладного уровня протокол транспортного уровня можно считать физическим), а только потом передаются данные по протоколу FTP (то есть логика протокола). ↩

    Такова реализация libjingle и некоторых браузеров. Это так, потому что кандидаты являются частью SDP объекта и записываются в него. ↩

    WebRTC: фреймворк ICE, STUN и сервера TURN

    WebRTC (Web Real Time Communication) — это проект с открытым исходным кодом, позволяющий создавать одноранговые (P2P) аудио- и видеосвязи через JavaScript API.

    Для того чтобы установить P2P-соединение, одноранговые пользователи должны общаться о типах носителей, которыми они хотят обмениваться, сообщить друг другу, когда они хотят начать или прекратить общение, а также должны найти друг друга в сети. Весь этот процесс называется сигнализацией, но нас интересует только последняя часть — как соединить одноранговые узлы, максимально избегая посредников.

    Это не так просто, как кажется. Устройства пользователей обычно не имеют публичного IP-адреса или могут быть не допущены до установления какого-либо прямого соединения. Вот почему нам нужна платформа Interactive Connectivity Establishment (ICE).

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

    С другой стороны, в Интернете исторически не хватало “номеров” для каждого подключенного устройства. С IPv4 было доступно только около 4 миллиардов адресов. Недостаток адресов был решен путем группировки многих устройств под одним общим адресом с маршрутизатором, переводящим адреса в пакеты, проходящие через него. Этот процесс называется трансляцией сетевых адресов (NAT).

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

    В этом поможет протокол STUN (Session Traversal Utilities for NAT). Необходимо предоставить сервер STUN при попытке установить P2P-соединение. В WebRTC вы предоставляете его при создании объекта JavaScript, представляющего соединение:

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

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

    Реализации NAT

    Не все NAT реализованы одинаково и могут отличаться в том, как они позволяют пакетам проходить. Некоторые реализации NAT, такие как NAT один к одному, позволят установить P2P-соединение. Некоторые, например симметричные, этого не делают.

    NAT один к одному (или Full Cone NAT)

    В этой реализации, как только внутренний IP-адрес/порт duo сопоставляется с внешним IP-адресом/портом duo, все пакеты, поступающие на внешний адрес/порт, независимо от того, откуда они поступают, будут отправлены через исходный внутренний адрес/порт.

    Если за таким NAT стоят одноранговые узлы, то для установления P2P-соединения достаточно получить публичный IP-адрес и порт обоих одноранговых узлов.

    Симметричный NAT

    В симметричных NAT’ах внешний IP-адрес/порт зависит от внутреннего IP-адреса/порта duo и назначения. Запросы от 198.145.1.2: 3000 к серверу TURN сопоставляются с заданным IP-адресом и портом внешнего источника. Но если один и тот же внутренний хост отправляет пакет в другое место назначения, например в одноранговый узел, с которым он пытается связаться, внешний IP-адрес/порт будет отличаться. Кроме того, внешний хост должен получить пакет от внутреннего хоста, прежде чем он сможет отправить пакет обратно.

    Если контакты находятся за симметричным NAT, они не смогут общаться. Вот почему нам нужно другое решение: TURN.

    Когда прямое соединение не может быть установлено, связь должна проходить через сервер TURN. TURN обозначает “Traversal Using Relays around NAT”. Как следует из названия, соединение будет проходить через ретрансляционный сервер.

    Это очевидно ухудшает производительность и имеет финансовые издержки. В то время как сервер STUN имеет дело с очень маленькими и легкими запросами, сервер TURN ретранслирует весь разговор, что генерирует гораздо больше трафика. Вот почему вы можете найти публичные серверы STUN, но не публичные серверы TURN (по крайней мере, ни один владелец которых не знает, что он является публичным).

    ICE в WebRTC

    Чтобы быть установленным в TURN, для WebRTConnection нужно указать URL-адрес вашего сервера в объекте RCTPeerConnection:

    Серверы TURN по причине, описанной выше, обычно защищены паролем.

    Агент ICE сначала попытается установить соединение непосредственно между одноранговыми узлами и переключится на опцию TURN только в том случае, если это не сработает. Вам не нужно заботиться об этом самостоятельно, нужно только слушать событие onicecandidate RTCPeerConnection. Оно будет срабатывать каждый раз, когда обнаруживается кандидат ICE. Затем вам нужно отправить кандидата своему контакту через свой сигнальный механизм:

    Когда вы получаете кандидата от своего контакта, нужно доставить его агенту ICE, вызвав addIceCandidate. Остальная часть переговоров и окончательный отбор кандидатов затем осуществляется агентом ICE. В конце переговоров о кандидате, в случае успеха, коллеги могут начать общение.

    Что такое STUN и зачем он нужен?

    Так случилось, что очень много пользователей сидят в интернете за NAT (Network Address Translation). Например, наш компьютер в локальной сети имеет IP-адрес 192.168.1.100. Адресов диапазона 192.168.x.x в Интернете быть не может (он зарезервирован для локальных сетей), и такой пакет к отправителю не вернется. Когда пакет из локалки уходит в интернет, NAT (обычно это часть функционала шлюза в интернет) подменяет в нем адрес отправителя на внешний (публичный) адрес NATа, например 1.2.3.4. Когда получатель пакета получит его и решит отправить ответ, то он пошлет его на внешний адрес NATа. А внутри себя NAT заменит адрес обратно на 192.168.1.100 и дошлет пакет компьютеру в локалку.

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

    Вроде бы все работает прозрачно для сидящих за NATом компьютеров. Проблема возникает тогда, когда компьютеры сначала договариваются о передаче данных по одному протоколу, сообщая друг другу свои IP-адреса, через которые пойдет обмен (конечно, NAT про протоколы не знает, ему важны номера портов), а потом начинается собственно передача данных. Именно так происходит установление соединения в VoIP — договариваются хосты о соединении по SIP, сообщая друг другу адреса и номера портов для голосовых RTP-потоков по SDP, а обмен идет уже по RTP.

    Компьютер с адресом 192.168.1.100 посылает VoIP-шлюзу во внешней сети свой адрес и порт, допустим, 192.168.1.100:40000. Шлюз после установления соединения начинает отправлять RTP поток. куда? Адрес-то левый! В итоге абонент в телефонной сети со стороны шлюза слышит голос из локалки, а его — не слышат. Типичный случай "one-way-voice".

    Поэтому компьютер в локальной сети должен сначала узнать свой внешний адрес и номер порта. Для этого в интернете существуют STUN-серверы. Упрощенно это выглядит так: компьютер из локалки посылает STUN-серверу пакет, тот его получает и отправляет обратно, запихнув внутрь адрес и номер порта, с которых он их получил. Дальше предпринимаются еще несколько действий для выяснения типа NATa, но это уже не так важно и хорошо описано в статье по ссылке выше.

    Теперь дело техники: компьютер в локалке передаст в SDP не свой локальный адрес, а полученный через STUN. Путь пакетам уже "пробит" запросом к STUN-серверу (т.е. NAT установил соответствие локальный хост : порт <-> внешний порт), поэтому входящие извне пакеты попадут в локалку и слышимость будет обоюдная.

    Stun Server

    In this post we will learn about the STUN Server and it's friends TURN, NAT, ICE and UDP, let's get started.

    STUN server: What is it? and how does it make the magic of WebRTC work.

    This is a story about packets of data and how do they travel peer-to-peer between 2 devices through very difficult terrain of corporate firewalls, Multiple NATs, flaky connections and unknown network addresses ports.

    Our Journey begins with the STUN server, and we will also learn about the following along the way:

    • What are Stun Servers?
    • What are Turn Servers?
    • What is NAT Traversal?
    • What are ICE Candidates?
    • What is the UDP Protocol?

    Stun server

    What is a STUN Server?​

    How do the Outside World of internet see me?

    STUN is a protocol that allows the host application to discover the presence of NAT on the network, and if found get the public IP address and port for the current connection.

    To achieve this the STUN protocol requires a well known third party server on the public network i.e the internet called the STUN server.

    But, What is a NAT and how do they come up to be?

    IP addresses depletion Problem​

    So many devices are being born, we can't feed them all.

    During the 1990 there was a cambrian explosion of devices on the internet.

    And as we know the IPV4 is a 32bit number, so there are only 4.29 billion unique IPV4 addresses in the world.

    The people running the internet were worried, we cannot give every device its own IP address, something needs to be done about this.

    They came up with a temporary solution called NAT which like most things in life became a permanent solution and we have NAT everywhere.

    NAT design

    What's a NAT? and how do we traverse the NAT?​

    NAT or Network address translation is a method of mapping an IP address space to allow the traffic to get to its destination when a device does not have a public IP address.

    A NAT device at the edge of a network, which would be mapped to a public IP address and which will have a table of local IP addresses.

    The devices behind the NAT will use the local IP addresses and the public IP address of the NAT will be used for all the devices behind the NAT.

    So, any traffic that needs to go to any device behind the NAT will be sent to the public IP of the NAT and NAT will have a table of devices with mapped local address

    NAT will send the traffic to the local device behind it.

    To the world on internet all the devices behind the NAT look like a single device.

    The local address shall remain unknown to the outside world, so some IP subnets were reserved for the local networks i.e

    • 10.0.0.0 – 10.255.255.255
    • 172.16.0.0 – 172.31.255.255
    • 192.168.0.0 – 192.168.255.255

    These addresses should not be routed in the internet and were reserved for local use and thus be reused, and in front of these private ip addresses there will be a NAT device that would have globally route-able public ip address and would do that translation from public to private addresses and vice versa for its network.

    Hence using one public IP for many devices.

    Usually in a home or office the internet service provider provides a single public IP address and all the devices are behind this IP address.

    To reach a specific device from the outside world the outside servers sends the packets to the public IP address and then the NAT transfers the data to the device on the local IP address because the NAT know which device on the local network requested the data.

    The problem arises if we want to establish a direct connection between two or more clients, because with NAT all the clients will be behind a NAT.

    It only knows it s internal local IP address and the NAT devices rewrites the source port and address in every UDP packet as well as the originating IP addresses within the IP packet.

    The client cannot communicate with outside peers with its internal IP address because connection will fail.

    Hence, the application must discover its public IP address and then share it with a peer outside its network.

    However, Just knowing about the public IP address does not solve the problem.

    Any packet that arrives at the public IP of a NAT device must also have a destination port and an entry into the NAT table that can translate it to an internal IP to an internal destination host IP and port.

    If this entry does not exists which is most likely the case if the client is directly communicating with its peers from the outside world then the NAT drops the packets because NAT has no way of knowing where to send this packet (that is to which device this packet needs to go).

    TO work around this mismatch various Traversal techniques have been invented namely (STUN, TURN and ICE).

    These are use to establish end-to-end connectivity between peers across the network.

    STUN Server: The Deep Dive.​

    Session Traversal Utilities for NAT (STUN) is a protocol that allows the host applications to discover the presence of NAT on a network.

    When the NAT is found STUN also allows the public IP and the port of the local device connection to be discovered.

    For this protocol to work there must be a well known stun server available on the public network

    Assuming the IP address of the STUN server is known, because it is on the public network (through DNS stun for UDP or stuns for TCP/TLS server resource record. or manually writing the public address of the STUN server).

    The client application sends a binding request to the STUN server and the server responds with the public IP address and host of the client as seen through the eyes of the public stun server.

    The result is obfuscated through exclusive or (XOR) mapping to avoid translation of the packet content by application layer gateways that perform deep packet inspection in an attempt to perform alternate NAT traversal methods.

    This solves many problems that we discover while sending data through NAT:

    The client discover the public IP and port of its peers and is able to communicate with its peers.

    The outbound request to the STUN server create an routing entry into the NAT table along the path.

    such that the inbound packets can find their path to the host on the local network when they arrive at the public IP address.

    The STUN protocol defines a simple mechanism for keep alive pings to keep the NAT routing entries from timing out.

    With STUN servers in place when ever two peers want to connect with each other they will send their requests to their STUN servers and after a successful response from both sides they can establish a public IP and port to exchange data.

    STUN messages are sent using the UDP protocol and since as we have discussed above the UDP is not a reliable protocol. reliability must be implement through application control retransmissions.

    The STUN servers themselves do not implement any reliability methods inside them. If reliability is mandatory TCP can be used and for security STUN packets can be encrypted using the TLS security layer.

    In practice, However STUN servers are not sufficient to deal with all NAT topologies and network conditions

    Sometimes commonly in corporate environments UDP might be blocked in the firewall settings.

    To deal with this issue, whenever STUN fails we can fallback on TURN (Traversal using Relay around NAT) the KEY word here is Relay.

    Metered Video provides a free WebRTC TURN server to relay traffic across networks.

    We will learn more about how TURN works in the section after this one.

    Going Even Deeper​

    STUN is a client server protocol. IT supports 2 types of transactions.

    The first one is a client server request, where a client sends a request to the server and the server responds.

    The second one is called a indication transaction, this can be send through with the client or the server but it generates no response.

    Both the transactions include a transactionID, a randomly selected 96 bit number.

    For the client server transaction the transactionID acts as a verification tool and for the indication transaction it can act as a debugging tool.

    All stun messages start with a fixed header that contains the following:

    1. a method
    2. a class
    3. a transactionID

    The only mandatory method is the binding method which indicates the various requests.

    The binding method is used to determine the particular binding a NAT response has allocated to the client. the binding method can also be used to keep the bindings alive.

    The class indicates whether this is a :

    1. request
    2. success response
    3. an error response
    4. an indication

    In the Binding request/ response transactions a binding request is sent from the client to the server.

    TO reach the server the binding request passes through a single NAT or multiple NATS that are between the client and the server As the Binding requests pass through NATs the NAT modifies the source transport address ( that is the source IP address and the source port) of the packet.

    As a result when the server receive the packet from the NAt it will contain the public IP address and port of the NAt closest to the server.

    This is called as reflexive transport addresses.

    The stun server then copies this address in an COR mapped addresses and sends it back to the client in the STUN binding response.

    As this packet passes through the NAT the NAt will modify the destination transport header in the IP header but the XOR MAPPED ADDRESS will remain untouched.

    In this the client learns its XOR-MAPPED-HEADER

    Show me the Terms:​

    STUN Agent: The entity that implements the STUN protocol. The entity could be a client or a server.

    STUN client: The entity that sends the STUN requests and gets the stun responses is a STUN client.

    STUN server: The entity that receives a STUN requests and sends the STUN responses is a STUN server.

    Transport Address: Ip address and port number combination is called as a Transport address.

    Reflexive Transport Address: The address as seen by the STUN server. Reflexive Transport address is the mapped address allocated to the client on the other side of the NAT.

    Mapped Address: same meaning as reflective address.

    Long-Term Credentials a username and password that is a shared Credential between a server and the class. Long term credentials are generally granted to the client by a service provider (a service provider that is offering the service. Example: a free service provider is the Open Relay Project by Metered Video they provide a free public turn server.)

    Long-Term Password password is a long term Credential

    Short-Term Credentials A temporary username and password that is used to establish a connection between the client and the server before the STUN exchange. They are exchanged with some kind of mechanism.

    Short-Term Password A short term password

    STUN indication: A STUN message that does not receive a response.

    Attribute A Type length Value object that can be added to the STUN message. There are 2 types

    RTO Retransmission Timeout: Time between initial transmission of request and another retransmit of that request

    Not the server just the protocol workings : STUN​

    In this section we will discuss the following

    1. How STUN messages are formed
    2. How STUN messages are sent
      1. Sending Request over the UDP protocol
      2. Sending Request over the TCP or TLS-over-IP protocol

      How STUN messages are formed​

      The STUN agent creates a STUN message. The STUN message class must be wither "Request" or "Indication" and the method must be either "binding" or some other methods For Binding method with no auth no attributes are required.

      Sending a request​

      The STUN message must specify the transport protocol that is being used and how the agent determines the IP address and port of the recipient.

      STUN agent can also use DNS to determine the IP address and port number of the host.

      A client can have multiple outstanding requests with the same TURN server.

      Care must be taken given other considerations that new transactions are spaced to a server by RTO and should limit itself to 10 outstanding transactions to the same server.

      Sending over UDP​

      When sending packets over UDP it is possible that the packets are dropped as the UDP offers No guarantees to reach the destination No failure notifications

      reliability of STUN requests must be accomplished through retransmissions of the request message by the client itself.

      The client can retransmit the request message starting with the RTO (retransmission Time out) interval and doubling after each retransmission. retransmissions can continue until a response is received or until the total Rc requests have be exhaused the default Rc requests is 7.

      Sending over TCP /IP​

      For transmitting the STUN messages over the TCP the client opens are TCP connection to the server.

      In some use cases the STUN is send as the only protocol over the TCP connection, in these cases the STUN can be sent with any additional framing or multiplexing.

      In other use cases STUN is sent STUN is multiplexed with other data over the TCP connection.

      When STUN is multiplexed with other data over the TCP connection some kind of framing protocol is required and STUN runs on top of that framing protocol.

      That framing protocol allows the STUN messages to be received.

      If you are running the STUN messages over TCP the RCA cipher must be implemented at a minimum but other cipher suites can also be used.

      reliability of STUN messages being received is handled by TCP itself and there is no need for retransmissions at the STUN protocol level

      For a request / response transaction if the client is unable to establish a connection over TCP or if the TCP connection is reset of fails then the request / response transaction is considered to have failed.

      the client can send multiple requests over TCP and it can send multiple requests even before receiving a response.

      The client should keep the connection open until

      • all the STUN requests have been sent over the connection
      • have no plans to use any other resources that were learned through STUN requests or relayed address (TURN)

      The server should keep the communication open and let the client end the communication unless it is timed out.

      Bindings learned by the client are valid only such time as the connection is open.

      Receiving STUN messages​

      When a STUN server receives a message, it checks for the following criteria.

      1. Are the first 2 bits 0 ?
      2. Magic cookie field has the correct value?
      3. Does the message length makes sense?
      4. Is the message class allowed for the particular method?
      5. Is the message value a supported method?
      6. If it is a success response or a error response it checks whether the transactionID is the same as the transactionID of the current transaction in process.
      7. If errors are detected the message is silently discarded.
      8. If fingerprint attribute is used the agent checks if the fingerprint attribute is present and if it is correct.
      9. If there are any authentication mechanisms in place the STUN checks for the authentication.
      Processing the request.​

      How does the STUN agent process the request once it is received. It does the following processes:

      1. Checks for one or more unknown comprehension-required attributes and if present sends the error response with the code 403 and includes an UNKNOWN-ATTRIBUTE response in the response listing the unknown attributes.
      2. Does any additional checking that is required by the method and formulates a success response.
      Formulating a Success or ERROR response​

      The method of sending the success or error response is the same as that of receiving the request.

      success response sends the data along with the success code of 200.

      For the ERROR response the server adds an error code attribute to the response.

      a phrase is also added to the error response that describes the type of error.

      turn-server

      TURN Server: Just the server Not the protocol.​

      Turn Server is a server that is required to relay traffic between 2 hosts/ peers that are in different networks.

      This is because a direct connection is not possible between 2 peers unless they are on the same network(This is because firewall blocks the traffic).

      The Term TURN server stands for Traversal using NAT.

      There are currently a few options for TURN servers online, one of them is the Open Relay Project by Metered Video they provide a public TURN server for Free.

      This is how TURN server works in practice

      1. Multiple clients send their requests to the same TURN server following by authentication and permission negotiations
      2. Once the connection is establish and the negotiations are completed the clients communicate with the TURN server which in turn relays the data to the other clients.

      Using TURN servers means that the communication is no longer peer-to-peer and must go through the server.

      TURN is the most reliable method of communicating between peers but it carries a high cost in terms of network traffic as all traffic must go through the server and as much in many scenarios it is used as a last resort when connectivity fails.

      TURN server configuration​

      Once you have a TURN server online, all you need is the correct RTCconfiguration for the client to use it.

      If you are using the Free turn server provided by the Open Relay Project then they have provided the configuration

      A demo configuration if you are using your own TURN server would be.

      Turn server will have the host name and will be running on a port. the configuration object supports username and password fields

      Testing the TURN Server.​

      Go to the Trickle ICE website at

      and enter the TURN server credentials

      ICE Candidates

      ICE Candidates​

      Building an effective NAT traversal solution is a very difficult given the layers upon layers of NAT and firewalls blocking ports and protocols. Thankfully ICE has been developed as an effective protocol to traverse the NAT ICE or Interactive Connectivity Establishment protocol is a set of methods that see to establish the most efficient tunnel between the participants

      1. Connecting peers directly when possible
      2. Using STUN negotiation when needed
      3. and fallback on TURN when needed.

      The STUN server and the data transport is done on the UDP protocol. Let's learn more about the UDP protocol:

      The UDP Protocol​

      Jon Postel added the UDP protocol or the User Datagram Protocol to the core network protocol suite on August of 1980, about the time TCP and IP specifications were being split into 2 different RFCs.

      This timing is important, because the primary appeal of the UDP protocol is not in what it introduces but in what it chooses to omit.

      The UDP is also called the null protocol or the unreliable datagram protocol indeed the RFC of the UDP could easily fit on a paper napkin:

      A self-contained, independent entity of data carrying sufficient information to be routed from the source to the destination nodes without reliance on earlier exchanges between the nodes and the transporting network.

      While datagram and packets are terms that are used interchangeable there are some differences. While packet refers to a formatted block of code the datagram refers to a block of code transported via unreliable networks.

      The defining feature of the UDP protocol is the unreliable nature of transportation of data. That is:

      • No delivery guarantees
      • No failure notifications

      For this reason UDP is called Unreliable Datagram protocol instead of the official term User Datagram protocol and this is the reason UDP packets are called as DataGrams.

      While you might be wondering if it is unreliable, what use can it be of when there are other reliable protocols available. Well people have built reliable systems off of unreliable protocols and what the UDP loses in reliability it gains in speed and throughput

      The webRTC (Web real time communications) standards that enable video calling, voice calling, and data transfers of all kinds run on the UDP protocol.

      Null Protocol Services​

      To understand UDP, lets look at the Internet Protocol (IP), which is located one layer below the both TCP and UDP protocols.

      The primary task of the IP protocol is delivering datagrams or packets from source to the destination host based on their addresses.

      Messages are encapsulated within the IP packet which identifies the source and destination of the address as well a number of routing parameters

      The IP layer provides no guarantees of delivery or notification of failures hence exposes the unreliability of the underlying protocol to the layers above it.

      If a routing node drops a packet due to congestion, high load or any other reason then it is the responsibility of the layers above it to recover, retransmit the data if that is the desired behavior.

      bit +0.7 +0.7 +8.15 +8.15 +16.23 +24.31
      0 Version Header Length DSCP ECN Total Length Total Length
      32 Identification Identification Identification Identification Flags Fragment Offset
      64 Time to Live Time to Live Protocol Protocol Header Checksum Header Checksum
      96 Source IP Address Source IP Address Source IP Address Source IP Address Source IP Address Source IP Address
      128 Destination IP Address Destination IP Address Destination IP Address Destination IP Address Destination IP Address Destination IP Address
      160 Options (if present) Options (if present) Options (if present) Options (if present) Options (if present) Options (if present)
      . payload payload payload payload payload payload

      IPV4 header

      Bit +0.7 +0.7 +8.15 +8.15 +16.23 +24.31
      0 source port source port source port source port Destination Port Destination Port
      32 length length length length checksum checksum
      . payload payload payload payload payload payload

      UDP header

      UDP protocol encapsulates the User messages into its own package structure which adds 4 more fields to the IP layer

      • source port
      • destination port
      • length of the packet
      • checksum

      When the IP delivers the packet to the destination host the host is able to identify the target application by the destination port and deliver the message.

      At its code, UDP just provides application multiplexing above the IP protocol by embedding the source and target application ports of the communicating hosts. Let us summarize all the UDP non-services:

      • No guarantees of message delivery: No acknowledgements, retransmissions or timeouts
      • No guarantees of order of delivery: No packet sequence numbers, no reordering, no head-of-line blocking
      • No connection state tracking No connection establishment or teardown state machines
      • No congestion control No built in client or network feedback mechanisms

      Conclusion:​

      In this article we have listed how the STUN protocol works and how its friends namely the TURN server, the ICE protocol and the UDP protocol help with the connection and transmission of data through webrtc.

      Читать:
      Как подключить стром 1000 к конфиденциальной сети

Похожие статьи