Skip to content

Commit f3d9f56

Browse files
authored
docs: update WebRTC jsdocs (#3005)
Updates config comments and moves constants into the constants file
1 parent 96f79bc commit f3d9f56

File tree

12 files changed

+139
-97
lines changed

12 files changed

+139
-97
lines changed

packages/transport-webrtc/src/constants.ts

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import { encodingLength } from 'uint8-varint'
2+
import { Message } from './private-to-public/pb/message.js'
3+
14
/**
25
* STUN servers help clients discover their own public IPs.
36
*
@@ -13,9 +16,97 @@ export const DEFAULT_ICE_SERVERS = [
1316
'stun:stun.services.mozilla.com:3478'
1417
]
1518

19+
/**
20+
* Characters that can be present in a ufrag
21+
*/
1622
export const UFRAG_ALPHABET = Array.from('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890')
1723

24+
/**
25+
* Used to detect the version of the WebRTC Direct connection protocol in use
26+
*/
1827
export const UFRAG_PREFIX = 'libp2p+webrtc+v1/'
1928

29+
/**
30+
* The multicodec code for webrtc-direct tuples
31+
*/
2032
export const CODEC_WEBRTC_DIRECT = 0x0118
33+
34+
/**
35+
* The multicodec code for certhash tuples
36+
*/
2137
export const CODEC_CERTHASH = 0x01d2
38+
39+
/**
40+
* How much can be buffered to the DataChannel at once
41+
*/
42+
export const MAX_BUFFERED_AMOUNT = 2 * 1024 * 1024
43+
44+
/**
45+
* How long time we wait for the 'bufferedamountlow' event to be emitted
46+
*/
47+
export const BUFFERED_AMOUNT_LOW_TIMEOUT = 30 * 1000
48+
49+
/**
50+
* Max message size that can be sent to the DataChannel. In browsers this is
51+
* 256KiB but go-libp2p and rust-libp2p only support 16KiB at the time of
52+
* writing.
53+
*
54+
* @see https://blog.mozilla.org/webrtc/large-data-channel-messages/
55+
* @see https://issues.webrtc.org/issues/40644524
56+
*/
57+
export const MAX_MESSAGE_SIZE = 16 * 1024
58+
59+
/**
60+
* max protobuf overhead:
61+
*
62+
* ```
63+
* [message-length][flag-field-id+type][flag-field-length][flag-field][message-field-id+type][message-field-length][message-field]
64+
* ```
65+
*/
66+
function calculateProtobufOverhead (maxMessageSize = MAX_MESSAGE_SIZE): number {
67+
// these have a fixed size
68+
const messageLength = encodingLength(maxMessageSize - encodingLength(maxMessageSize))
69+
const flagField = 1 + encodingLength(Object.keys(Message.Flag).length - 1) // id+type/value
70+
const messageFieldIdType = 1 // id+type
71+
const available = maxMessageSize - messageLength - flagField - messageFieldIdType
72+
73+
// let message-length/message-data fill the rest of the message
74+
const messageFieldLengthLength = encodingLength(available)
75+
76+
return messageLength + flagField + messageFieldIdType + messageFieldLengthLength
77+
}
78+
79+
/**
80+
* The protobuf message overhead includes the maximum amount of all bytes in the
81+
* protobuf that aren't message field bytes
82+
*/
83+
export const PROTOBUF_OVERHEAD = calculateProtobufOverhead()
84+
85+
/**
86+
* When closing streams we send a FIN then wait for the remote to
87+
* reply with a FIN_ACK. If that does not happen within this timeout
88+
* we close the stream anyway.
89+
*/
90+
export const FIN_ACK_TIMEOUT = 5_000
91+
92+
/**
93+
* When sending data messages, if the channel is not in the "open" state, wait
94+
* this long for the "open" event to fire.
95+
*/
96+
export const OPEN_TIMEOUT = 5_000
97+
98+
/**
99+
* When closing a stream, we wait for `bufferedAmount` to become 0 before
100+
* closing the underlying RTCDataChannel - this controls how long we wait in ms
101+
*/
102+
export const DATA_CHANNEL_DRAIN_TIMEOUT = 30_1000
103+
104+
/**
105+
* Set as the 'negotiated' muxer protocol name
106+
*/
107+
export const MUXER_PROTOCOL = '/webrtc'
108+
109+
/**
110+
* The protocol used for the signalling stream protocol
111+
*/
112+
export const SIGNALING_PROTOCOL = '/webrtc-signaling/0.0.1'

packages/transport-webrtc/src/index.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -215,17 +215,17 @@ import type { Transport } from '@libp2p/interface'
215215

216216
export interface DataChannelOptions {
217217
/**
218-
* The maximum message size sendable over the channel in bytes
218+
* The maximum message size to be sent over the channel in bytes
219219
*
220-
* @default 16384
220+
* @default 16_384
221221
*/
222222
maxMessageSize?: number
223223

224224
/**
225225
* If the channel's `bufferedAmount` grows over this amount in bytes, wait
226226
* for it to drain before sending more data
227227
*
228-
* @default 16777216
228+
* @default 16_777_216
229229
*/
230230
maxBufferedAmount?: number
231231

@@ -234,7 +234,7 @@ export interface DataChannelOptions {
234234
* the `bufferedAmountLow` event fires - this controls how long we wait for
235235
* that event in ms
236236
*
237-
* @default 30000
237+
* @default 30_000
238238
*/
239239
bufferedAmountLowEventTimeout?: number
240240

@@ -243,7 +243,7 @@ export interface DataChannelOptions {
243243
* closing the underlying RTCDataChannel - this controls how long we wait
244244
* in ms
245245
*
246-
* @default 30000
246+
* @default 30_000
247247
*/
248248
drainTimeout?: number
249249

@@ -252,13 +252,15 @@ export interface DataChannelOptions {
252252
* for a FIN_ACK reply before closing the underlying RTCDataChannel - this
253253
* controls how long we wait for the acknowledgement in ms
254254
*
255-
* @default 5000
255+
* @default 5_000
256256
*/
257257
closeTimeout?: number
258258

259259
/**
260260
* When sending the first data message, if the channel is not in the "open"
261261
* state, wait this long for the "open" event to fire.
262+
*
263+
* @default 5_000
262264
*/
263265
openTimeout?: number
264266
}
@@ -271,6 +273,7 @@ export interface TransportCertificate {
271273
* The private key for the certificate in PEM format
272274
*/
273275
privateKey: string
276+
274277
/**
275278
* PEM format certificate
276279
*/

packages/transport-webrtc/src/muxer.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { MUXER_PROTOCOL } from './constants.js'
12
import { createStream } from './stream.js'
23
import { drainAndClose, nopSink, nopSource } from './util.js'
34
import type { DataChannelOptions } from './index.js'
@@ -7,8 +8,6 @@ import type { AbortOptions } from '@multiformats/multiaddr'
78
import type { Source, Sink } from 'it-stream-types'
89
import type { Uint8ArrayList } from 'uint8arraylist'
910

10-
const PROTOCOL = '/webrtc'
11-
1211
export interface DataChannelMuxerFactoryInit {
1312
/**
1413
* WebRTC Peer Connection
@@ -55,7 +54,7 @@ export class DataChannelMuxerFactory implements StreamMuxerFactory {
5554
this.components = components
5655
this.peerConnection = init.peerConnection
5756
this.metrics = init.metrics
58-
this.protocol = init.protocol ?? PROTOCOL
57+
this.protocol = init.protocol ?? MUXER_PROTOCOL
5958
this.dataChannelOptions = init.dataChannelOptions ?? {}
6059
this.log = components.logger.forComponent('libp2p:webrtc:muxerfactory')
6160

@@ -135,7 +134,7 @@ export class DataChannelMuxer implements StreamMuxer {
135134
this.logger = components.logger
136135
this.streams = init.streams.map(s => s.stream)
137136
this.peerConnection = init.peerConnection
138-
this.protocol = init.protocol ?? PROTOCOL
137+
this.protocol = init.protocol ?? MUXER_PROTOCOL
139138
this.metrics = init.metrics
140139
this.dataChannelOptions = init.dataChannelOptions ?? {}
141140

packages/transport-webrtc/src/private-to-private/initiate-connection.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ import { InvalidParametersError } from '@libp2p/interface'
22
import { peerIdFromString } from '@libp2p/peer-id'
33
import { pbStream } from 'it-protobuf-stream'
44
import { CustomProgressEvent } from 'progress-events'
5+
import { SIGNALING_PROTOCOL } from '../constants.js'
56
import { SDPHandshakeFailedError } from '../error.js'
67
import { DataChannelMuxerFactory } from '../muxer.js'
78
import { RTCPeerConnection, RTCSessionDescription } from '../webrtc/index.js'
89
import { Message } from './pb/message.js'
9-
import { SIGNALING_PROTO_ID, splitAddr, type WebRTCDialEvents, type WebRTCTransportMetrics } from './transport.js'
10+
import { splitAddr, type WebRTCDialEvents, type WebRTCTransportMetrics } from './transport.js'
1011
import { readCandidatesUntilConnected } from './util.js'
1112
import type { DataChannelOptions } from '../index.js'
1213
import type { LoggerOptions, Connection, ComponentLogger, IncomingStreamData } from '@libp2p/interface'
@@ -71,7 +72,7 @@ export async function initiateConnection ({ rtcConfiguration, dataChannel, signa
7172
try {
7273
onProgress?.(new CustomProgressEvent('webrtc:open-signaling-stream'))
7374

74-
const stream = await connection.newStream(SIGNALING_PROTO_ID, {
75+
const stream = await connection.newStream(SIGNALING_PROTOCOL, {
7576
signal,
7677
runOnLimitedConnection: true
7778
})

packages/transport-webrtc/src/private-to-private/transport.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { InvalidParametersError, serviceCapabilities, serviceDependencies, setMa
22
import { peerIdFromString } from '@libp2p/peer-id'
33
import { multiaddr, type Multiaddr } from '@multiformats/multiaddr'
44
import { WebRTC } from '@multiformats/multiaddr-matcher'
5+
import { SIGNALING_PROTOCOL } from '../constants.js'
56
import { WebRTCMultiaddrConnection } from '../maconn.js'
67
import { DataChannelMuxerFactory } from '../muxer.js'
78
import { getRtcConfiguration } from '../util.js'
@@ -14,18 +15,24 @@ import type { OutboundConnectionUpgradeEvents, CreateListenerOptions, DialTransp
1415
import type { Registrar, ConnectionManager, TransportManager } from '@libp2p/interface-internal'
1516
import type { ProgressEvent } from 'progress-events'
1617

17-
const WEBRTC_TRANSPORT = '/webrtc'
18-
const CIRCUIT_RELAY_TRANSPORT = '/p2p-circuit'
19-
export const SIGNALING_PROTO_ID = '/webrtc-signaling/0.0.1'
20-
2118
export interface WebRTCTransportInit {
19+
/**
20+
* Add additional configuration to any RTCPeerConnections that are created.
21+
*
22+
* This could be extra STUN/TURN servers, certificate, etc.
23+
*/
2224
rtcConfiguration?: RTCConfiguration | (() => RTCConfiguration | Promise<RTCConfiguration>)
25+
26+
/**
27+
* Any options here will be applied to any RTCDataChannels that are opened.
28+
*/
2329
dataChannel?: DataChannelOptions
2430

2531
/**
2632
* Inbound connections must complete the upgrade within this many ms
2733
*
28-
* @default 30000
34+
* @default 30_000
35+
* @deprecated configure `connectionManager.inboundUpgradeTimeout` instead
2936
*/
3037
inboundConnectionTimeout?: number
3138
}
@@ -105,7 +112,7 @@ export class WebRTCTransport implements Transport<WebRTCDialEvents>, Startable {
105112
}
106113

107114
async start (): Promise<void> {
108-
await this.components.registrar.handle(SIGNALING_PROTO_ID, (data: IncomingStreamData) => {
115+
await this.components.registrar.handle(SIGNALING_PROTOCOL, (data: IncomingStreamData) => {
109116
// ensure we don't try to upgrade forever
110117
const signal = this.components.upgrader.createInboundAbortSignal(this.shutdownController.signal)
111118

@@ -123,7 +130,7 @@ export class WebRTCTransport implements Transport<WebRTCDialEvents>, Startable {
123130
}
124131

125132
async stop (): Promise<void> {
126-
await this.components.registrar.unhandle(SIGNALING_PROTO_ID)
133+
await this.components.registrar.unhandle(SIGNALING_PROTOCOL)
127134
this._started = false
128135
}
129136

@@ -255,12 +262,12 @@ export class WebRTCTransport implements Transport<WebRTCDialEvents>, Startable {
255262
}
256263

257264
export function splitAddr (ma: Multiaddr): { baseAddr: Multiaddr, peerId: PeerId } {
258-
const addrs = ma.toString().split(WEBRTC_TRANSPORT + '/')
265+
const addrs = ma.toString().split('/webrtc/')
259266
if (addrs.length !== 2) {
260267
throw new InvalidParametersError('webrtc protocol was not present in multiaddr')
261268
}
262269

263-
if (!addrs[0].includes(CIRCUIT_RELAY_TRANSPORT)) {
270+
if (!addrs[0].includes('/p2p-circuit')) {
264271
throw new InvalidParametersError('p2p-circuit protocol was not present in multiaddr')
265272
}
266273

packages/transport-webrtc/src/private-to-public/utils/get-rtcpeerconnection.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { PeerConnection } from '@ipshipyard/node-datachannel'
22
import { RTCPeerConnection } from '@ipshipyard/node-datachannel/polyfill'
33
import { Crypto } from '@peculiar/webcrypto'
4-
import { DEFAULT_ICE_SERVERS } from '../../constants.js'
5-
import { MAX_MESSAGE_SIZE } from '../../stream.js'
4+
import { DEFAULT_ICE_SERVERS, MAX_MESSAGE_SIZE } from '../../constants.js'
65
import { generateTransportCertificate } from './generate-certificates.js'
76
import type { TransportCertificate } from '../../index.js'
87
import type { CertificateFingerprint } from '@ipshipyard/node-datachannel'

packages/transport-webrtc/src/private-to-public/utils/sdp.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,8 @@ import { base64url } from 'multiformats/bases/base64'
44
import { bases, digest } from 'multiformats/basics'
55
import * as Digest from 'multiformats/hashes/digest'
66
import { sha256 } from 'multiformats/hashes/sha2'
7-
import { CODEC_CERTHASH } from '../../constants.js'
7+
import { CODEC_CERTHASH, MAX_MESSAGE_SIZE } from '../../constants.js'
88
import { InvalidFingerprintError, UnsupportedHashAlgorithmError } from '../../error.js'
9-
import { MAX_MESSAGE_SIZE } from '../../stream.js'
109
import type { Multiaddr } from '@multiformats/multiaddr'
1110
import type { MultihashDigest } from 'multiformats/hashes/interface'
1211

packages/transport-webrtc/src/stream.ts

Lines changed: 1 addition & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import pDefer from 'p-defer'
77
import pTimeout from 'p-timeout'
88
import { raceEvent } from 'race-event'
99
import { raceSignal } from 'race-signal'
10-
import { encodingLength } from 'uint8-varint'
1110
import { Uint8ArrayList } from 'uint8arraylist'
11+
import { BUFFERED_AMOUNT_LOW_TIMEOUT, FIN_ACK_TIMEOUT, MAX_BUFFERED_AMOUNT, MAX_MESSAGE_SIZE, OPEN_TIMEOUT, PROTOBUF_OVERHEAD } from './constants.js'
1212
import { Message } from './private-to-public/pb/message.js'
1313
import type { DataChannelOptions } from './index.js'
1414
import type { RTCDataChannel } from './webrtc/index.js'
@@ -27,65 +27,6 @@ export interface WebRTCStreamInit extends AbstractStreamInit, DataChannelOptions
2727
logger: ComponentLogger
2828
}
2929

30-
/**
31-
* How much can be buffered to the DataChannel at once
32-
*/
33-
export const MAX_BUFFERED_AMOUNT = 2 * 1024 * 1024
34-
35-
/**
36-
* How long time we wait for the 'bufferedamountlow' event to be emitted
37-
*/
38-
export const BUFFERED_AMOUNT_LOW_TIMEOUT = 30 * 1000
39-
40-
/**
41-
* Max message size that can be sent to the DataChannel. In browsers this is
42-
* 256KiB but go-libp2p and rust-libp2p only support 16KiB at the time of
43-
* writing.
44-
*
45-
* @see https://blog.mozilla.org/webrtc/large-data-channel-messages/
46-
* @see https://issues.webrtc.org/issues/40644524
47-
*/
48-
export const MAX_MESSAGE_SIZE = 16 * 1024
49-
50-
/**
51-
* max protobuf overhead:
52-
*
53-
* ```
54-
* [message-length][flag-field-id+type][flag-field-length][flag-field][message-field-id+type][message-field-length][message-field]
55-
* ```
56-
*/
57-
function calculateProtobufOverhead (maxMessageSize = MAX_MESSAGE_SIZE): number {
58-
// these have a fixed size
59-
const messageLength = encodingLength(maxMessageSize - encodingLength(maxMessageSize))
60-
const flagField = 1 + encodingLength(Object.keys(Message.Flag).length - 1) // id+type/value
61-
const messageFieldIdType = 1 // id+type
62-
const available = maxMessageSize - messageLength - flagField - messageFieldIdType
63-
64-
// let message-length/message-data fill the rest of the message
65-
const messageFieldLengthLength = encodingLength(available)
66-
67-
return messageLength + flagField + messageFieldIdType + messageFieldLengthLength
68-
}
69-
70-
/**
71-
* The protobuf message overhead includes the maximum amount of all bytes in the
72-
* protobuf that aren't message field bytes
73-
*/
74-
export const PROTOBUF_OVERHEAD = calculateProtobufOverhead()
75-
76-
/**
77-
* When closing streams we send a FIN then wait for the remote to
78-
* reply with a FIN_ACK. If that does not happen within this timeout
79-
* we close the stream anyway.
80-
*/
81-
export const FIN_ACK_TIMEOUT = 5000
82-
83-
/**
84-
* When sending data messages, if the channel is not in the "open" state, wait
85-
* this long for the "open" event to fire.
86-
*/
87-
export const OPEN_TIMEOUT = 5000
88-
8930
export class WebRTCStream extends AbstractStream {
9031
/**
9132
* The data channel used to send and receive data

0 commit comments

Comments
 (0)