diff --git a/doc/api/quic.md b/doc/api/quic.md index 4b286f40b1..ed5df95e76 100644 --- a/doc/api/quic.md +++ b/doc/api/quic.md @@ -17,17 +17,14 @@ const quic = require('quic'); const key = getTLSKeySomehow(); const cert = getTLSCertSomehow(); -const ca = getTLSCAListSomehow(); -// The default export of the quic module is the -// createSocket function. -const createSocket = require('quic'); +const { createSocket } = require('quic'); // Create the local QUIC UDP socket... const socket = createSocket({ type: 'udp4', port: 1234 }); // Tell the socket to operate as a server... -socket.listen({ key, cert, ca }); +socket.listen({ key, cert }); socket.on('session', (session) => { // A new server side session has been created! @@ -62,28 +59,40 @@ socket.on('listening', () => { }); ``` -### quic.createSocket([options]) +## quic.createSocket([options]) * `options` {Object} - * `address` {string} The local address to bind to. - * `ipv6Only` {boolean} - * `lookup` {Function} + * `address` {string} The local address to bind to. This may be an IPv4 or IPv6 + address or a hostname. If a hostname is given, it will be resolved to an IP + address. + * `client` {Object} A default configuration for QUIC client sessions created + using `quicsocket.connect()`. + * `lookup` {Function} A custom DNS lookup function. Default `dns.lookup()`. + * `maxConnectionsPerHost` {number} The maximum number of inbound connections + per remote host. Default: `100`. * `port` {number} The local port to bind to. - * `resuseAddr` {boolean} + * `retryTokenTimeout` {number} The maximum number of seconds for retry token + validation. Defaults: `10`. + * `server` {Object} A default configuration for QUIC server sessions. * `type` {string} Either `'udp4'` or `'upd6'` to use either IPv4 or IPv6, respectively. Creates a new `QuicSocket` instance. -### Class: QuicSession +## Class: QuicSession exends 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 `'close'` event if the `QuicSession` was destroyed with +Emitted before the `'close'` event if the `QuicSession` was destroyed with an error. +### Event: `'extendMaxBidiStreams'` + + +Emitted when the maximum number of bidirectional streams has been extended. + +The callback will be invoked with a single argument: + +* `maxStreams` {number} The new maximum number of bidirectional streams + +### Event: `'extendMaxUniStreams'` + + +Emitted when the maximum number of unidirectional streams has been extended. + +The callback will be invoked with a single argument: + +* `maxStreams` {number} The new maximum number of unidirectional streams + ### Event: `'secure'` +* Type: {object} + * `name` {string} The cipher algorithm name. + * `type` {string} The TLS version (currently always `'TLSv1.3'`). + +Information about the cipher algorithm selected for the session. + +### quicsession.close([code[, callback]]) + + +* `code` {number} The error code to when closing the session. Default: `0`. * `callback` {Function} Callback invoked when the close operation is completed -Closes the `QuicSession`. +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. + +### quicsession.closing + + +* Type: {boolean} + +Set the `true` if the `QuicSession` is in the process of a graceful shutdown. ### quicsession.destroy([error]) +* 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} Defaults to `false` +* `detailed` {boolean} Include the full certificate chain if `true`, otherwise include + just the peer's certificate. +* 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, each certificate will include an `issuerCertificate` +property containing an object representing its issuer's certificate. + +### quicsession.handshakeComplete + + +* Type: {boolean} + +True if the TLS handshake has completed. ### quicsession.openStream([options]) * Extends: {QuicSession} -TBD +The `QuicClientSession` class implements the client side of a QUIC connection. +Instances are created using the `quicsocket.connect()` method. -#### Event: `'sessionTicket'` +### 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 @@ -224,40 +312,96 @@ three arguments: The `sessionTicket` and `remoteTransportParams` are useful when creating a new `QuicClientSession` to more quickly resume an existing session. -#### quicclientsession.ephemeralKeyInfo +### 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.ready -### Class: QuicServerSession +* Type: {boolean} + +True if the `QuicClientSession` is ready for use. False if the `QuicSocket` has not +yet been bound. + +### quicclientsession.readyToMigrate + + +* Type: {boolean} + +Once established, a `QuicClientSession` can be migrated from one `QuicSocket` instance +to another, without requiring the TLS handshake to be reestablished. Migration, however, +can only occur once the TLS handshake is complete and the underlying session has had an +opportunity to generate a pool of extra connection identifiers. + +### quicclientsession.setSocket(socket, callback]) + + +* `socket` {QuicSocket} A `QuicSocket` instance to move this session to. +* `callback` {Function} A callback function that will be invoked once the migration to + the new `QuicSocket` is complete. + +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. If `quicclientsession.readyToMigrate` is `false`, an error will be thrown. + +## Class: QuicServerSession extends QuicSession * Extends: {QuicSession} -TBD +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 +## Class: QuicSocket +New instances of `QuicSocket` are created using the `quic.createSocket()` method. + +Once created, a `QuicSocket` can be configured to work as both a client and a server. + ### Event: `'close'` +Emitted after the `QuicSocket` has been destroyed and is no longer usable. + ### Event: `'error'` +Emitted before the `'close'` event if the `QuicSocket` was destroyed with an `error`. + ### Event: `'ready'` +Emitted once the `QuicSocket` has been bound to a local UDP port. + ### Event: `'session'` * `options` {Object} + * `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 @@ -492,6 +678,7 @@ added: REPLACEME preferences instead of the client's. When `true`, causes `SSL_OP_CIPHER_SERVER_PREFERENCE` to be set in `secureOptions`, 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 with `options.passphrase`. Multiple keys using different @@ -500,6 +687,16 @@ added: REPLACEME passphrase: ]}`. The object form can only occur in an array. `object.passphrase` is optional. Encrypted keys will be decrypted with `object.passphrase` if provided, or `options.passphrase` if it is not. + * `maxAckDelay` {number} + * `maxCidLen` {number} + * `maxData` {number} + * `maxPacketSize` {number} + * `maxStreamsBidi` {number} + * `maxStreamsUni` {number} + * `maxStreamDataBidiLocal` {number} + * `maxStreamDataBidiRemote` {number} + * `maxStreamDataUni` {number} + * `minCidLen` {number} * `passphrase` {string} Shared passphrase used for a single private key and/or a PFX. * `pfx` {string|string[]|Buffer|Buffer[]|Object[]} PFX or PKCS12 encoded @@ -511,6 +708,10 @@ added: REPLACEME occur in an array. `object.passphrase` is optional. Encrypted PFX will be decrypted with `object.passphrase` if provided, or `options.passphrase` if it is not. + * `preferredAddress` {Object} + * `address` {string} + * `port` {number} + * `type` {string} `'udp4'` or `'udp6'`. * `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 the `SSL_OP_*` options from @@ -546,6 +747,9 @@ added: REPLACEME * `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. + ### quicsocket.setMulticastLoopback([on]) +On most systems, where scope format uses the interface name: + +```js +const socket = quic.createSocket({ type: 'udp6', port: 1234 }); + +socket.on('ready', () => { + socket.setMulticastInterface('::%eth1'); +}); +``` + +On Windows, where scope format uses an interface number: + +```js +const socket = quic.createSocket({ type: 'udp6', port: 1234 }); + +socket.on('ready', () => { + socket.setMulticastInterface('::%2'); +}); +``` + +#### Example: IPv4 Outgoing Multicast Interface + +All systems use an IP of the host on the desired physical interface: + +```js +const socket = quic.createSocket({ type: 'udp4', port: 1234 }); + +socket.on('ready', () => { + socket.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. + ### quicsocket.setMulticastTTL(ttl) -### Class: QuicStream +## Class: QuicStream extends stream.Duplex @@ -606,6 +901,24 @@ added: REPLACEME added: REPLACEME --> +### quicstream.bidirectional + + +* Type: {boolean} + +True if the `QuicStream` is bidirectional. + +### quicstream.clientInitiated + + +* Type: {boolean} + +True if the `QuicStream` was initiated by a `QuicClientSession` instance. + ### quicstream.id + +* Type: {boolean} + +True if the `QuicStream` was initiated by a `QuicServerSession` instance. + ### quicstream.session * Type: {QuicSession} + +The `QuicServerSession` or `QuicClientSession`. + +### quicstream.unidirectional + + +* Type: {boolean} + +True if the `QuicStream` is unidirectional. + + + +[RFC 4007]: https://tools.ietf.org/html/rfc4007 +[Certificate Object]: https://nodejs.org/dist/latest-v12.x/docs/api/tls.html#tls_certificate_object