Как браузер выбирает TCP или UDP для соединения

Как браузер решает, какое соединение ему открывать, TCP или UDP?

Теория: кто выбирает транспорт

Браузер не “выбирает TCP или UDP” как взаимозаменяемые аналоги для одного и того же протокола, а следует стеку: прикладной протокол задаёт транспорт (например, HTTP/3 определён как отображение HTTP-семантики поверх QUIC).
QUIC, в свою очередь, определён как транспорт, пакеты которого переносятся в UDP-датаграммах, из-за чего “HTTP/3 = UDP” на практике означает “HTTP/3 = QUIC поверх UDP”.

Разделение ответственности обычно выглядит так: приложение (браузер) выбирает прикладной протокол и включает механизмы обнаружения/согласования, а ядро ОС выполняет системные вызовы для TCP- или UDP-сокета в соответствии с тем, что требуется протоколом.

Схема уровней (упрощённо):

браузер (URL, политика безопасности, кэш Alt-Svc/HTTPS RR)
↓
HTTP/1.1 или HTTP/2 (поверх TCP)  |  HTTP/3 (поверх QUIC)
↓                                  ↓
TCP                                 QUIC
↓                                  ↓
IP                                  UDP
↓                                  ↓
сеть                                сеть

Web-стек и примеры

HTTP/2 исторически использовался преимущественно как “TLS поверх TCP”, а HTTP/3 определён как перенос HTTP-семантики на QUIC.
Спецификация HTTP/3 фиксирует поведение при проблемах связности уровня UDP: при неудаче установления QUIC (например, когда UDP блокируется) клиенту следует попытаться использовать TCP-версии HTTP.

Три наиболее частые ситуации в веб-разработке:

  • Обычная загрузка страниц и API через https://...: возможна попытка HTTP/3 (QUIC/UDP) при наличии сигналов обнаружения, иначе HTTP/2 или HTTP/1.1 по TCP.
  • WebSocket (ws://, wss://): протокол является независимым TCP-ориентированным протоколом и концептуально является слоем поверх TCP, а связь с HTTP ограничена рукопожатием Upgrade.
  • WebRTC: стек реального времени включает транспортные варианты (TCP и UDP) и компоненты вроде ICE/STUN/TURN; обзорные документы описывают транспортный слой как область, где фигурируют TCP и UDP, и указывают на обязательность набора транспортных протоколов в профиле WebRTC.
Факт “UDP доступен” не гарантируется: UDP может блокироваться или ограничиваться сетевыми устройствами, поэтому механизмы отката (fallback) и/или “гонка” QUIC↔TCP встречаются в реальных реализациях и исследованиях производительности браузеров.

Как именно решается TCP/UDP

В HTTP/3 описано, что клиент может попытаться открыть QUIC-соединение к endpoint и использовать ALPN-токен h3 в ходе TLS-рукопожатия, а наличие HTTP/3 endpoint может объявляться через Alt-Svc/ALTSVC с токеном h3.
Alt-Svc определяется как способ, которым origin может рекламировать альтернативные сервисы в ответах, при этом получатель может игнорировать Alt-Svc, а порядок значений отражает предпочтение сервера.

Последовательность (типовая, упрощённая) для https://site.example/:

  1. Выполняется разрешение имени в адрес (обычно через ОС или встроенный резолвер).
  2. Проверяется локальное знание об HTTP/3 для origin: кэш Alt-Svc или данные из DNS HTTPS/SVCB.
  3. Если известен доступный HTTP/3 endpoint, выполняется попытка QUIC (UDP) и согласование приложения h3 через ALPN во время рукопожатия.
  4. Если QUIC не устанавливается из‑за проблем связности (например, блокировка UDP), выполняется попытка “TCP-based versions of HTTP” (например, HTTP/2 или HTTP/1.1).

Псевдокод логики (на уровне “как это выглядит концептуально”, не API браузера):

function connectForHttpsOrigin(origin):
  hints = loadCachedAltSvc(origin) + loadHttpsSvcb(origin)
  if hints.supports("h3"):
    if tryQuicUdp(origin, alpn="h3") == success:
      return transport="udp", protocol="http3"
  return transport="tcp", protocol=negotiateHttp1or2WithTlsAlpn(origin)

Пример сигналов “сервер поддерживает HTTP/3”:

Alt-Svc: h3=":443"; ma=86400

Примеры DNS HTTPS RR (идея параметров ALPN показана в документах про HTTPS/SVCB, где встречается alpn=h2,h3):

alt.example. IN HTTPS 1 . alpn=h2,h3
_8443._https.example.com. IN HTTPS 1 alt3.example. ( port=9443 alpn=h2,h3 )

Ключевой момент: DNS HTTPS/SVCB предназначены для передачи клиенту параметров, нужных для установления соединения к сетевому сервису, а также могут согласовываться по смыслу с уже закэшированным Alt-Svc.

Практика, таблица, подсказка

Практическая проверка обычно делается инструментами разработчика (инициатор, протокол, наличие “h3”), либо внешними утилитами, потому что из JavaScript транспорт напрямую не выбирается.
Для HTTP/3 важно помнить, что обслуживание возможно на любом UDP-порту, но альтернативный сервис всегда указывает порт явно.

Таблица “прикладной протокол → транспорт”:

Сценарий в браузереПрикладной протоколТранспортЧто влияет на выбор
Обычный https://HTTP/1.1 или HTTP/2TCPСогласование по TLS ALPN для HTTP/2, совместимость и политика клиента.
Обычный https:// при поддержке HTTP/3HTTP/3QUIC поверх UDPОбнаружение endpoint через Alt-Svc/ALTSVC и/или DNS HTTPS/SVCB, затем ALPN h3.
ws:// / wss://WebSocketTCPПротокол является TCP-ориентированным; HTTP нужен для Upgrade-рукопожатия.
Видеосвязь/RTCWebRTC suiteОбычно UDP (возможны TCP/TLS через реле)ICE/STUN/TURN и транспортный профиль, где рассматриваются TCP и UDP.

Кратко: транспорт (TCP или UDP) в браузере определяется выбранным прикладным протоколом и результатами согласования/обнаружения; HTTP/3 работает как QUIC поверх UDP и при проблемах UDP выполняется откат на TCP-версии HTTP, тогда как WebSocket остаётся TCP-ориентированным, а WebRTC чаще опирается на UDP с механизмами обхода NAT.