Как пробросить свой UDP-транспорт через RustDesk без патча сервера
vaalimusic 5 минут назад Как пробросить свой UDP-транспорт через RustDesk без патча сервера Сложный 4 мин 0 Open source * Rust * Сетевые технологии * Системное администрирование * Туториал Привет, Хабр!Есть...
Anthropic — What company has the best second artificial intelligence model at the end of June?
В сфере искусственного интеллекта произошло заметное событие. vaalimusic 5 минут назад Как пробросить свой UDP-транспорт через RustDesk без патча сервера Сложный 4 мин 0 Open source * Rust * Сетевые технологии * Системное администрирование * Туториал Привет, Хабр! Есть RustDesk-инфраструктура: rendezvous-сервер (hbbs) для NAT traversal и relay (hbbr) для проброса трафика, когда P2P не получился. И есть свой UDP-транспорт реального времени для видео (у меня это EVRT), который хочется гнать напрямую между пирами, минуя relay — ради задержки.
Вопрос: как двум пирам договориться о прямом UDP-канале, если они общаются только через RustDesk? Ответ короткий: RustDesk relay — это «тупая труба». Он передаёт зашифрованные PeerMessage между пирами и не парсит их содержимое.
Технические детали
Значит, в эти сообщения можно подложить свои данные — и сервер прозрачно их пробросит, ничего не зная про твой протокол. Расширяем Misc своими полямиDesk-сообщения — это protobuf. Внутри PeerMessage есть Misc с oneof-полем union.
Туда и добавляем свои варианты — с большими tag-номерами, заведомо вне диапазона, который использует апстрим RustDesk: // rustdesk_proto. proto oneof Почему tag 100+ — критично. protobuf — формат с прямой совместимостью: неизвестные поля просто игнорируются при декодировании.
RustDesk-сервер релеит наш PeerMessage как непрозрачный блоб (он его даже не расшифровывает — это E2E между пирами), но если бы и парсил — поля с tag 100/101 он бы пропустил, не сломавшись. А мы на своей стороне (оба пира — наш клиент) их видим. Берёшь незанятый диапазон — и расширяешь протокол, не трогая ни сервер, ни апстрим.
Отраслевые последствия
Хост анонсирует свой UDP-портХост уже подключён к клиенту через RustDesk (relay или P2P-TCP — неважно). Он биндит свой EVRT UDP-сокет и отправляет порт обычным PeerMessage по тому же каналу: fn evrt_port_message(port: u16) -> PeerMessage { }Это уходит в тот же зашифрованный поток, что и кадры/ввод. Для RustDesk-сервера это просто очередной байтовый блоб от хоста к клиенту.
Клиент собирает адрес и пробует P2P до relayТут вся соль. У клиента уже есть IP пира — его дал rendezvous-сервер в PunchHoleResponse. socket_addr при пробивке NAT.
А порт только что прилетел в . Складываем — получаем полный адрес для прямого UDP: Some(misc::Union::EvrtUdpPort(port)) => { let p = (*port). min(65535) as u16; if p > 0 { // IP уже есть от punch-hole, порт — отсюда.
Этот прогресс даёт важные сигналы о будущем отрасли, и технологический мир внимательно наблюдает.




