Перейти к содержанию

🚀 Где задеплоить проект?

Партнёрская ссылка. Дата-центры в РФ, оплата картой.

QUIC

Стабильность: 1 – Экспериментальная

1.0 — ранняя разработка. Возможность ещё не завершена и может существенно измениться. Эта возможность не подпадает под правила семантического версионирования.

Модуль node:quic реализует протокол QUIC. Чтобы им пользоваться, запустите Node.js с опцией --experimental-quic:

1
import quic from 'node:quic';
1
const quic = require('node:quic');

Модуль доступен только в схеме node:.

quic.connect(address[, options])

Инициирует новую клиентскую сессию.

1
2
3
4
5
6
7
8
9
import { connect } from 'node:quic';
import { Buffer } from 'node:buffer';

const enc = new TextEncoder();
const alpn = 'foo';
const client = await connect('123.123.123.123:8888', { alpn });
await client.createUnidirectionalStream({
  body: enc.encode('hello world'),
});

По умолчанию каждый вызов connect(...) создаёт новый локальный экземпляр QuicEndpoint, привязанный к новому случайному локальному IP-порту. Чтобы задать точный локальный адрес или мультиплексировать несколько сессий QUIC через один локальный порт, передайте опцию endpoint со значением QuicEndpoint или EndpointOptions.

1
2
3
4
5
6
7
import { QuicEndpoint, connect } from 'node:quic';

const endpoint = new QuicEndpoint({
  address: '127.0.0.1:1234',
});

const client = await connect('123.123.123.123:8888', { endpoint });

quic.listen(onsession,[options])

Настраивает endpoint на прослушивание как сервер. Когда удалённый пир инициирует новую сессию, вызывается переданный callback onsession с созданной сессией.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import { listen } from 'node:quic';

const endpoint = await listen((session) => {
  // ... обработка сессии
});

// Закрытие endpoint позволяет завершить уже открытые на момент close
// сессии естественным образом и не принимать новые.
// Когда все сессии завершатся, endpoint будет уничтожен.
// Вызов возвращает промис, который выполнится после уничтожения endpoint.
await endpoint.close();

По умолчанию каждый вызов listen(...) создаёт новый локальный QuicEndpoint, привязанный к новому случайному локальному IP-порту. Чтобы задать точный локальный адрес или мультиплексировать несколько сессий QUIC через один локальный порт, передайте опцию endpoint со значением QuicEndpoint или EndpointOptions.

Один QuicEndpoint можно настроить на прослушивание как сервер не более одного раза.

Класс: QuicEndpoint

QuicEndpoint инкапсулирует локальную привязку UDP-порта для QUIC. Может использоваться и как клиент, и как сервер.

new QuicEndpoint([options])

endpoint.address

Локальный UDP-адрес сокета, к которому привязан endpoint, если есть.

Если endpoint сейчас не привязан, значение будет undefined. Только для чтения.

endpoint.busy

Если endpoint.busy равен true, endpoint временно отклоняет создание новых сессий. Чтение и запись.

1
2
3
4
5
// Пометить endpoint занятым — новые сессии не принимаются
endpoint.busy = true;

// Снять занятость — новые сессии снова разрешены
endpoint.busy = false;

Свойство busy полезно при высокой нагрузке на endpoint, когда нужно временно отклонять новые сессии, пока он не разгрузится.

endpoint.close()

Корректно закрывает endpoint. Endpoint закроется и уничтожится, когда закроются все текущие сессии. После вызова новые сессии отклоняются.

Возвращает промис, выполняющийся после уничтожения endpoint.

endpoint.closed

Промис, выполняющийся после уничтожения endpoint. Это тот же промис, что возвращает endpoint.close(). Только для чтения.

endpoint.closing

true, если вызван endpoint.close() и закрытие endpoint ещё не завершилось. Только для чтения.

endpoint.destroy([error])

Принудительно закрывает endpoint, немедленно закрывая все открытые сессии.

endpoint.destroyed

true, если вызван endpoint.destroy(). Только для чтения.

endpoint.setSNIContexts(entries[, options])

  • entries <object> Объект «имя хоста — параметры TLS-идентичности». В каждой записи должны быть keys и certs.
  • options <object>
    • replace <boolean> Если true, заменяет всю карту SNI. Если false (по умолчанию), объединяет записи с существующей картой.

Заменяет или обновляет TLS-контексты SNI для этого endpoint. Позволяет менять TLS-идентичность (ключ/сертификат) для имён хостов без перезапуска endpoint. Существующие сессии не затрагиваются — обновлённые контексты используют только новые сессии.

1
2
3
4
5
6
7
8
endpoint.setSNIContexts({
  'api.example.com': { keys: [newApiKey], certs: [newApiCert] },
});

// Заменить всю карту SNI
endpoint.setSNIContexts({
  'api.example.com': { keys: [newApiKey], certs: [newApiCert] },
}, { replace: true });

endpoint.stats

Статистика, собранная для активной сессии. Только для чтения.

endpoint[Symbol.asyncDispose]()

Вызывает endpoint.close() и возвращает промис, выполняющийся после закрытия endpoint.

Класс: QuicEndpoint.Stats

Представление собранной статистики для endpoint.

endpointStats.createdAt

  • Тип: <bigint> Метка времени создания endpoint. Только для чтения.

endpointStats.destroyedAt

  • Тип: <bigint> Метка времени уничтожения endpoint. Только для чтения.

endpointStats.bytesReceived

  • Тип: <bigint> Общее число байт, полученных этим endpoint. Только для чтения.

endpointStats.bytesSent

  • Тип: <bigint> Общее число байт, отправленных этим endpoint. Только для чтения.

endpointStats.packetsReceived

  • Тип: <bigint> Общее число успешно принятых этим endpoint QUIC-пакетов. Только для чтения.

endpointStats.packetsSent

  • Тип: <bigint> Общее число успешно отправленных этим endpoint QUIC-пакетов. Только для чтения.

endpointStats.serverSessions

  • Тип: <bigint> Общее число сессий, инициированных пиром и принятых этим endpoint. Только для чтения.

endpointStats.clientSessions

  • Тип: <bigint> Общее число сессий, инициированных этим endpoint. Только для чтения.

endpointStats.serverBusyCount

  • Тип: <bigint> Сколько раз начальный пакет был отклонён из-за пометки endpoint как занятого. Только для чтения.

endpointStats.retryCount

  • Тип: <bigint> Общее число попыток QUIC retry на этом endpoint. Только для чтения.

endpointStats.versionNegotiationCount

  • Тип: <bigint> Общее число сессий, отклонённых из-за несовпадения версии QUIC. Только для чтения.

endpointStats.statelessResetCount

  • Тип: <bigint> Общее число обработанных этим endpoint stateless reset. Только для чтения.

endpointStats.immediateCloseCount

  • Тип: <bigint> Общее число сессий, закрытых до завершения рукопожатия. Только для чтения.

Класс: QuicSession

QuicSession представляет локальную сторону QUIC-соединения.

session.close()

Инициирует корректное закрытие сессии. Уже открытые потоки могут завершиться, новые не открываются. Когда все потоки закроются, сессия будет уничтожена. Промис выполнится после уничтожения сессии.

session.closed

Промис, выполняющийся после уничтожения сессии.

session.destroy([error])

Немедленно уничтожает сессию. Все потоки уничтожаются, сессия закрывается.

session.destroyed

true, если вызван session.destroy(). Только для чтения.

session.endpoint

Конечная точка, создавшая эту сессию. Только для чтения.

session.onstream

Вызывается при инициации нового потока удалённым пиром. Чтение и запись.

session.ondatagram

Вызывается при получении новой датаграммы от удалённого пира. Чтение и запись.

session.ondatagramstatus

Вызывается при изменении статуса датаграммы. Чтение и запись.

session.onpathvalidation

Вызывается при обновлении проверки пути. Чтение и запись.

session.onsessionticket

Вызывается при получении нового session ticket. Чтение и запись.

session.onversionnegotiation

Вызывается при начале согласования версии. Чтение и запись.

session.onhandshake

Вызывается при завершении TLS-рукопожатия. Чтение и запись.

session.createBidirectionalStream([options])

Открывает новый двунаправленный поток. Если опция body не указана, исходящий поток будет полузакрыт.

session.createUnidirectionalStream([options])

Открывает новый однонаправленный поток. Если опция body не указана, исходящий поток будет закрыт.

session.path

Локальный и удалённый адреса сокета, связанные с сессией. Только для чтения.

session.sendDatagram(datagram)

Отправляет ненадёжную датаграмму удалённому пиру, возвращая идентификатор датаграммы. Если полезная нагрузка задана как ArrayBufferView, владение этим представлением передаётся нижележащему потоку.

session.stats

Текущая статистика сессии. Только для чтения.

session.updateKey()

Инициирует обновление ключа для сессии.

session[Symbol.asyncDispose]()

Вызывает session.close() и возвращает промис, выполняющийся после закрытия сессии.

Класс: QuicSession.Stats

sessionStats.createdAt

sessionStats.closingAt

sessionStats.handshakeCompletedAt

sessionStats.handshakeConfirmedAt

sessionStats.bytesReceived

sessionStats.bytesSent

sessionStats.bidiInStreamCount

sessionStats.bidiOutStreamCount

sessionStats.uniInStreamCount

sessionStats.uniOutStreamCount

sessionStats.maxBytesInFlights

sessionStats.bytesInFlight

sessionStats.blockCount

sessionStats.cwnd

sessionStats.latestRtt

sessionStats.minRtt

sessionStats.rttVar

sessionStats.smoothedRtt

sessionStats.ssthresh

sessionStats.datagramsReceived

sessionStats.datagramsSent

sessionStats.datagramsAcknowledged

sessionStats.datagramsLost

Класс: QuicStream

stream.closed

Промис, выполняющийся после полного закрытия потока.

stream.destroy([error])

Немедленно и аварийно уничтожает поток.

stream.destroyed

true, если вызван stream.destroy().

stream.direction

  • Тип: <string> Одно из значений: 'bidi' или 'uni'.

Направленность потока. Только для чтения.

stream.id

Идентификатор потока. Только для чтения.

stream.onblocked

Вызывается, когда поток заблокирован. Чтение и запись.

stream.onreset

Вызывается при сбросе потока. Чтение и запись.

stream.readable

stream.session

Сессия, создавшая этот поток. Только для чтения.

stream.stats

Текущая статистика потока. Только для чтения.

Класс: QuicStream.Stats

streamStats.ackedAt

streamStats.bytesReceived

streamStats.bytesSent

streamStats.createdAt

streamStats.destroyedAt

streamStats.finalSize

streamStats.isConnected

streamStats.maxOffset

streamStats.maxOffsetAcknowledged

streamStats.maxOffsetReceived

streamStats.openedAt

streamStats.receivedAt

Типы

Тип: EndpointOptions

Параметры конфигурации endpoint, передаваемые при создании QuicEndpoint.

endpointOptions.address

Если не указано, endpoint привяжется к IPv4 localhost на случайном порту.

endpointOptions.addressLRUSize

Конечная точка хранит внутренний кэш проверенных адресов сокетов для оптимизации. Эта опция задаёт максимальное число адресов в кэше. Расширенная опция, обычно не требуется.

endpointOptions.ipv6Only

При true endpoint привязывается только к IPv6-адресам.

endpointOptions.maxConnectionsPerHost

Максимальное число одновременных сессий на один удалённый адрес пира.

endpointOptions.maxConnectionsTotal

Максимальное общее число одновременных сессий.

endpointOptions.maxRetries

Максимальное число попыток QUIC retry на один удалённый адрес пира.

endpointOptions.maxStatelessResetsPerHost

Максимальное число stateless reset на один удалённый адрес пира.

endpointOptions.retryTokenExpiration

Время, в течение которого считается действительным QUIC retry token.

endpointOptions.resetTokenSecret

16-байтовый секрет для генерации QUIC retry token.

endpointOptions.tokenExpiration

Время, в течение которого считается действительным QUIC token.

endpointOptions.tokenSecret

16-байтовый секрет для генерации QUIC token.

endpointOptions.udpReceiveBufferSize

endpointOptions.udpSendBufferSize

endpointOptions.udpTTL

endpointOptions.validateAddress

При true endpoint должен проверять адреса пиров через retry-пакеты при установлении нового соединения.

Тип: SessionOptions

sessionOptions.alpn

Идентификатор(ы) ALPN (согласование протокола прикладного уровня).

Для клиентских сессий — одна строка с желаемым протоколом (например 'h3').

Для серверных сессий — массив имён протоколов в порядке предпочтения, которые поддерживает сервер (например ['h3', 'h3-29']). При TLS-рукопожатии сервер выбирает первый протокол из своего списка, который поддерживает и клиент.

Согласованный ALPN определяет прикладную реализацию для сессии. Варианты 'h3' и 'h3-*' выбирают HTTP/3; остальные значения — реализацию по умолчанию.

По умолчанию: 'h3'

sessionOptions.ca (только клиент)

Сертификаты центра сертификации (CA) для клиентских сессий. Для серверных сертификаты CA задаются по идентичности в карте sessionOptions.sni.

sessionOptions.cc

Алгоритм контроля перегрузки; должен быть одним из 'reno', 'cubic' или 'bbr'.

Расширенная опция, обычно не требуется.

sessionOptions.certs (только клиент)

TLS-сертификаты для клиентских сессий. Для серверных сессий сертификаты задаются по идентичности в sessionOptions.sni.

sessionOptions.ciphers

Список поддерживаемых шифров TLS 1.3.

sessionOptions.crl (только клиент)

Списки отзыва сертификатов (CRL) для клиентских сессий. Для серверных CRL задаются по идентичности в sessionOptions.sni.

sessionOptions.groups

Список групп шифров TLS 1.3.

sessionOptions.keylog

true — включить вывод TLS key logging.

sessionOptions.keys (только клиент)

Криптографические ключи TLS для клиентских сессий. Для серверных ключи задаются по идентичности в sessionOptions.sni.

sessionOptions.maxPayloadSize

Максимальный размер полезной нагрузки UDP-пакета.

sessionOptions.maxStreamWindow

Максимальный размер окна управления потоком.

sessionOptions.maxWindow

Максимальный размер окна управления сессией.

sessionOptions.minVersion

Минимально допустимый номер версии QUIC. Расширенная опция, обычно не требуется.

sessionOptions.preferredAddressPolicy

  • Тип: <string> Одно из 'use', 'ignore' или 'default'.

Если удалённый пир объявляет preferred address, опция задаёт, использовать его или игнорировать.

sessionOptions.qlog

true — включить вывод qlog.

sessionOptions.sessionTicket

  • Тип: <ArrayBufferView> Билет сессии для возобновления сессии 0-RTT.

sessionOptions.handshakeTimeout

Максимальное время в миллисекундах на TLS-рукопожатие до тайм-аута.

sessionOptions.servername (только клиент)

Имя сервера пира (SNI). По умолчанию 'localhost'.

sessionOptions.sni (только сервер)

Объект «имя хоста — параметры TLS-идентичности» для поддержки указания имени сервера (SNI). Обязателен для серверных сессий. Специальный ключ '*' задаёт идентичность по умолчанию, если не подошло другое имя. В записи могут быть:

1
2
3
4
5
6
7
const endpoint = await listen(callback, {
  sni: {
    '*': { keys: [defaultKey], certs: [defaultCert] },
    'api.example.com': { keys: [apiKey], certs: [apiCert] },
    'www.example.com': { keys: [wwwKey], certs: [wwwCert], ca: [customCA] },
  },
});

Общие параметры TLS (ciphers, groups, keylog, verifyClient и др.) задаются на верхнем уровне опций сессии и применяются ко всем идентичностям. Каждая запись SNI переопределяет только поля сертификата.

Карту SNI можно заменить во время выполнения через endpoint.setSNIContexts(): карта атомарно меняется для новых сессий, существующие продолжают использовать прежнюю идентичность.

sessionOptions.tlsTrace

true — включить трассировку TLS.

sessionOptions.transportParams

Параметры транспорта QUIC для сессии.

sessionOptions.unacknowledgedPacketThreshold

Максимальное число неподтверждённых пакетов, допустимое для сессии.

sessionOptions.verifyClient

true — требовать проверку клиентского TLS-сертификата.

sessionOptions.verifyPrivateKey (только клиент)

true — требовать проверку закрытого ключа для клиентских сессий. Для серверных эта опция задаётся по идентичности в sessionOptions.sni.

sessionOptions.version

Номер версии QUIC. Расширенная опция, обычно не требуется.

Тип: TransportParams

transportParams.preferredAddressIpv4

  • Тип: <net.SocketAddress> Предпочитаемый объявляемый IPv4-адрес.

transportParams.preferredAddressIpv6

  • Тип: <net.SocketAddress> Предпочитаемый объявляемый IPv6-адрес.

transportParams.initialMaxStreamDataBidiLocal

transportParams.initialMaxStreamDataBidiRemote

transportParams.initialMaxStreamDataUni

transportParams.initialMaxData

transportParams.initialMaxStreamsBidi

transportParams.initialMaxStreamsUni

transportParams.maxIdleTimeout

transportParams.activeConnectionIDLimit

transportParams.ackDelayExponent

transportParams.maxAckDelay

transportParams.maxDatagramFrameSize

Обратные вызовы

Callback: OnSessionCallback

Вызывается при инициации новой сессии удалённым пиром.

Callback: OnStreamCallback

Callback: OnDatagramCallback

Callback: OnDatagramStatusCallback

Callback: OnPathValidationCallback

Callback: OnSessionTicketCallback

Callback: OnVersionNegotiationCallback

Callback: OnHandshakeCallback

Callback: OnBlockedCallback

Callback: OnStreamErrorCallback

Диагностические каналы

Channel: quic.endpoint.created

Channel: quic.endpoint.listen

Channel: quic.endpoint.closing

Channel: quic.endpoint.closed

Channel: quic.endpoint.error

Channel: quic.endpoint.busy.change

Channel: quic.session.created.client

Channel: quic.session.created.server

Channel: quic.session.open.stream

Channel: quic.session.received.stream

Channel: quic.session.send.datagram

Channel: quic.session.update.key

Channel: quic.session.closing

Channel: quic.session.closed

Channel: quic.session.receive.datagram

Channel: quic.session.receive.datagram.status

Channel: quic.session.path.validation

Channel: quic.session.ticket

Channel: quic.session.version.negotiation

Channel: quic.session.handshake

Комментарии