@libp2p/webrtc 5.2.2 → 5.2.3-5b084e968
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/index.min.js +4 -4
- package/dist/src/constants.d.ts +6 -0
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +6 -0
- package/dist/src/constants.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/maconn.d.ts +1 -1
- package/dist/src/maconn.js +1 -1
- package/dist/src/muxer.js +1 -1
- package/dist/src/muxer.js.map +1 -1
- package/dist/src/private-to-public/listener.d.ts.map +1 -1
- package/dist/src/private-to-public/listener.js +3 -8
- package/dist/src/private-to-public/listener.js.map +1 -1
- package/dist/src/private-to-public/transport.d.ts +0 -12
- package/dist/src/private-to-public/transport.d.ts.map +1 -1
- package/dist/src/private-to-public/transport.js +1 -17
- package/dist/src/private-to-public/transport.js.map +1 -1
- package/dist/src/private-to-public/utils/connect.js +13 -4
- package/dist/src/private-to-public/utils/connect.js.map +1 -1
- package/dist/src/private-to-public/utils/generate-noise-prologue.js +1 -1
- package/dist/src/private-to-public/utils/generate-noise-prologue.js.map +1 -1
- package/dist/src/private-to-public/utils/sdp.d.ts +1 -1
- package/dist/src/private-to-public/utils/sdp.d.ts.map +1 -1
- package/dist/src/private-to-public/utils/sdp.js +10 -10
- package/dist/src/private-to-public/utils/sdp.js.map +1 -1
- package/dist/src/stream.js +5 -5
- package/dist/src/stream.js.map +1 -1
- package/package.json +8 -8
- package/src/constants.ts +7 -0
- package/src/index.ts +1 -1
- package/src/maconn.ts +1 -1
- package/src/muxer.ts +1 -1
- package/src/private-to-public/listener.ts +3 -9
- package/src/private-to-public/transport.ts +1 -20
- package/src/private-to-public/utils/connect.ts +13 -4
- package/src/private-to-public/utils/generate-noise-prologue.ts +1 -1
- package/src/private-to-public/utils/sdp.ts +10 -10
- package/src/stream.ts +5 -5
- package/dist/typedoc-urls.json +0 -14
package/src/constants.ts
CHANGED
@@ -16,3 +16,10 @@ export const DEFAULT_ICE_SERVERS = [
|
|
16
16
|
export const UFRAG_ALPHABET = Array.from('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890')
|
17
17
|
|
18
18
|
export const UFRAG_PREFIX = 'libp2p+webrtc+v1/'
|
19
|
+
|
20
|
+
/**
|
21
|
+
* The time to wait, in milliseconds, for the data channel handshake to complete
|
22
|
+
*/
|
23
|
+
export const HANDSHAKE_TIMEOUT_MS = 10_000
|
24
|
+
export const CODEC_WEBRTC_DIRECT = 0x0118
|
25
|
+
export const CODEC_CERTHASH = 0x01d2
|
package/src/index.ts
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/**
|
2
2
|
* @packageDocumentation
|
3
3
|
*
|
4
|
-
* A [libp2p transport](https://docs.libp2p.io/concepts/transports/overview/) based on [WebRTC
|
4
|
+
* A [libp2p transport](https://docs.libp2p.io/concepts/transports/overview/) based on [WebRTC data channels](https://webrtc.org/).
|
5
5
|
*
|
6
6
|
* [WebRTC](https://www.w3.org/TR/webrtc/) is a specification that allows real-time communication between nodes - it's commonly used in browser video conferencing applications but it also provides a reliable data transport mechanism called [data channels](https://www.w3.org/TR/webrtc/#peer-to-peer-data-api) which libp2p uses to facilitate [protocol streams](https://docs.libp2p.io/concepts/multiplex/overview/) between peers.
|
7
7
|
*
|
package/src/maconn.ts
CHANGED
package/src/muxer.ts
CHANGED
@@ -59,7 +59,7 @@ export class DataChannelMuxerFactory implements StreamMuxerFactory {
|
|
59
59
|
this.dataChannelOptions = init.dataChannelOptions ?? {}
|
60
60
|
this.log = components.logger.forComponent('libp2p:webrtc:muxerfactory')
|
61
61
|
|
62
|
-
// store any
|
62
|
+
// store any data channels opened before upgrade has been completed
|
63
63
|
this.peerConnection.ondatachannel = ({ channel }) => {
|
64
64
|
this.log.trace('incoming early datachannel with channel id %d and label "%s"', channel.id)
|
65
65
|
|
@@ -6,6 +6,7 @@ import { IP4, WebRTCDirect } from '@multiformats/multiaddr-matcher'
|
|
6
6
|
import { Crypto } from '@peculiar/webcrypto'
|
7
7
|
import getPort from 'get-port'
|
8
8
|
import pWaitFor from 'p-wait-for'
|
9
|
+
import { CODEC_CERTHASH, CODEC_WEBRTC_DIRECT, HANDSHAKE_TIMEOUT_MS } from '../constants.js'
|
9
10
|
import { connect } from './utils/connect.js'
|
10
11
|
import { generateTransportCertificate } from './utils/generate-certificates.js'
|
11
12
|
import { createDialerRTCPeerConnection } from './utils/get-rtcpeerconnection.js'
|
@@ -18,13 +19,6 @@ import type { Multiaddr } from '@multiformats/multiaddr'
|
|
18
19
|
|
19
20
|
const crypto = new Crypto()
|
20
21
|
|
21
|
-
/**
|
22
|
-
* The time to wait, in milliseconds, for the data channel handshake to complete
|
23
|
-
*/
|
24
|
-
const HANDSHAKE_TIMEOUT_MS = 10_000
|
25
|
-
const CODEC_WEBRTC_DIRECT = 0x0118
|
26
|
-
const CODEC_CERTHASH = 0x01d2
|
27
|
-
|
28
22
|
export interface WebRTCDirectListenerComponents {
|
29
23
|
peerId: PeerId
|
30
24
|
privateKey: PrivateKey
|
@@ -99,14 +93,14 @@ export class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> impl
|
|
99
93
|
.pop()?.[1]
|
100
94
|
|
101
95
|
if (host == null) {
|
102
|
-
throw new Error('IP4/6 host must be specified in webrtc-direct
|
96
|
+
throw new Error('IP4/6 host must be specified in webrtc-direct multiaddr')
|
103
97
|
}
|
104
98
|
const port = parseInt(parts
|
105
99
|
.filter(([code, value]) => code === UDP_PROTOCOL.code)
|
106
100
|
.pop()?.[1] ?? '')
|
107
101
|
|
108
102
|
if (isNaN(port)) {
|
109
|
-
throw new Error('UDP port must be specified in webrtc-direct
|
103
|
+
throw new Error('UDP port must be specified in webrtc-direct multiaddr')
|
110
104
|
}
|
111
105
|
|
112
106
|
// have to do this before any async work happens so starting two listeners
|
@@ -1,8 +1,8 @@
|
|
1
1
|
import { serviceCapabilities, transportSymbol } from '@libp2p/interface'
|
2
2
|
import { peerIdFromString } from '@libp2p/peer-id'
|
3
|
-
import { protocols } from '@multiformats/multiaddr'
|
4
3
|
import { WebRTCDirect } from '@multiformats/multiaddr-matcher'
|
5
4
|
import { raceSignal } from 'race-signal'
|
5
|
+
import { HANDSHAKE_TIMEOUT_MS } from '../constants.js'
|
6
6
|
import { genUfrag } from '../util.js'
|
7
7
|
import { WebRTCDirectListener } from './listener.js'
|
8
8
|
import { connect } from './utils/connect.js'
|
@@ -13,25 +13,6 @@ import type { CreateListenerOptions, Transport, Listener, ComponentLogger, Logge
|
|
13
13
|
import type { TransportManager } from '@libp2p/interface-internal'
|
14
14
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
15
15
|
|
16
|
-
/**
|
17
|
-
* The time to wait, in milliseconds, for the data channel handshake to complete
|
18
|
-
*/
|
19
|
-
const HANDSHAKE_TIMEOUT_MS = 10_000
|
20
|
-
|
21
|
-
/**
|
22
|
-
* Created by converting the hexadecimal protocol code to an integer.
|
23
|
-
*
|
24
|
-
* {@link https://github.com/multiformats/multiaddr/blob/master/protocols.csv}
|
25
|
-
*/
|
26
|
-
export const WEBRTC_CODE: number = protocols('webrtc-direct').code
|
27
|
-
|
28
|
-
/**
|
29
|
-
* Created by converting the hexadecimal protocol code to an integer.
|
30
|
-
*
|
31
|
-
* {@link https://github.com/multiformats/multiaddr/blob/master/protocols.csv}
|
32
|
-
*/
|
33
|
-
export const CERTHASH_CODE: number = protocols('certhash').code
|
34
|
-
|
35
16
|
/**
|
36
17
|
* The peer for this transport
|
37
18
|
*/
|
@@ -146,6 +146,7 @@ export async function connect (peerConnection: DirectRTCPeerConnection, ufrag: s
|
|
146
146
|
case 'closed':
|
147
147
|
maConn.close().catch((err) => {
|
148
148
|
options.log.error('error closing connection', err)
|
149
|
+
maConn.abort(err)
|
149
150
|
})
|
150
151
|
break
|
151
152
|
default:
|
@@ -167,18 +168,25 @@ export async function connect (peerConnection: DirectRTCPeerConnection, ufrag: s
|
|
167
168
|
// Therefore, we need to secure an inbound noise connection from the remote.
|
168
169
|
options.log.trace('%s secure inbound', options.role)
|
169
170
|
await connectionEncrypter.secureInbound(wrappedDuplex, {
|
170
|
-
remotePeer: options.remotePeerId
|
171
|
+
remotePeer: options.remotePeerId,
|
172
|
+
signal: options.signal
|
171
173
|
})
|
172
174
|
|
173
175
|
options.log.trace('%s upgrade outbound', options.role)
|
174
|
-
return options.upgrader.upgradeOutbound(maConn, {
|
176
|
+
return options.upgrader.upgradeOutbound(maConn, {
|
177
|
+
skipProtection: true,
|
178
|
+
skipEncryption: true,
|
179
|
+
muxerFactory,
|
180
|
+
signal: options.signal
|
181
|
+
})
|
175
182
|
}
|
176
183
|
|
177
184
|
// For inbound connections, we are expected to start the noise handshake.
|
178
185
|
// Therefore, we need to secure an outbound noise connection from the remote.
|
179
186
|
options.log.trace('%s secure outbound', options.role)
|
180
187
|
const result = await connectionEncrypter.secureOutbound(wrappedDuplex, {
|
181
|
-
remotePeer: options.remotePeerId
|
188
|
+
remotePeer: options.remotePeerId,
|
189
|
+
signal: options.signal
|
182
190
|
})
|
183
191
|
maConn.remoteAddr = maConn.remoteAddr.encapsulate(`/p2p/${result.remotePeer}`)
|
184
192
|
|
@@ -187,6 +195,7 @@ export async function connect (peerConnection: DirectRTCPeerConnection, ufrag: s
|
|
187
195
|
await options.upgrader.upgradeInbound(maConn, {
|
188
196
|
skipProtection: true,
|
189
197
|
skipEncryption: true,
|
190
|
-
muxerFactory
|
198
|
+
muxerFactory,
|
199
|
+
signal: options.signal
|
191
200
|
})
|
192
201
|
}
|
@@ -15,7 +15,7 @@ export function generateNoisePrologue (localFingerprint: string, remoteAddr: Mul
|
|
15
15
|
const localFpString = localFingerprint.trim().toLowerCase().replaceAll(':', '')
|
16
16
|
const localFpArray = uint8arrayFromString(localFpString, 'hex')
|
17
17
|
const local = Digest.create(sha256.code, localFpArray)
|
18
|
-
const remote: Uint8Array = sdp.
|
18
|
+
const remote: Uint8Array = sdp.multibaseDecoder.decode(sdp.certhash(remoteAddr))
|
19
19
|
const byteLength = PREFIX.byteLength + local.bytes.byteLength + remote.byteLength
|
20
20
|
|
21
21
|
if (role === 'server') {
|
@@ -4,9 +4,9 @@ import { base64url } from 'multiformats/bases/base64'
|
|
4
4
|
import { bases, digest } from 'multiformats/basics'
|
5
5
|
import * as Digest from 'multiformats/hashes/digest'
|
6
6
|
import { sha256 } from 'multiformats/hashes/sha2'
|
7
|
+
import { CODEC_CERTHASH } from '../../constants.js'
|
7
8
|
import { InvalidFingerprintError, UnsupportedHashAlgorithmError } from '../../error.js'
|
8
9
|
import { MAX_MESSAGE_SIZE } from '../../stream.js'
|
9
|
-
import { CERTHASH_CODE } from '../transport.js'
|
10
10
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
11
11
|
import type { MultihashDigest } from 'multiformats/hashes/interface'
|
12
12
|
|
@@ -14,7 +14,7 @@ import type { MultihashDigest } from 'multiformats/hashes/interface'
|
|
14
14
|
* Get base2 | identity decoders
|
15
15
|
*/
|
16
16
|
// @ts-expect-error - Not easy to combine these types.
|
17
|
-
export const
|
17
|
+
export const multibaseDecoder: any = Object.values(bases).map(b => b.decoder).reduce((d, b) => d.or(b))
|
18
18
|
|
19
19
|
const fingerprintRegex = /^a=fingerprint:(?:\w+-[0-9]+)\s(?<fingerprint>(:?[0-9a-fA-F]{2})+)$/m
|
20
20
|
export function getFingerprintFromSdp (sdp: string | undefined): string | undefined {
|
@@ -29,7 +29,7 @@ export function getFingerprintFromSdp (sdp: string | undefined): string | undefi
|
|
29
29
|
// Extract the certhash from a multiaddr
|
30
30
|
export function certhash (ma: Multiaddr): string {
|
31
31
|
const tups = ma.stringTuples()
|
32
|
-
const certhash = tups.filter((tup) => tup[0] ===
|
32
|
+
const certhash = tups.filter((tup) => tup[0] === CODEC_CERTHASH).map((tup) => tup[1])[0]
|
33
33
|
|
34
34
|
if (certhash === undefined || certhash === '') {
|
35
35
|
throw new InvalidParametersError(`Couldn't find a certhash component of multiaddr: ${ma.toString()}`)
|
@@ -42,16 +42,16 @@ export function certhash (ma: Multiaddr): string {
|
|
42
42
|
* Convert a certhash into a multihash
|
43
43
|
*/
|
44
44
|
export function decodeCerthash (certhash: string): MultihashDigest {
|
45
|
-
return digest.decode(
|
45
|
+
return digest.decode(multibaseDecoder.decode(certhash))
|
46
46
|
}
|
47
47
|
|
48
48
|
export function certhashToFingerprint (certhash: string): string {
|
49
|
-
const
|
49
|
+
const multibaseDecoded = decodeCerthash(certhash)
|
50
50
|
|
51
|
-
return new Array(
|
51
|
+
return new Array(multibaseDecoded.bytes.length)
|
52
52
|
.fill(0)
|
53
53
|
.map((val, index) => {
|
54
|
-
return
|
54
|
+
return multibaseDecoded.digest[index].toString(16).padStart(2, '0').toUpperCase()
|
55
55
|
})
|
56
56
|
.join(':')
|
57
57
|
}
|
@@ -60,9 +60,9 @@ export function certhashToFingerprint (certhash: string): string {
|
|
60
60
|
* Extract the fingerprint from a multiaddr
|
61
61
|
*/
|
62
62
|
export function ma2Fingerprint (ma: Multiaddr): string {
|
63
|
-
const
|
64
|
-
const prefix = toSupportedHashFunction(
|
65
|
-
const fingerprint =
|
63
|
+
const multihashDecoded = decodeCerthash(certhash(ma))
|
64
|
+
const prefix = toSupportedHashFunction(multihashDecoded.code)
|
65
|
+
const fingerprint = multihashDecoded.digest.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '')
|
66
66
|
const sdp = fingerprint.match(/.{1,2}/g)
|
67
67
|
|
68
68
|
if (sdp == null) {
|
package/src/stream.ts
CHANGED
@@ -305,10 +305,10 @@ export class WebRTCStream extends AbstractStream {
|
|
305
305
|
while (data.byteLength > 0) {
|
306
306
|
const toSend = Math.min(data.byteLength, this.maxMessageSize)
|
307
307
|
const buf = data.subarray(0, toSend)
|
308
|
-
const
|
309
|
-
const
|
308
|
+
const messageBuf = Message.encode({ message: buf })
|
309
|
+
const sendBuf = lengthPrefixed.encode.single(messageBuf)
|
310
310
|
this.log.trace('-> sending message %s', this.channel.readyState)
|
311
|
-
await this._sendMessage(
|
311
|
+
await this._sendMessage(sendBuf)
|
312
312
|
this.log.trace('-> sent message %s', this.channel.readyState)
|
313
313
|
|
314
314
|
data.consume(toSend)
|
@@ -411,8 +411,8 @@ export class WebRTCStream extends AbstractStream {
|
|
411
411
|
}
|
412
412
|
|
413
413
|
this.log.trace('sending flag %s', flag.toString())
|
414
|
-
const
|
415
|
-
const prefixedBuf = lengthPrefixed.encode.single(
|
414
|
+
const messageBuf = Message.encode({ flag })
|
415
|
+
const prefixedBuf = lengthPrefixed.encode.single(messageBuf)
|
416
416
|
|
417
417
|
try {
|
418
418
|
await this._sendMessage(prefixedBuf, false)
|
package/dist/typedoc-urls.json
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"DataChannelOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.DataChannelOptions.html",
|
3
|
-
".:DataChannelOptions": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.DataChannelOptions.html",
|
4
|
-
"TransportCertificate": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.TransportCertificate.html",
|
5
|
-
".:TransportCertificate": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.TransportCertificate.html",
|
6
|
-
"WebRTCDirectTransportComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.WebRTCDirectTransportComponents.html",
|
7
|
-
"WebRTCTransportComponents": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.WebRTCTransportComponents.html",
|
8
|
-
"WebRTCTransportDirectInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.WebRTCTransportDirectInit.html",
|
9
|
-
"WebRTCTransportInit": "https://libp2p.github.io/js-libp2p/interfaces/_libp2p_webrtc.WebRTCTransportInit.html",
|
10
|
-
"webRTC": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTC.html",
|
11
|
-
".:webRTC": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTC.html",
|
12
|
-
"webRTCDirect": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTCDirect.html",
|
13
|
-
".:webRTCDirect": "https://libp2p.github.io/js-libp2p/functions/_libp2p_webrtc.webRTCDirect.html"
|
14
|
-
}
|