- Assertion testing
- Async hooks
- Buffer
- C++ addons
- C/C++ addons with N-API
- C++ embedder API
- Child processes
- Cluster
- Command-line options
- Console
- Crypto
- Debugger
- Deprecated APIs
- DNS
- Domain
- Errors
- Events
- File system
- Globals
- HTTP
- HTTP/2
- HTTPS
- Inspector
- Internationalization
- Modules: CommonJS modules
- Modules: ECMAScript modules
- Modules:
module
API - Modules: Packages
- Net
- OS
- Path
- Performance hooks
- Policies
- Process
- Punycode
- Query strings
- QUIC
- Readline
- REPL
- Report
- Stream
- String decoder
- Timers
- TLS/SSL
- Trace events
- TTY
- UDP/datagram
- URL
- Utilities
- V8
- VM
- WASI
- Worker threads
- Zlib
Node.js v15.0.0-test20201005a7f6681ae6 Documentation
Table of Contents
- QUIC
- Example
- QUIC basics
- QUIC and HTTP/3
- QUIC JavaScript API
net.createQuicSocket([options])
- Class:
QuicEndpoint
quicendpoint.addMembership(address, iface)
quicendpoint.address
quicendpoint.bind([options])
quicendpoint.bound
quicendpoint.close()
quicendpoint.closing
quicendpoint.destroy([error])
quicendpoint.destroyed
quicendpoint.dropMembership(address, iface)
quicendpoint.fd
quicendpoint.pending
quicendpoint.ref()
quicendpoint.setBroadcast([on])
quicendpoint.setMulticastInterface(iface)
quicendpoint.setMulticastLoopback([on])
quicendpoint.setMulticastTTL(ttl)
quicendpoint.setTTL(ttl)
quicendpoint.unref()
- Class:
QuicSession extends EventEmitter
- Event:
'close'
- Event:
'error'
- Event:
'keylog'
- Event:
'pathValidation'
- Event:
'secure'
- Event:
'stream'
quicsession.ackDelayRetransmitCount
quicsession.address
quicsession.alpnProtocol
quicsession.authenticated
quicsession.authenticationError
quicsession.bidiStreamCount
quicsession.blockCount
quicsession.bytesInFlight
quicsession.bytesReceived
quicsession.bytesSent
quicsession.cipher
quicsession.close()
quicsession.closeCode
quicsession.closing
quicsession.destroy([error])
quicsession.destroyed
quicsession.duration
quicsession.getCertificate()
quicsession.getPeerCertificate([detailed])
quicsession.handshakeAckHistogram
quicsession.handshakeContinuationHistogram
quicsession.handshakeComplete
quicsession.handshakeConfirmed
quicsession.handshakeDuration
quicsession.idleTimeout
quicsession.keyUpdateCount
quicsession.latestRTT
quicsession.lossRetransmitCount
quicsession.maxDataLeft
quicsession.maxInFlightBytes
quicsession.maxStreams
quicsession.minRTT
quicsession.openStream([options])
quicsession.ping()
quicsession.peerInitiatedStreamCount
quicsession.qlog
quicsession.remoteAddress
quicsession.selfInitiatedStreamCount
quicsession.servername
quicsession.smoothedRTT
quicsession.socket
quicsession.statelessReset
quicsession.uniStreamCount
quicsession.updateKey()
quicsession.usingEarlyData
- Event:
- Class:
QuicClientSession extends QuicSession
- Class:
QuicServerSession extends QuicSession
- Class:
QuicSocket
- Event:
'busy'
- Event:
'close'
- Event:
'endpointClose'
- Event:
'error'
- Event:
'listening'
- Event:
'ready'
- Event:
'session'
- Event:
'sessionError'
quicsocket.addEndpoint(options)
quicsocket.blockList
quicsocket.bound
quicsocket.boundDuration
quicsocket.bytesReceived
quicsocket.bytesSent
quicsocket.clientSessions
quicsocket.close()
quicsocket.connect([options])
quicsocket.destroy([error])
quicsocket.destroyed
quicsocket.duration
quicsocket.endpoints
quicsocket.listen([options])
quicsocket.listenDuration
quicsocket.listening
quicsocket.packetsIgnored
quicsocket.packetsReceived
quicsocket.packetsSent
quicsocket.pending
quicsocket.ref()
quicsocket.serverBusy
quicsocket.serverBusyCount
quicsocket.serverSessions
quicsocket.setDiagnosticPacketLoss(options)
quicsocket.statelessReset
quicsocket.statelessResetCount
quicsocket.unref();
- Event:
- Class:
QuicStream extends stream.Duplex
- Event:
'blocked'
- Event:
'close'
- Event:
'data'
- Event:
'end'
- Event:
'error'
- Event:
'informationalHeaders'
- Event:
'initialHeaders'
- Event:
'trailingHeaders'
- Event:
'readable'
quicstream.bidirectional
quicstream.bytesReceived
quicstream.bytesSent
quicstream.clientInitiated
quicstream.close()
quicstream.dataAckHistogram
quicstream.dataRateHistogram
quicstream.dataSizeHistogram
quicstream.duration
quicstream.finalSize
quicstream.id
quicstream.maxAcknowledgedOffset
quicstream.maxExtendedOffset
quicstream.maxReceivedOffset
quicstream.pushStream(headers[, options])
quicstream.serverInitiated
quicstream.session
quicstream.sendFD(fd[, options])
quicstream.sendFile(path[, options])
quicstream.submitInformationalHeaders(headers)
quicstream.submitInitialHeaders(headers)
quicstream.submitTrailingHeaders(headers)
quicstream.unidirectional
- Event:
- Additional notes
QUIC#
The net
module provides an implementation of the QUIC protocol. To
access it, the Node.js binary must be compiled using the
--experimental-quic
configuration flag.
const { createQuicSocket } = require('net');
Example#
'use strict';
const key = getTLSKeySomehow();
const cert = getTLSCertSomehow();
const { createQuicSocket } = require('net');
// Create the QUIC UDP IPv4 socket bound to local IP port 1234
const socket = createQuicSocket({ endpoint: { port: 1234 } });
socket.on('session', async (session) => {
// A new server side session has been created!
// The peer opened a new stream!
session.on('stream', (stream) => {
// Let's say hello
stream.end('Hello World');
// Let's see what the peer has to say...
stream.setEncoding('utf8');
stream.on('data', console.log);
stream.on('end', () => console.log('stream ended'));
});
const uni = await session.openStream({ halfOpen: true });
uni.write('hi ');
uni.end('from the server!');
});
// Tell the socket to operate as a server using the given
// key and certificate to secure new connections, using
// the fictional 'hello' application protocol.
(async function() {
await socket.listen({ key, cert, alpn: 'hello' });
console.log('The socket is listening for sessions!');
})();
QUIC basics#
QUIC is a UDP-based network transport protocol that includes built-in security via TLS 1.3, flow control, error correction, connection migration, multiplexing, and more.
Within the Node.js implementation of the QUIC protocol, there are three main
components: the QuicSocket
, the QuicSession
and the QuicStream
.
QuicSocket#
A QuicSocket
encapsulates a binding to one or more local UDP ports. It is
used to send data to, and receive data from, remote endpoints. Once created,
a QuicSocket
is associated with a local network address and IP port and can
act as both a QUIC client and server simultaneously. User code at the
JavaScript level interacts with the QuicSocket
object to:
- Query or modified the properties of the local UDP binding;
- Create client
QuicSession
instances; - Wait for server
QuicSession
instances; or - Query activity statistics
Unlike the net.Socket
and tls.TLSSocket
, a QuicSocket
instance cannot be
directly used by user code at the JavaScript level to send or receive data over
the network.
Client and server QuicSessions#
A QuicSession
represents a logical connection between two QUIC endpoints (a
client and a server). In the JavaScript API, each is represented by the
QuicClientSession
and QuicServerSession
specializations.
At any given time, a QuicSession
exists is one of four possible states:
Initial
- Entered as soon as theQuicSession
is created.Handshake
- Entered as soon as the TLS 1.3 handshake between the client and server begins. The handshake is always initiated by the client.Ready
- Entered as soon as the TLS 1.3 handshake completes. Once theQuicSession
enters theReady
state, it may be used to exchange application data usingQuicStream
instances.Closed
- Entere as soon as theQuicSession
connection has been terminated.
New instances of QuicClientSession
are created using the connect()
function on a QuicSocket
as in the example below:
const { createQuicSocket } = require('net');
// Create a QuicSocket associated with localhost and port 1234
const socket = createQuicSocket({ endpoint: { port: 1234 } });
(async function() {
const client = await socket.connect({
address: 'example.com',
port: 4567,
alpn: 'foo'
});
})();
As soon as the QuicClientSession
is created, the address
provided in
the connect options will be resolved to an IP address (if necessary), and
the TLS 1.3 handshake will begin. The QuicClientSession
cannot be used
to exchange application data until after the 'secure'
event has been
emitted by the QuicClientSession
object, signaling the completion of
the TLS 1.3 handshake.
client.on('secure', () => {
// The QuicClientSession can now be used for application data
});
New instances of QuicServerSession
are created internally by the
QuicSocket
if it has been configured to listen for new connections
using the listen()
method.
const { createQuicSocket } = require('net');
const key = getTLSKeySomehow();
const cert = getTLSCertSomehow();
const socket = createQuicSocket();
socket.on('session', (session) => {
session.on('secure', () => {
// The QuicServerSession can now be used for application data
});
});
(async function() {
await socket.listen({ key, cert, alpn: 'foo' });
})();
As with client QuicSession
instances, the QuicServerSession
cannot be
used to exhange application data until the 'secure'
event has been emitted.
QuicSession and ALPN#
QUIC uses the TLS 1.3 ALPN ("Application-Layer Protocol Negotiation")
extension to identify the application level protocol that is using the QUIC
connection. Every QuicSession
instance has an ALPN identifier that must be
specified in either the connect()
or listen()
options. ALPN identifiers that
are known to Node.js (such as the ALPN identifier for HTTP/3) will alter how the
QuicSession
and QuicStream
objects operate internally, but the QUIC
implementation for Node.js has been designed to allow any ALPN to be specified
and used.
QuicStream#
Once a QuicSession
transitions to the Ready
state, QuicStream
instances
may be created and used to exchange application data. On a general level, all
QuicStream
instances are simply Node.js Duplex Streams that allow
bidirectional data flow between the QUIC client and server. However, the
application protocol negotiated for the QuicSession
may alter the semantics
and operation of a QuicStream
associated with the session. Specifically,
some features of the QuicStream
(e.g. headers) are enabled only if the
application protocol selected is known by Node.js to support those features.
Once the QuicSession
is ready, a QuicStream
may be created by either the
client or server, and may be unidirectional or bidirectional.
The openStream()
method is used to create a new QuicStream
:
// Create a new bidirectional stream
async function createStreams(session) {
const stream1 = await session.openStream();
// Create a new unidirectional stream
const stream2 = await session.openStream({ halfOpen: true });
}
As suggested by the names, a bidirectional stream allows data to be sent on a stream in both directions, by both client and server, regardless of which peer opened the stream. A unidirectional stream can be written to only by the QuicSession that opened it.
The 'stream'
event is emitted by the QuicSession
when a new QuicStream
has been initated by the connected peer:
session.on('stream', (stream) => {
if (stream.bidirectional) {
stream.write('Hello World');
stream.end();
}
stream.on('data', console.log);
stream.on('end', () => {});
});
QuicStream headers#
Some QUIC application protocols (like HTTP/3) use headers.
There are four kinds of headers that the Node.js QUIC implementation is capable of handling dependent entirely on known application protocol support:
- Informational Headers
- Initial Headers
- Trailing Headers
- Push Headers
These categories correlate exactly with the equivalent HTTP concepts:
- Informational Headers: Any response headers transmitted within
a block of headers using a
1xx
status code. - Initial Headers: HTTP request or response headers
- Trailing Headers: A block of headers that follow the body of a request or response.
- Push Promise Headers: A block of headers included in a promised push stream.
If headers are supported by the application protocol in use for
a given QuicSession
, the 'initialHeaders'
, 'informationalHeaders'
,
and 'trailingHeaders'
events will be emitted by the QuicStream
object when headers are received; and the submitInformationalHeaders()
,
submitInitialHeaders()
, and submitTrailingHeaders()
methods can be
used to send headers.
QUIC and HTTP/3#
HTTP/3 is an application layer protocol that uses QUIC as the transport.
TBD
QUIC JavaScript API#
net.createQuicSocket([options])
#
options
<Object>client
<Object> A default configuration for QUIC client sessions created usingquicsocket.connect()
.disableStatelessReset
<boolean> Whentrue
theQuicSocket
will not send stateless resets. Default:false
.endpoint
<Object> An object describing the local address to bind to.address
<string> The local address to bind to. This may be an IPv4 or IPv6 address or a host name. If a host name is given, it will be resolved to an IP address.port
<number> The local port to bind to.type
<string> Can be one of'udp4'
,'upd6'
, or'udp6-only'
to use IPv4, IPv6, or IPv6 with dual-stack mode disabled. Default:'udp4'
.
lookup
<Function> A custom DNS lookup function. Default: undefined.maxConnections
<number> The maximum number of total active inbound connections.maxConnectionsPerHost
<number> The maximum number of inbound connections allowed per remote host. Default:100
.maxStatelessResetsPerHost
<number> The maximum number of stateless resets that theQuicSocket
is permitted to send per remote host. Default:10
.qlog
<boolean> Whether to enable 'qlog' for incoming sessions. (For outgoing client sessions, setclient.qlog
.) Default:false
.retryTokenTimeout
<number> The maximum number of seconds for retry token validation. Default:10
seconds.server
<Object> A default configuration for QUIC server sessions.statelessResetSecret
<Buffer> | <Uint8Array> A 16-byteBuffer
orUint8Array
providing the secret to use when generating stateless reset tokens. If not specified, a random secret will be generated for theQuicSocket
. Default:undefined
.validateAddress
<boolean> Whentrue
, theQuicSocket
will use explicit address validation using a QUICRETRY
frame when listening for new server sessions. Default:false
.
The net.createQuicSocket()
function is used to create new QuicSocket
instances associated with a local UDP address.
Class: QuicEndpoint
#
The QuicEndpoint
wraps a local UDP binding used by a QuicSocket
to send
and receive data. A single QuicSocket
may be bound to multiple
QuicEndpoint
instances at any given time.
Users will not create instances of QuicEndpoint
directly.
quicendpoint.addMembership(address, iface)
#
Tells the kernel to join a multicast group at the given multicastAddress
and
multicastInterface
using the IP_ADD_MEMBERSHIP
socket option. If the
multicastInterface
argument is not specified, the operating system will
choose one interface and will add membership to it. To add membership to every
available interface, call addMembership()
multiple times, once per
interface.
quicendpoint.address
#
- Type: Address
An object containing the address information for a bound QuicEndpoint
.
The object will contain the properties:
address
<string> The local IPv4 or IPv6 address to which theQuicEndpoint
is bound.family
<string> Either'IPv4'
or'IPv6'
.port
<number> The local IP port to which theQuicEndpoint
is bound.
If the QuicEndpoint
is not bound, quicendpoint.address
is an empty object.
quicendpoint.bind([options])
#
Binds the QuicEndpoint
if it has not already been bound. User code will
not typically be responsible for binding a QuicEndpoint
as the owning
QuicSocket
will do that automatically.
options
<Object>signal
<AbortSignal> Optionally allows thebind()
to be canceled using anAbortController
.
- Returns: <Promise>
The quicendpoint.bind()
function returns Promise
that will be resolved
with the address once the bind operation is successful.
If the QuicEndpoint
has been destroyed, or is destroyed while the Promise
is pending, the Promise
will be rejected with an ERR_INVALID_STATE
error.
If an AbortSignal
is specified in the options
and it is triggered while
the Promise
is pending, the Promise
will be rejected with an AbortError
.
If quicendpoint.bind()
is called again while a previously returned Promise
is still pending or has already successfully resolved, the previously returned
pending Promise
will be returned. If the additional call to
quicendpoint.bind()
contains an AbortSignal
, the signal
will be ignored.
quicendpoint.bound
#
- Type: <boolean>
Set to true
if the QuicEndpoint
is bound to the local UDP port.
quicendpoint.close()
#
Closes and destroys the QuicEndpoint
. Returns a Promise
that is resolved
once the QuicEndpoint
has been destroyed, or rejects if the QuicEndpoint
is destroyed with an error.
- Returns: <Promise>
The Promise
cannot be canceled. Once quicendpoint.close()
is called, the
QuicEndpoint
will be destroyed.
quicendpoint.closing
#
- Type: <boolean>
Set to true
if the QuicEndpoint
is in the process of closing.
quicendpoint.destroy([error])
#
error
<Object> AnError
object.
Closes and destroys the QuicEndpoint
instance making it usuable.
quicendpoint.destroyed
#
- Type: <boolean>
Set to true
if the QuicEndpoint
has been destroyed.
quicendpoint.dropMembership(address, iface)
#
Instructs the kernel to leave a multicast group at multicastAddress
using the
IP_DROP_MEMBERSHIP
socket option. This method is automatically called by the
kernel when the socket is closed or the process terminates, so most apps will
never have reason to call this.
If multicastInterface
is not specified, the operating system will attempt to
drop membership on all valid interfaces.
quicendpoint.fd
#
- Type: <integer>
The system file descriptor the QuicEndpoint
is bound to. This property
is not set on Windows.
quicendpoint.pending
#
- Type: <boolean>
Set to true
if the QuicEndpoint
is in the process of binding to
the local UDP port.
quicendpoint.ref()
#
quicendpoint.setBroadcast([on])
#
on
<boolean>
Sets or clears the SO_BROADCAST
socket option. When set to true
, UDP
packets may be sent to a local interface's broadcast address.
quicendpoint.setMulticastInterface(iface)
#
iface
<string>
All references to scope in this section are referring to IPv6 Zone Indices,
which are defined by RFC 4007. In string form, an IP with a scope index
is written as 'IP%scope'
where scope is an interface name or interface
number.
Sets the default outgoing multicast interface of the socket to a chosen interface or back to system interface selection. The multicastInterface must be a valid string representation of an IP from the socket's family.
For IPv4 sockets, this should be the IP configured for the desired physical interface. All packets sent to multicast on the socket will be sent on the interface determined by the most recent successful use of this call.
For IPv6 sockets, multicastInterface should include a scope to indicate the interface as in the examples that follow. In IPv6, individual send calls can also use explicit scope in addresses, so only packets sent to a multicast address without specifying an explicit scope are affected by the most recent successful use of this call.
Examples: IPv6 outgoing multicast interface#
On most systems, where scope format uses the interface name:
const { createQuicSocket } = require('net');
const socket = createQuicSocket({ endpoint: { type: 'udp6', port: 1234 } });
socket.on('ready', () => {
socket.endpoints[0].setMulticastInterface('::%eth1');
});
On Windows, where scope format uses an interface number:
const { createQuicSocket } = require('net');
const socket = createQuicSocket({ endpoint: { type: 'udp6', port: 1234 } });
socket.on('ready', () => {
socket.endpoints[0].setMulticastInterface('::%2');
});
Example: IPv4 outgoing multicast interface#
All systems use an IP of the host on the desired physical interface:
const { createQuicSocket } = require('net');
const socket = createQuicSocket({ endpoint: { type: 'udp4', port: 1234 } });
socket.on('ready', () => {
socket.endpoints[0].setMulticastInterface('10.0.0.2');
});
Call results#
A call on a socket that is not ready to send or no longer open may throw a Not running Error.
If multicastInterface can not be parsed into an IP then an EINVAL
System
Error is thrown.
On IPv4, if multicastInterface
is a valid address but does not match any
interface, or if the address does not match the family then a System Error
such as EADDRNOTAVAIL
or EPROTONOSUP
is thrown.
On IPv6, most errors with specifying or omitting scope will result in the socket continuing to use (or returning to) the system's default interface selection.
A socket's address family's ANY address (IPv4 '0.0.0.0'
or IPv6 '::'
)
can be used to return control of the sockets default outgoing interface to
the system for future multicast packets.
quicendpoint.setMulticastLoopback([on])
#
on
<boolean>
Sets or clears the IP_MULTICAST_LOOP
socket option. When set to true
,
multicast packets will also be received on the local interface.
quicendpoint.setMulticastTTL(ttl)
#
ttl
<number>
Sets the IP_MULTICAST_TTL
socket option. While TTL generally stands for
"Time to Live", in this context it specifies the number of IP hops that a
packet is allowed to travel through, specifically for multicast traffic. Each
router or gateway that forwards a packet decrements the TTL. If the TTL is
decremented to 0
by a router, it will not be forwarded.
The argument passed to setMulticastTTL()
is a number of hops between
0
and 255
. The default on most systems is 1
but can vary.
quicendpoint.setTTL(ttl)
#
ttl
<number>
Sets the IP_TTL
socket option. While TTL generally stands for "Time to Live",
in this context it specifies the number of IP hops that a packet is allowed to
travel through. Each router or gateway that forwards a packet decrements the
TTL. If the TTL is decremented to 0
by a router, it will not be forwarded.
Changing TTL values is typically done for network probes or when multicasting.
The argument to setTTL()
is a number of hops between 1
and 255
.
The default on most systems is 64
but can vary.
quicendpoint.unref()
#
Class: QuicSession extends EventEmitter
#
- Extends: <EventEmitter>
The QuicSession
is an abstract base class that defines events, methods, and
properties that are shared by both QuicClientSession
and QuicServerSession
.
Users will not create instances of QuicSession
directly.
Event: 'close'
#
Emitted after the QuicSession
has been destroyed and is no longer usable.
The 'close'
event will not be emitted more than once.
Event: 'error'
#
Emitted immediately before the 'close'
event if the QuicSession
was
destroyed with an error.
The callback will be invoked with a single argument:
error
<Object> AnError
object.
The 'error'
event will not be emitted more than once.
Event: 'keylog'
#
Emitted when key material is generated or received by a QuicSession
(typically during or immediately following the handshake process). This keying
material can be stored for debugging, as it allows captured TLS traffic to be
decrypted. It may be emitted multiple times per QuicSession
instance.
The callback will be invoked with a single argument:
line
<Buffer> Line of ASCII text, in NSS SSLKEYLOGFILE format.
A typical use case is to append received lines to a common text file, which is later used by software (such as Wireshark) to decrypt the traffic:
const log = fs.createWriteStream('/tmp/ssl-keys.log', { flags: 'a' });
// ...
session.on('keylog', (line) => log.write(line));
The 'keylog'
event will be emitted multiple times.
Event: 'pathValidation'
#
Emitted when a path validation result has been determined. This event
is strictly informational. When path validation is successful, the
QuicSession
will automatically update to use the new validated path.
The callback will be invoked with three arguments:
result
<string> Either'failure'
or'success'
, denoting the status of the path challenge.local
<Object> The local address component of the tested path.remote
<Object> The remote address component of the tested path.
The 'pathValidation'
event will be emitted multiple times.
Event: 'secure'
#
Emitted after the TLS handshake has been completed.
The callback will be invoked with two arguments:
servername
<string> The SNI servername requested by the client.alpnProtocol
<string> The negotiated ALPN protocol.cipher
<Object> Information about the selected cipher algorithm.
These will also be available using the quicsession.servername
,
quicsession.alpnProtocol
, and quicsession.cipher
properties.
The 'secure'
event will not be emitted more than once.
Event: 'stream'
#
Emitted when a new QuicStream
has been initiated by the connected peer.
The 'stream'
event may be emitted multiple times.
quicsession.ackDelayRetransmitCount
#
- Type: <number>
The number of retransmissions caused by delayed acknowledgements.
quicsession.address
#
- Type: <Object>
An object containing the local address information for the QuicSocket
to which
the QuicSession
is currently associated.
quicsession.alpnProtocol
#
- Type: <string>
The ALPN protocol identifier negotiated for this session.
quicsession.authenticated
#
- Type: <boolean>
True if the certificate provided by the peer during the TLS 1.3 handshake has been verified.
quicsession.authenticationError
#
- Type: <Object> An error object
If quicsession.authenticated
is false, returns an Error
object
representing the reason the peer certificate verification failed.
quicsession.bidiStreamCount
#
- Type: <number>
The total number of bidirectional streams created for this QuicSession
.
quicsession.blockCount
#
- Type: <number>
The total number of times the QuicSession
has been blocked from sending
stream data due to flow control.
Such blocks indicate that transmitted stream data is not being consumed quickly enough by the connected peer.
quicsession.bytesInFlight
#
- Type: <number>
The total number of unacknowledged bytes this QUIC endpoint has transmitted to the connected peer.
quicsession.bytesReceived
#
- Type: <number>
The total number of bytes received from the peer.
quicsession.bytesSent
#
- Type: <number>
The total number of bytes sent to the peer.
quicsession.cipher
#
- Type: <Object>
Information about the cipher algorithm selected for the session.
quicsession.close()
#
Begins a graceful close of the QuicSession
. Existing QuicStream
instances
will be permitted to close naturally. New QuicStream
instances will not be
permitted. Once all QuicStream
instances have closed, the QuicSession
instance will be destroyed. Returns a Promise
that is resolved once the
QuicSession
instance is destroyed.
quicsession.closeCode
#
- Type: <Object>
quicsession.closing
#
- Type: <boolean>
Set to true
if the QuicSession
is in the process of a graceful shutdown.
quicsession.destroy([error])
#
error
<any>
Destroys the QuicSession
immediately causing the close
event to be emitted.
If error
is not undefined
, the error
event will be emitted immediately
before the close
event.
Any QuicStream
instances that are still opened will be abruptly closed.
quicsession.destroyed
#
- Type: <boolean>
Set to true
if the QuicSession
has been destroyed.
quicsession.duration
#
- Type: <number>
The length of time the QuicSession
was active.
quicsession.getCertificate()
#
- Returns: <Object> A Certificate Object.
Returns an object representing the local certificate. The returned object has some properties corresponding to the fields of the certificate.
If there is no local certificate, or if the QuicSession
has been destroyed,
an empty object will be returned.
quicsession.getPeerCertificate([detailed])
#
detailed
<boolean> Include the full certificate chain iftrue
, otherwise include just the peer's certificate. Default:false
.- Returns: <Object> A Certificate Object.
Returns an object representing the peer's certificate. If the peer does not
provide a certificate, or if the QuicSession
has been destroyed, an empty
object will be returned.
If the full certificate chain was requested (details
equals true
), each
certificate will include an issuerCertificate
property containing an object
representing the issuer's certificate.
quicsession.handshakeAckHistogram
#
TBD
quicsession.handshakeContinuationHistogram
#
TBD
quicsession.handshakeComplete
#
- Type: <boolean>
Set to true
if the TLS handshake has completed.
quicsession.handshakeConfirmed
#
- Type: <boolean>
Set to true
when the TLS handshake completion has been confirmed.
quicsession.handshakeDuration
#
- Type: <number>
The length of time taken to complete the TLS handshake.
quicsession.idleTimeout
#
- Type: <boolean>
Set to true
if the QuicSession
was closed due to an idle timeout.
quicsession.keyUpdateCount
#
- Type: <number>
The number of key update operations that have occured.
quicsession.latestRTT
#
- Type: <number>
The most recently recorded RTT for this QuicSession
.
quicsession.lossRetransmitCount
#
- Type: <number>
The number of lost-packet retransmissions that have been performed on
this QuicSession
.
quicsession.maxDataLeft
#
- Type: <number>
The total number of bytes the QuicSession
is currently allowed to
send to the connected peer.
quicsession.maxInFlightBytes
#
- Type: <number>
The maximum number of in-flight bytes recorded for this QuicSession
.
quicsession.maxStreams
#
- Type: <Object>
The highest cumulative number of bidirectional and unidirectional streams
that can currently be opened. The values are set initially by configuration
parameters when the QuicSession
is created, then updated over the lifespan
of the QuicSession
as the connected peer allows new streams to be created.
quicsession.minRTT
#
- Type: <number>
The minimum RTT recorded so far for this QuicSession
.
quicsession.openStream([options])
#
options
<Object>halfOpen
<boolean> Set totrue
to open a unidirectional stream,false
to open a bidirectional stream. Default:true
.highWaterMark
<number> Total number of bytes that theQuicStream
may buffer internally before thequicstream.write()
function starts returningfalse
. Default:16384
.defaultEncoding
<string> The default encoding that is used when no encoding is specified as an argument toquicstream.write()
. Default:'utf8'
.
- Returns: <Promise> containing <QuicStream>
Returns a Promise
that resolves a new QuicStream
.
The Promise
will be rejected if the QuicSession
has been destroyed, is in
the process of a graceful shutdown, or the QuicSession
is otherwise blocked
from opening a new stream.
quicsession.ping()
#
The ping()
method will trigger the underlying QUIC connection to serialize
any frames currently pending in the outbound queue if it is able to do so.
This has the effect of keeping the connection with the peer active and resets
the idle and retransmission timers. The ping()
method is a best-effort
that ignores any errors that may occur during the serialization and send
operations. There is no return value and there is no way to monitor the status
of the ping()
operation.
quicsession.peerInitiatedStreamCount
#
- Type: <number>
The total number of QuicStreams
initiated by the connected peer.
quicsession.qlog
#
- Type: <stream.Readable>
If qlog
support is enabled for QuicSession
, the quicsession.qlog
property
provides a stream.Readable
that may be used to access the qlog
event
data according to the qlog standard. For client QuicSessions
, the
quicsession.qlog
property will be undefined
untilt the 'qlog'
event
is emitted.
quicsession.remoteAddress
#
- Type: <Object>
An object containing the remote address information for the connected peer.
quicsession.selfInitiatedStreamCount
#
- Type: <number>
The total number of QuicStream
instances initiated by this QuicSession
.
quicsession.servername
#
- Type: <string>
The SNI servername requested for this session by the client.
quicsession.smoothedRTT
#
- Type: <number>
The modified RTT calculated for this QuicSession
.
quicsession.socket
#
- Type: <QuicSocket>
The QuicSocket
the QuicSession
is associated with.
quicsession.statelessReset
#
- Type: <boolean>
True if the QuicSession
was closed due to QUIC stateless reset.
quicsession.uniStreamCount
#
- Type: <number>
The total number of unidirectional streams created on this QuicSession
.
quicsession.updateKey()
#
- Returns: <boolean>
true
if the key update operation is successfully initiated.
Initiates QuicSession key update.
An error will be thrown if called before quicsession.handshakeConfirmed
is equal to true
.
quicsession.usingEarlyData
#
- Type: <boolean>
On server QuicSession
instances, set to true
on completion of the TLS
handshake if early data is enabled. On client QuicSession
instances,
set to true on handshake completion if early data is enabled and was
accepted by the server.
Class: QuicClientSession extends QuicSession
#
- Extends: <QuicSession>
The QuicClientSession
class implements the client side of a QUIC connection.
Instances are created using the quicsocket.connect()
method.
Event: 'sessionTicket'
#
The 'sessionTicket'
event is emitted when a new TLS session ticket has been
generated for the current QuicClientSession
. The callback is invoked with
two arguments:
sessionTicket
<Buffer> The serialized session ticket.remoteTransportParams
<Buffer> The serialized remote transport parameters provided by the QUIC server.
The sessionTicket
and remoteTransportParams
are useful when creating a new
QuicClientSession
to more quickly resume an existing session.
The 'sessionTicket'
event may be emitted multiple times.
Event: 'qlog'
#
The 'qlog'
event is emitted when the QuicClientSession
is ready to begin
providing qlog
event data. The callback is invoked with a single argument:
qlog
<stream.Readable> Astream.Readable
that is also available using thequicsession.qlog
property.
Event: 'usePreferredAddress'
#
The 'usePreferredAddress'
event is emitted when the client QuicSession
is updated to use the server-advertised preferred address. The callback is
invoked with a single address
argument:
address
<Object>
This event is purely informational and will be emitted only when
preferredAddressPolicy
is set to 'accept'
.
The 'usePreferredAddress'
event will not be emitted more than once.
quicclientsession.ephemeralKeyInfo
#
- Type: <Object>
An object representing the type, name, and size of parameter of an ephemeral
key exchange in Perfect Forward Secrecy on a client connection. It is an
empty object when the key exchange is not ephemeral. The supported types are
'DH'
and 'ECDH'
. The name
property is available only when type is
'ECDH'
.
For example: { type: 'ECDH', name: 'prime256v1', size: 256 }
.
quicclientsession.setSocket(socket[, natRebinding])
#
socket
<QuicSocket> AQuicSocket
instance to move this session to.natRebinding
<boolean> Whentrue
, indicates that the local address is to be changed without triggering address validation. This will be rare and will typically be used only to test resiliency in NAT rebind scenarios. Default:false
.- Returns: <Promise>
Migrates the QuicClientSession
to the given QuicSocket
instance. If the new
QuicSocket
has not yet been bound to a local UDP port, it will be bound prior
to attempting the migration.
Class: QuicServerSession extends QuicSession
#
- Extends: <QuicSession>
The QuicServerSession
class implements the server side of a QUIC connection.
Instances are created internally and are emitted using the QuicSocket
'session'
event.
Class: QuicSocket
#
New instances of QuicSocket
are created using the net.createQuicSocket()
method, and can be used as both a client and a server.
Event: 'busy'
#
Emitted when the server busy state has been toggled using
quicSocket.serverBusy = true | false
. The callback is invoked with no
arguments. Use the quicsocket.serverBusy
property to determine the
current status. This event is strictly informational.
const { createQuicSocket } = require('net');
const socket = createQuicSocket();
socket.on('busy', () => {
if (socket.serverBusy)
console.log('Server is busy');
else
console.log('Server is not busy');
});
socket.serverBusy = true;
socket.serverBusy = false;
This 'busy'
event may be emitted multiple times.
Event: 'close'
#
Emitted after the QuicSocket
has been destroyed and is no longer usable.
The 'close'
event will only ever be emitted once.
Event: 'endpointClose'
#
Emitted after a QuicEndpoint
associated with the QuicSocket
closes and
has been destroyed. The handler will be invoked with two arguments:
endpoint
<QuicEndpoint> TheQuicEndpoint
that has been destroyed.error
<Error> AnError
object if theQuicEndpoint
was destroyed because of an error.
When all of the QuicEndpoint
instances associated with a QuicSocket
have
closed, the QuicEndpoint
will also automatically close.
Event: 'error'
#
Emitted before the 'close'
event if the QuicSocket
was destroyed with an
error
.
The 'error'
event will only ever be emitted once.
Event: 'listening'
#
Emitted after quicsocket.listen()
is called and the QuicSocket
has started
listening for incoming QuicServerSession
s. The callback is invoked with
no arguments.
The 'listening'
event will only ever be emitted once.
Event: 'ready'
#
Emitted once the QuicSocket
has been bound to a local UDP port.
The 'ready'
event will only ever be emitted once.
Event: 'session'
#
Emitted when a new QuicServerSession
has been created. The callback is
invoked with a single argument providing the newly created QuicServerSession
object.
const { createQuicSocket } = require('net');
const options = getOptionsSomehow();
const server = createQuicSocket({ server: options });
server.on('session', (session) => {
// Attach session event listeners.
});
server.listen();
The 'session'
event will be emitted multiple times.
The 'session'
event handler can be an async function.
If the 'session'
event handler throws an error, or if it returns a Promise
that is rejected, the error will be handled by destroying the QuicServerSession
automatically and emitting a 'sessionError'
event on the QuicSocket
.
Event: 'sessionError'
#
Emitted when an error occurs processing an event related to a specific
QuicSession
instance. The callback is invoked with two arguments:
error
<Error> The error that was either thrown or rejected.session
<QuicSession> TheQuicSession
instance that was destroyed.
The QuicSession
instance will have been destroyed by the time the
'sessionError'
event is emitted.
const { createQuicSocket } = require('net');
const options = getOptionsSomehow();
const server = createQuicSocket({ server: options });
server.listen();
server.on('session', (session) => {
throw new Error('boom');
});
server.on('sessionError', (error, session) => {
console.log('error:', error.message);
});
quicsocket.addEndpoint(options)
#
options
: <Object> An object describing the local address to bind to.address
<string> The local address to bind to. This may be an IPv4 or IPv6 address or a host name. If a host name is given, it will be resolved to an IP address.port
<number> The local port to bind to.type
<string> Can be one of'udp4'
,'upd6'
, or'udp6-only'
to use IPv4, IPv6, or IPv6 with dual-stack mode disabled. Default:'udp4'
.lookup
<Function> A custom DNS lookup function. Default: undefined.
- Returns: <QuicEndpoint>
Creates and adds a new QuicEndpoint
to the QuicSocket
instance. An
error will be thrown if quicsock.addEndpoint()
is called either after
the QuicSocket
has already started binding to the local ports, or after
the QuicSocket
has been destroyed.
quicsocket.blockList
#
- Type: <net.BlockList>
A <net.BlockList> instance used to define rules for remote IPv4 or IPv6
addresses that this QuicSocket
is not permitted to interact with. The
rules can be specified as either specific individual addresses, ranges
of addresses, or CIDR subnet ranges.
When listening as a server, if a packet is received from a blocked address, the packet will be ignored.
When connecting as a client, if the remote IP address is blocked, the connection attempt will be rejected.
quicsocket.bound
#
- Type: <boolean>
Will be true
if the QuicSocket
has been successfully bound to a local UDP
port. Initially the value is false
.
QuicSocket
instances are not bound to a local UDP port until the first time
eithe quicsocket.listen()
or quicsocket.connect()
is called. The 'ready'
event will be emitted once the QuicSocket
has been bound and the value of
quicsocket.bound
will become true
.
Read-only.
quicsocket.boundDuration
#
- Type: <number>
The length of time this QuicSocket
has been bound to a local port.
Read-only.
quicsocket.bytesReceived
#
- Type: <number>
The number of bytes received by this QuicSocket
.
Read-only.
quicsocket.bytesSent
#
- Type: <number>
The number of bytes sent by this QuicSocket
.
Read-only.
quicsocket.clientSessions
#
- Type: <number>
The number of client QuicSession
instances that have been associated
with this QuicSocket
.
Read-only.
quicsocket.close()
#
- Returns: <Promise>
Gracefully closes the QuicSocket
. Existing QuicSession
instances will be
permitted to close naturally. New QuicClientSession
and QuicServerSession
instances will not be allowed. The returns Promise
will be resolved once
the QuicSocket
is destroyed.
quicsocket.connect([options])
#
options
<Object>address
<string> The domain name or IP address of the QUIC server endpoint.alpn
<string> An ALPN protocol identifier.ca
<string> | <string[]> | <Buffer> | <Buffer[]> Optionally override the trusted CA certificates. Default is to trust the well-known CAs curated by Mozilla. Mozilla's CAs are completely replaced when CAs are explicitly specified using this option. The value can be a string orBuffer
, or anArray
of strings and/orBuffer
s. Any string orBuffer
can contain multiple PEM CAs concatenated together. The peer's certificate must be chainable to a CA trusted by the server for the connection to be authenticated. When using certificates that are not chainable to a well-known CA, the certificate's CA must be explicitly specified as a trusted or the connection will fail to authenticate. If the peer uses a certificate that doesn't match or chain to one of the default CAs, use theca
option to provide a CA certificate that the peer's certificate can match or chain to. For self-signed certificates, the certificate is its own CA, and must be provided. For PEM encoded certificates, supported types are "TRUSTED CERTIFICATE", "X509 CERTIFICATE", and "CERTIFICATE".cert
<string> | <string[]> | <Buffer> | <Buffer[]> Cert chains in PEM format. One cert chain should be provided per private key. Each cert chain should consist of the PEM formatted certificate for a provided privatekey
, followed by the PEM formatted intermediate certificates (if any), in order, and not including the root CA (the root CA must be pre-known to the peer, seeca
). When providing multiple cert chains, they do not have to be in the same order as their private keys inkey
. If the intermediate certificates are not provided, the peer will not be able to validate the certificate, and the handshake will fail.ciphers
<string> Cipher suite specification, replacing the default. For more information, see modifying the default cipher suite. Permitted ciphers can be obtained viatls.getCiphers()
. Cipher names must be uppercased in order for OpenSSL to accept them.clientCertEngine
<string> Name of an OpenSSL engine which can provide the client certificate.crl
<string> | <string[]> | <Buffer> | <Buffer[]> PEM formatted CRLs (Certificate Revocation Lists).defaultEncoding
<string> The default encoding that is used when no encoding is specified as an argument toquicstream.write()
. Default:'utf8'
.dhparam
<string> | <Buffer> Diffie Hellman parameters, required for Perfect Forward Secrecy. Useopenssl dhparam
to create the parameters. The key length must be greater than or equal to 1024 bits, otherwise an error will be thrown. It is strongly recommended to use 2048 bits or larger for stronger security. If omitted or invalid, the parameters are silently discarded and DHE ciphers will not be available.ecdhCurve
<string> A string describing a named curve or a colon separated list of curve NIDs or names, for exampleP-521:P-384:P-256
, to use for ECDH key agreement. Set toauto
to select the curve automatically. Usecrypto.getCurves()
to obtain a list of available curve names. On recent releases,openssl ecparam -list_curves
will also display the name and description of each available elliptic curve. Default:tls.DEFAULT_ECDH_CURVE
.highWaterMark
<number> Total number of bytes that theQuicStream
may buffer internally before thequicstream.write()
function starts returningfalse
. Default:16384
.honorCipherOrder
<boolean> Attempt to use the server's cipher suite preferences instead of the client's. Whentrue
, causesSSL_OP_CIPHER_SERVER_PREFERENCE
to be set insecureOptions
, see OpenSSL Options for more information.idleTimeout
<number>key
<string> | <string[]> | <Buffer> | <Buffer[]> | <Object[]> Private keys in PEM format. PEM allows the option of private keys being encrypted. Encrypted keys will be decrypted withoptions.passphrase
. Multiple keys using different algorithms can be provided either as an array of unencrypted key strings or buffers, or an array of objects in the form{pem: <string|buffer>[, passphrase: <string>]}
. The object form can only occur in an array.object.passphrase
is optional. Encrypted keys will be decrypted withobject.passphrase
if provided, oroptions.passphrase
if it is not.lookup
<Function> A custom DNS lookup function. Default: undefined.activeConnectionIdLimit
<number> Must be a value between2
and8
(inclusive). Default:2
.congestionAlgorithm
<string> Must be either'reno'
or'cubic'
. Default:'reno'
.maxAckDelay
<number>maxData
<number>maxUdpPayloadSize
<number>maxStreamDataBidiLocal
<number>maxStreamDataBidiRemote
<number>maxStreamDataUni
<number>maxStreamsBidi
<number>maxStreamsUni
<number>h3
<Object> HTTP/3 Specific Configuration OptionsocspHandler
<Function> A function for handling OCSP responses.passphrase
<string> Shared passphrase used for a single private key and/or a PFX.pfx
<string> | <string[]> | <Buffer> | <Buffer[]> | <Object[]> PFX or PKCS12 encoded private key and certificate chain.pfx
is an alternative to providingkey
andcert
individually. PFX is usually encrypted, if it is,passphrase
will be used to decrypt it. Multiple PFX can be provided either as an array of unencrypted PFX buffers, or an array of objects in the form{buf: <string|buffer>[, passphrase: <string>]}
. The object form can only occur in an array.object.passphrase
is optional. Encrypted PFX will be decrypted withobject.passphrase
if provided, oroptions.passphrase
if it is not.port
<number> The IP port of the remote QUIC server.preferredAddressPolicy
<string>'accept'
or'reject'
. When'accept'
, indicates that the client will automatically use the preferred address advertised by the server.remoteTransportParams
<Buffer> | <TypedArray> | <DataView> The serialized remote transport parameters from a previously established session. These would have been provided as part of the'sessionTicket'
event on a previousQuicClientSession
object.qlog
<boolean> Whether to enable 'qlog' for this session. Default:false
.secureOptions
<number> Optionally affect the OpenSSL protocol behavior, which is not usually necessary. This should be used carefully if at all! Value is a numeric bitmask of theSSL_OP_*
options from OpenSSL Options.servername
<string> The SNI servername.sessionTicket
: <Buffer> | <TypedArray> | <DataView> The serialized TLS Session Ticket from a previously established session. These would have been provided as part of the'sessionTicket
' event on a previousQuicClientSession
object.type
: <string> Identifies the type of UDP socket. The value must either be'udp4'
, indicating UDP over IPv4, or'udp6'
, indicating UDP over IPv6. Default:'udp4'
.
- Returns: <Promise>
Returns a Promise
that resolves a new QuicClientSession
.
quicsocket.destroy([error])
#
error
<any>
Destroys the QuicSocket
then emits the 'close'
event when done. The 'error'
event will be emitted after 'close'
if the error
is not undefined
.
quicsocket.destroyed
#
- Type: <boolean>
Will be true
if the QuicSocket
has been destroyed.
Read-only.
quicsocket.duration
#
- Type: <number>
The length of time this QuicSocket
has been active,
Read-only.
quicsocket.endpoints
#
- Type: <QuicEndpoint[]>
An array of QuicEndpoint
instances associated with the QuicSocket
.
Read-only.
quicsocket.listen([options])
#
options
<Object>alpn
<string> A required ALPN protocol identifier.ca
<string> | <string[]> | <Buffer> | <Buffer[]> Optionally override the trusted CA certificates. Default is to trust the well-known CAs curated by Mozilla. Mozilla's CAs are completely replaced when CAs are explicitly specified using this option. The value can be a string orBuffer
, or anArray
of strings and/orBuffer
s. Any string orBuffer
can contain multiple PEM CAs concatenated together. The peer's certificate must be chainable to a CA trusted by the server for the connection to be authenticated. When using certificates that are not chainable to a well-known CA, the certificate's CA must be explicitly specified as a trusted or the connection will fail to authenticate. If the peer uses a certificate that doesn't match or chain to one of the default CAs, use theca
option to provide a CA certificate that the peer's certificate can match or chain to. For self-signed certificates, the certificate is its own CA, and must be provided. For PEM encoded certificates, supported types are "TRUSTED CERTIFICATE", "X509 CERTIFICATE", and "CERTIFICATE".cert
<string> | <string[]> | <Buffer> | <Buffer[]> Cert chains in PEM format. One cert chain should be provided per private key. Each cert chain should consist of the PEM formatted certificate for a provided privatekey
, followed by the PEM formatted intermediate certificates (if any), in order, and not including the root CA (the root CA must be pre-known to the peer, seeca
). When providing multiple cert chains, they do not have to be in the same order as their private keys inkey
. If the intermediate certificates are not provided, the peer will not be able to validate the certificate, and the handshake will fail.ciphers
<string> Cipher suite specification, replacing the default. For more information, see modifying the default cipher suite. Permitted ciphers can be obtained viatls.getCiphers()
. Cipher names must be uppercased in order for OpenSSL to accept them.clientCertEngine
<string> Name of an OpenSSL engine which can provide the client certificate.clientHelloHandler
<Function> An async function that may be used to set a <tls.SecureContext> for the given server name at the start of the TLS handshake. See Handling client hello for details.crl
<string> | <string[]> | <Buffer> | <Buffer[]> PEM formatted CRLs (Certificate Revocation Lists).defaultEncoding
<string> The default encoding that is used when no encoding is specified as an argument toquicstream.write()
. Default:'utf8'
.dhparam
<string> | <Buffer> Diffie Hellman parameters, required for Perfect Forward Secrecy. Useopenssl dhparam
to create the parameters. The key length must be greater than or equal to 1024 bits, otherwise an error will be thrown. It is strongly recommended to use 2048 bits or larger for stronger security. If omitted or invalid, the parameters are silently discarded and DHE ciphers will not be available.earlyData
<boolean> Set tofalse
to disable 0RTT early data. Default:true
.ecdhCurve
<string> A string describing a named curve or a colon separated list of curve NIDs or names, for exampleP-521:P-384:P-256
, to use for ECDH key agreement. Set toauto
to select the curve automatically. Usecrypto.getCurves()
to obtain a list of available curve names. On recent releases,openssl ecparam -list_curves
will also display the name and description of each available elliptic curve. Default:tls.DEFAULT_ECDH_CURVE
.highWaterMark
<number> Total number of bytes thatQuicStream
instances may buffer internally before thequicstream.write()
function starts returningfalse
. Default:16384
.honorCipherOrder
<boolean> Attempt to use the server's cipher suite references instead of the client's. Whentrue
, causesSSL_OP_CIPHER_SERVER_PREFERENCE
to be set insecureOptions
, see OpenSSL Options for more information.idleTimeout
<number>key
<string> | <string[]> | <Buffer> | <Buffer[]> | <Object[]> Private keys in PEM format. PEM allows the option of private keys being encrypted. Encrypted keys will be decrypted withoptions.passphrase
. Multiple keys using different algorithms can be provided either as an array of unencrypted key strings or buffers, or an array of objects in the form{pem: <string|buffer>[, passphrase: <string>]}
. The object form can only occur in an array.object.passphrase
is optional. Encrypted keys will be decrypted withobject.passphrase
if provided, oroptions.passphrase
if it is not.lookup
<Function> A custom DNS lookup function. Default: undefined.activeConnectionIdLimit
<number>congestionAlgorithm
<string> Must be either'reno'
or'cubic'
. Default:'reno'
.maxAckDelay
<number>maxData
<number>maxUdpPayloadSize
<number>maxStreamsBidi
<number>maxStreamsUni
<number>maxStreamDataBidiLocal
<number>maxStreamDataBidiRemote
<number>maxStreamDataUni
<number>ocspHandler
<Function> A function for handling OCSP requests.passphrase
<string> Shared passphrase used for a single private key and/or a PFX.pfx
<string> | <string[]> | <Buffer> | <Buffer[]> | <Object[]> PFX or PKCS12 encoded private key and certificate chain.pfx
is an alternative to providingkey
andcert
individually. PFX is usually encrypted, if it is,passphrase
will be used to decrypt it. Multiple PFX can be provided either as an array of unencrypted PFX buffers, or an array of objects in the form{buf: <string|buffer>[, passphrase: <string>]}
. The object form can only occur in an array.object.passphrase
is optional. Encrypted PFX will be decrypted withobject.passphrase
if provided, oroptions.passphrase
if it is not.preferredAddress
<Object>requestCert
<boolean> Request a certificate used to authenticate the client.rejectUnauthorized
<boolean> If notfalse
the server will reject any connection which is not authorized with the list of supplied CAs. This option only has an effect ifrequestCert
istrue
. Default:true
.secureOptions
<number> Optionally affect the OpenSSL protocol behavior, which is not usually necessary. This should be used carefully if at all! Value is a numeric bitmask of theSSL_OP_*
options from OpenSSL Options.sessionIdContext
<string> Opaque identifier used by servers to ensure session state is not shared between applications. Unused by clients.
- Returns: <Promise>
Listen for new peer-initiated sessions. Returns a Promise
that is resolved
once the QuicSocket
is actively listening.
quicsocket.listenDuration
#
- Type: <number>
The length of time this QuicSocket
has been listening for connections.
Read-only
quicsocket.listening
#
- Type: <boolean>
Set to true
if the QuicSocket
is listening for new connections.
Read-only.
quicsocket.packetsIgnored
#
- Type: <number>
The number of packets received by this QuicSocket
that have been ignored.
Read-only.
quicsocket.packetsReceived
#
- Type: <number>
The number of packets successfully received by this QuicSocket
.
Read-only
quicsocket.packetsSent
#
- Type: <number>
The number of packets sent by this QuicSocket
.
Read-only
quicsocket.pending
#
- Type: <boolean>
Set to true
if the socket is not yet bound to the local UDP port.
Read-only.
quicsocket.ref()
#
quicsocket.serverBusy
#
- Type: <boolean> When
true
, theQuicSocket
will reject new connections.
Setting quicsocket.serverBusy
to true
will tell the QuicSocket
to reject all new incoming connection requests using the SERVER_BUSY
QUIC
error code. To begin receiving connections again, disable busy mode by setting
quicsocket.serverBusy = false
.
quicsocket.serverBusyCount
#
- Type: <number>
The number of QuicSession
instances rejected due to server busy status.
Read-only.
quicsocket.serverSessions
#
- Type: <number>
The number of server QuicSession
instances that have been associated with
this QuicSocket
.
Read-only.
quicsocket.setDiagnosticPacketLoss(options)
#
options
<Object>
The quicsocket.setDiagnosticPacketLoss()
method is a diagnostic only tool
that can be used to simulate packet loss conditions for this QuicSocket
by artificially dropping received or transmitted packets.
This method is not to be used in production applications.
quicsocket.statelessReset
#
- Type: <boolean>
true
if stateless reset processing is enabled;false
if disabled.
By default, a listening QuicSocket
will generate stateless reset tokens when
appropriate. The disableStatelessReset
option may be set when the
QuicSocket
is created to disable generation of stateless resets. The
quicsocket.statelessReset
property allows stateless reset to be turned on and
off dynamically through the lifetime of the QuicSocket
.
quicsocket.statelessResetCount
#
- Type: <number>
The number of stateless resets that have been sent.
Read-only.
quicsocket.unref();
#
Class: QuicStream extends stream.Duplex
#
- Extends: <stream.Duplex>
Event: 'blocked'
#
Emitted when the QuicStream
has been prevented from sending queued data for
the QuicStream
due to congestion control.
Event: 'close'
#
Emitted when the QuicStream
has is completely closed and the underlying
resources have been freed.
Event: 'data'
#
Event: 'end'
#
Event: 'error'
#
Event: 'informationalHeaders'
#
Emitted when the QuicStream
has received a block of informational headers.
Support for headers depends entirely on the QUIC Application used as identified
by the alpn
configuration option. In QUIC Applications that support headers,
informational header blocks typically come before initial headers.
The event handler is invoked with a single argument representing the block of Headers as an object.
stream('informationalHeaders', (headers) => {
// Use headers
});
Event: 'initialHeaders'
#
Emitted when the QuicStream
has received a block of initial headers.
Support for headers depends entirely on the QUIC Application used as identified
by the alpn
configuration option. HTTP/3, for instance, supports two kinds of
initial headers: request headers for HTTP request messages and response headers
for HTTP response messages. For HTTP/3 QUIC streams, request and response
headers are each emitted using the 'initialHeaders'
event.
The event handler is invoked with a single argument representing the block of Headers as an object.
stream('initialHeaders', (headers) => {
// Use headers
});
Event: 'trailingHeaders'
#
Emitted when the QuicStream
has received a block of trailing headers.
Support for headers depends entirely on the QUIC Application used as identified
by the alpn
configuration option. Trailing headers typically follow any data
transmitted on the QuicStream
, and therefore typically emit sometime after the
last 'data'
event but before the 'close'
event. The precise timing may
vary from one QUIC application to another.
The event handler is invoked with a single argument representing the block of Headers as an object.
stream('trailingHeaders', (headers) => {
// Use headers
});
Event: 'readable'
#
quicstream.bidirectional
#
- Type: <boolean>
When true
, the QuicStream
is bidirectional. Both the readable and
writable sides of the QuicStream
Duplex
are open.
Read-only.
quicstream.bytesReceived
#
- Type: <number>
The total number of bytes received for this QuicStream
.
Read-only.
quicstream.bytesSent
#
- Type: <number>
The total number of bytes sent by this QuicStream
.
Read-only.
quicstream.clientInitiated
#
- Type: <boolean>
Will be true
if the QuicStream
was initiated by a QuicClientSession
instance.
Read-only.
quicstream.close()
#
- Returns: {Promise`}
Closes the QuicStream
by ending both sides of the QuicStream
Duplex
.
Returns a Promise
that is resolved once the QuicStream
has been destroyed.
quicstream.dataAckHistogram
#
TBD
quicstream.dataRateHistogram
#
TBD
quicstream.dataSizeHistogram
#
TBD
quicstream.duration
#
- Type: <number>
The length of time the QuicStream
has been active.
Read-only.
quicstream.finalSize
#
- Type: <number>
The total number of bytes successfully received by the QuicStream
.
Read-only.
quicstream.id
#
- Type: <number>
The numeric identifier of the QuicStream
.
Read-only.
quicstream.maxAcknowledgedOffset
#
- Type: <number>
The highest acknowledged data offset received for this QuicStream
.
Read-only.
quicstream.maxExtendedOffset
#
- Type: <number>
The maximum extended data offset that has been reported to the connected peer.
Read-only.
quicstream.maxReceivedOffset
#
- Type: <number>
The maximum received offset for this QuicStream
.
Read-only.
quicstream.pushStream(headers[, options])
#
-
headers
<Object> An object representing a block of headers to be transmitted with the push promise. -
options
<Object>highWaterMark
<number> Total number of bytes that theQuicStream
may buffer internally before thequicstream.write()
function starts returningfalse
. Default:16384
.defaultEncoding
<string> The default encoding that is used when no encoding is specified as an argument toquicstream.write()
. Default:'utf8'
.
-
Returns: <QuicStream>
If the selected QUIC application protocol supports push streams, then the
pushStream()
method will initiate a new push promise and create a new
unidirectional QuicStream
object used to fulfill that push.
Currently only HTTP/3 supports the use of pushStream()
.
If the selected QUIC application protocol does not support push streams, an error will be thrown.
quicstream.serverInitiated
#
- Type: <boolean>
Will be true
if the QuicStream
was initiated by a QuicServerSession
instance.
Read-only.
quicstream.session
#
- Type: <QuicSession>
The QuicServerSession
or QuicClientSession
to which the
QuicStream
belongs.
Read-only.
quicstream.sendFD(fd[, options])
#
fd
<number> | <FileHandle> A readable file descriptor.options
<Object>
Instead of using a Quicstream
as a writable stream, send data from a given
file descriptor.
If offset
is set to a non-negative number, reading starts from that position
and the file offset will not be advanced.
If length
is set to a non-negative number, it gives the maximum number of
bytes that are read from the file.
The file descriptor or FileHandle
is not closed when the stream is closed,
so it will need to be closed manually once it is no longer needed.
Using the same file descriptor concurrently for multiple streams
is not supported and may result in data loss. Re-using a file descriptor
after a stream has finished is supported.
quicstream.sendFile(path[, options])
#
path
<string> | <Buffer> | <URL>options
<Object>onError
<Function> Callback function invoked in the case of an error before send.offset
<number> The offset position at which to begin reading. Default:-1
.length
<number> The amount of data from the fd to send. Default:-1
.
Instead of using a QuicStream
as a writable stream, send data from a given
file path.
The options.onError
callback will be called if the file could not be opened.
If offset
is set to a non-negative number, reading starts from that position.
If length
is set to a non-negative number, it gives the maximum number of
bytes that are read from the file.
quicstream.submitInformationalHeaders(headers)
#
headers
<Object>
TBD
quicstream.submitInitialHeaders(headers)
#
headers
<Object>
TBD
quicstream.submitTrailingHeaders(headers)
#
headers
<Object>
TBD
quicstream.unidirectional
#
- Type: <boolean>
Will be true
if the QuicStream
is undirectional. Whether the QuicStream
will be readable or writable depends on whether the quicstream.session
is
a QuicClientSession
or QuicServerSession
, and whether the QuicStream
was initiated locally or remotely.
quicstream.session | quicstream.serverInitiated | Readable | Writable |
---|---|---|---|
QuicClientSession | true | Y | N |
QuicServerSession | true | N | Y |
QuicClientSession | false | N | Y |
QuicServerSession | false | Y | N |
quicstream.session | quicstream.clientInitiated | Readable | Writable |
---|---|---|---|
QuicClientSession | true | N | Y |
QuicServerSession | true | Y | N |
QuicClientSession | false | Y | N |
QuicServerSession | false | N | Y |
Read-only.
Additional notes#
Custom DNS lookup functions#
By default, the QUIC implementation uses the dns
module's
promisified version of lookup()
to resolve domains names
into IP addresses. For most typical use cases, this will be
sufficient. However, it is possible to pass a custom lookup
function as an option in several places throughout the QUIC API:
net.createQuicSocket()
quicsocket.addEndpoint()
quicsocket.connect()
quicsocket.listen()
The custom lookup
function must return a Promise
that is
resolved once the lookup is complete. It will be invoked with
two arguments:
address
<string> | <undefined> The host name to resolve, orundefined
if no host name was provided.family
<number> One of4
or6
, identifying either IPv4 or IPv6.
async function myCustomLookup(address, type) {
// TODO(@jasnell): Make this example more useful
return resolveTheAddressSomehow(address, type);
}
Online Certificate Status Protocol (OCSP)#
The QUIC implementation supports use of OCSP during the TLS 1.3 handshake of a new QUIC session.
Requests#
A QuicServerSession
can receive and process OCSP requests by setting the
ocspHandler
option in the quicsocket.listen()
function. The value of
the ocspHandler
is an async function that must return an object with the
OCSP response and, optionally, a new <tls.SecureContext> to use during the
handshake.
The handler function will be invoked with two arguments:
type
: <string> Will always berequest
forQuicServerSession
.options
: <Object>servername
<string> The SNI server name.context
<tls.SecureContext> TheSecureContext
currently used.
async function ocspServerHandler(type, { servername, context }) {
// Process the request...
return { data: Buffer.from('The OCSP response') };
}
sock.listen({ ocspHandler: ocspServerHandler });
Responses#
A QuicClientSession
can receive and process OCSP responses by setting the
ocspHandler
option in the quicsocket.connect()
function. The value of
the ocspHandler
is an async function with no expected return value.
The handler function will be invoked with two arguments:
type
: <string> Will always beresponse
forQuicClientSession
.options
: <Object>data
: <Buffer> The OCSP response provided by the server
async function ocspClientHandler(type, { data }) {
console.log(data.toString());
}
sock.connect({ ocspHandler: ocspClientHandler });
Handling client hello#
When quicsocket.listen()
is called, a <tls.SecureContext> is created and used
by default for all new QuicServerSession
instances. There are times, however,
when the <tls.SecureContext> to be used for a QuicSession
can only be
determined once the client initiates a connection. This is accomplished using
the clientHelloHandler
option when calling quicsocket.listen()
.
The value of clientHelloHandler
is an async function that is called at the
start of a new QuicServerSession
. It is invoked with three arguments:
alpn
<string> The ALPN protocol identifier specified by the client.servername
<string> The SNI server name specified by the client.ciphers
<string[]> The array of TLS 1.3 ciphers specified by the client.
The clientHelloHandler
can return a new <tls.SecureContext> object that will
be used to continue the TLS handshake. If the function returns undefined
, the
default <tls.SecureContext> will be used. Returning any other value will cause
an error to be thrown that will destroy the QuicServerSession
instance.
const server = createQuicSocket();
server.listen({
async clientHelloHandler(alpn, servername, ciphers) {
console.log(alpn);
console.log(servername);
console.log(ciphers);
}
});