Перейти к основному содержимому

TURN

Протокол TURN для видеокоммуникаций

TURN (Traversal Using Relays around NAT) – это сетевой протокол, который используется для обеспечения связи между устройствами через NAT (Network Address Translation), особенно в случаях, когда прямое соединение невозможно. Этот протокол широко применяется в системах видеоконференцсвязи и VoIP (Voice over IP).

Основы работы протокола TURN

Протокол TURN позволяет устройству, находящемуся за NAT, установить TCP/UDP-соединение с сервером TURN, который затем будет пересылать данные от этого устройства к другим участникам сессии. Таким образом, даже если два устройства находятся за разными NAT, они могут обмениваться данными через посредника – TURN-сервер.

Основные компоненты системы:

  1. Клиент: устройство, которое хочет установить соединение.
  2. Сервер TURN: посредник, который помогает устройствам обходить ограничения NAT.
  3. Пир (Peer): другое устройство, с которым клиент хочет установить соединение.

Процесс взаимодействия выглядит следующим образом:

  1. Клиент отправляет запрос на сервер TURN с указанием типа соединения (TCP или UDP) и желаемого адреса назначения.
  2. Сервер TURN выделяет клиенту публичный адрес и порт, а также устанавливает туннель для пересылки данных.
  3. Когда другой пир отправляет данные на этот публичный адрес, сервер TURN перенаправляет их обратно клиенту.
  4. В случае двусторонней связи оба клиента могут использовать свои выделенные адреса и порты для обмена данными.

Формат сообщений TURN

Сообщения TURN передаются в формате STUN (Session Traversal Utilities for NAT), но имеют дополнительные поля для управления соединением. Основные типы сообщений включают:

  • Allocate: Запрос выделения ресурсов на сервере TURN.
  • CreatePermission: Создание разрешения для конкретного IP-адреса.
  • ChannelBind: Установка канала для передачи данных без использования дополнительных заголовков.
  • Send: Отправка данных через сервер TURN.
  • Data: Передача данных от сервера TURN клиенту.

Пример сообщения Allocate:

{
"magic": "0x2112A442",
"transactionID": "0x9cbe67a7b5e6d18f",
"messageType": "Allocate",
"length": 20,
"attributes": [
{
"type": "LIFETIME",
"value": 600
},
{
"type": "REQUESTED-TRANSPORT",
"value": "UDP"
}
]
}

Применение TURN в видеозвонках

Рассмотрим пример использования TURN в системе видеоконференцсвязи. Предположим, у нас есть два участника, каждый из которых находится за своим NAT. Прямое соединение между ними невозможно, поэтому они используют сервер TURN для установления связи.

  1. Оба участника отправляют запросы на выделение ресурсов на сервере TURN.
  2. Сервер TURN возвращает каждому участнику публичный IP-адрес и порт.
  3. Участники обмениваются этими адресами через сигнализационный сервер (например, SIP или WebRTC).
  4. Теперь участники могут отправлять данные друг другу через сервер TURN.

Пример реализации клиента TURN на Python с использованием библиотеки aioturn:

import asyncio
from aioturn import TurnClient

async def main():
client = await TurnClient.create('turn.example.com', 'username', 'password')

# Выделяем ресурсы на сервере TURN
allocation = await client.allocate()

# Получаем публичный IP-адрес и порт
public_ip, public_port = allocation.relayed_address

print(f'Public IP: {public_ip}, Public Port: {public_port}')

# Создаем разрешение для другого участника
peer_ip = '192.168.1.100'
await client.create_permission(peer_ip)

# Отправляем данные другому участнику
data = b'Hello, World!'
await client.send(data, peer_ip, 5000)

# Ожидаем получения данных от другого участника
received_data = await client.recv()
print(received_data)

# Освобождаем ресурсы
await client.close()

asyncio.run(main())

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