@libp2p/webrtc 5.2.23-cf9aab5c8 → 5.2.24-0f07e3df5
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 +10 -20
- package/dist/index.min.js +18 -18
- package/dist/index.min.js.map +4 -4
- package/dist/src/constants.d.ts +0 -23
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +0 -23
- package/dist/src/constants.js.map +1 -1
- package/dist/src/index.d.ts +12 -22
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +12 -22
- package/dist/src/index.js.map +1 -1
- package/dist/src/muxer.d.ts +14 -46
- package/dist/src/muxer.d.ts.map +1 -1
- package/dist/src/muxer.js +32 -135
- package/dist/src/muxer.js.map +1 -1
- package/dist/src/private-to-private/initiate-connection.d.ts +2 -3
- package/dist/src/private-to-private/initiate-connection.d.ts.map +1 -1
- package/dist/src/private-to-private/initiate-connection.js +23 -5
- package/dist/src/private-to-private/initiate-connection.js.map +1 -1
- package/dist/src/private-to-private/signaling-stream-handler.d.ts +4 -4
- package/dist/src/private-to-private/signaling-stream-handler.d.ts.map +1 -1
- package/dist/src/private-to-private/signaling-stream-handler.js +10 -6
- package/dist/src/private-to-private/signaling-stream-handler.js.map +1 -1
- package/dist/src/private-to-private/transport.d.ts +2 -2
- package/dist/src/private-to-private/transport.d.ts.map +1 -1
- package/dist/src/private-to-private/transport.js +30 -15
- package/dist/src/private-to-private/transport.js.map +1 -1
- package/dist/src/private-to-private/util.d.ts +3 -1
- package/dist/src/private-to-private/util.d.ts.map +1 -1
- package/dist/src/private-to-private/util.js +15 -3
- package/dist/src/private-to-private/util.js.map +1 -1
- package/dist/src/private-to-public/listener.d.ts.map +1 -1
- package/dist/src/private-to-public/listener.js +21 -15
- package/dist/src/private-to-public/listener.js.map +1 -1
- package/dist/src/private-to-public/transport.d.ts.map +1 -1
- package/dist/src/private-to-public/transport.js +3 -2
- package/dist/src/private-to-public/transport.js.map +1 -1
- package/dist/src/private-to-public/utils/connect.d.ts +1 -1
- package/dist/src/private-to-public/utils/connect.d.ts.map +1 -1
- package/dist/src/private-to-public/utils/connect.js +17 -14
- package/dist/src/private-to-public/utils/connect.js.map +1 -1
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.d.ts +4 -4
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.d.ts.map +1 -1
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.js +13 -2
- package/dist/src/private-to-public/utils/get-rtcpeerconnection.js.map +1 -1
- package/dist/src/private-to-public/utils/sdp.d.ts.map +1 -1
- package/dist/src/private-to-public/utils/sdp.js +25 -13
- package/dist/src/private-to-public/utils/sdp.js.map +1 -1
- package/dist/src/private-to-public/utils/stun-listener.js +1 -1
- package/dist/src/private-to-public/utils/stun-listener.js.map +1 -1
- package/dist/src/rtcpeerconnection-to-conn.d.ts +12 -0
- package/dist/src/rtcpeerconnection-to-conn.d.ts.map +1 -0
- package/dist/src/rtcpeerconnection-to-conn.js +43 -0
- package/dist/src/rtcpeerconnection-to-conn.js.map +1 -0
- package/dist/src/stream.d.ts +13 -26
- package/dist/src/stream.d.ts.map +1 -1
- package/dist/src/stream.js +64 -166
- package/dist/src/stream.js.map +1 -1
- package/dist/src/util.d.ts +3 -1
- package/dist/src/util.d.ts.map +1 -1
- package/dist/src/util.js +19 -0
- package/dist/src/util.js.map +1 -1
- package/dist/src/webrtc/index.d.ts +1 -1
- package/dist/src/webrtc/index.d.ts.map +1 -1
- package/dist/src/webrtc/index.js +1 -1
- package/dist/src/webrtc/index.js.map +1 -1
- package/package.json +26 -29
- package/src/constants.ts +0 -28
- package/src/index.ts +12 -22
- package/src/muxer.ts +43 -166
- package/src/private-to-private/initiate-connection.ts +30 -8
- package/src/private-to-private/signaling-stream-handler.ts +12 -9
- package/src/private-to-private/transport.ts +33 -17
- package/src/private-to-private/util.ts +21 -4
- package/src/private-to-public/listener.ts +22 -15
- package/src/private-to-public/transport.ts +3 -2
- package/src/private-to-public/utils/connect.ts +18 -15
- package/src/private-to-public/utils/get-rtcpeerconnection.ts +16 -4
- package/src/private-to-public/utils/sdp.ts +29 -13
- package/src/private-to-public/utils/stun-listener.ts +1 -1
- package/src/rtcpeerconnection-to-conn.ts +62 -0
- package/src/stream.ts +74 -194
- package/src/util.ts +22 -1
- package/src/webrtc/index.ts +1 -1
- package/dist/src/maconn.d.ts +0 -58
- package/dist/src/maconn.d.ts.map +0 -1
- package/dist/src/maconn.js +0 -56
- package/dist/src/maconn.js.map +0 -1
- package/src/maconn.ts +0 -101
@@ -1,12 +1,11 @@
|
|
1
1
|
import { isIPv4 } from '@chainsafe/is-ip'
|
2
2
|
import { InvalidParametersError } from '@libp2p/interface'
|
3
|
-
import { getThinWaistAddresses } from '@libp2p/utils
|
4
|
-
import {
|
3
|
+
import { getNetConfig, getThinWaistAddresses } from '@libp2p/utils'
|
4
|
+
import { CODE_CERTHASH, CODE_WEBRTC_DIRECT, multiaddr } from '@multiformats/multiaddr'
|
5
5
|
import { WebRTCDirect } from '@multiformats/multiaddr-matcher'
|
6
6
|
import getPort from 'get-port'
|
7
7
|
import { TypedEventEmitter, setMaxListeners } from 'main-event'
|
8
8
|
import pWaitFor from 'p-wait-for'
|
9
|
-
import { CODEC_CERTHASH, CODEC_WEBRTC_DIRECT } from '../constants.js'
|
10
9
|
import { connect } from './utils/connect.js'
|
11
10
|
import { createDialerRTCPeerConnection } from './utils/get-rtcpeerconnection.js'
|
12
11
|
import { stunListener } from './utils/stun-listener.js'
|
@@ -94,7 +93,11 @@ export class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> impl
|
|
94
93
|
}
|
95
94
|
|
96
95
|
async listen (ma: Multiaddr): Promise<void> {
|
97
|
-
const { host, port,
|
96
|
+
const { host, port, type, protocol } = getNetConfig(ma)
|
97
|
+
|
98
|
+
if (port == null || protocol !== 'udp' || (type !== 'ip4' && type !== 'ip6')) {
|
99
|
+
throw new InvalidParametersError(`Multiaddr ${ma} was not an IPv4 or IPv6 address or was missing a UDP port`)
|
100
|
+
}
|
98
101
|
|
99
102
|
let udpMuxServer: UDPMuxServer | undefined
|
100
103
|
|
@@ -106,7 +109,7 @@ export class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> impl
|
|
106
109
|
udpMuxServer = UDP_MUX_LISTENERS.find(s => s.port === port)
|
107
110
|
|
108
111
|
// make sure the port is free for the given family
|
109
|
-
if (udpMuxServer != null && ((udpMuxServer.isIPv4 &&
|
112
|
+
if (udpMuxServer != null && ((udpMuxServer.isIPv4 && type === 'ip4') || (udpMuxServer.isIPv6 && type === 'ip6'))) {
|
110
113
|
throw new InvalidParametersError(`There is already a listener for ${host}:${port}`)
|
111
114
|
}
|
112
115
|
|
@@ -119,13 +122,13 @@ export class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> impl
|
|
119
122
|
// start the mux server if we don't have one already
|
120
123
|
if (udpMuxServer == null) {
|
121
124
|
this.log('starting UDP mux server on %s:%p', host, port)
|
122
|
-
udpMuxServer = this.startUDPMuxServer(host, port,
|
125
|
+
udpMuxServer = this.startUDPMuxServer(host, port, type === 'ip4' ? 4 : 6)
|
123
126
|
UDP_MUX_LISTENERS.push(udpMuxServer)
|
124
127
|
}
|
125
128
|
|
126
|
-
if (
|
129
|
+
if (type === 'ip4') {
|
127
130
|
udpMuxServer.isIPv4 = true
|
128
|
-
} else if (
|
131
|
+
} else if (type === 'ip6') {
|
129
132
|
udpMuxServer.isIPv6 = true
|
130
133
|
}
|
131
134
|
|
@@ -205,7 +208,7 @@ export class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> impl
|
|
205
208
|
metrics: this.components.metrics,
|
206
209
|
events: this.metrics?.listenerEvents,
|
207
210
|
signal,
|
208
|
-
remoteAddr: multiaddr(`/ip${isIPv4(remoteHost) ? 4 : 6}/${remoteHost}/udp/${remotePort}`),
|
211
|
+
remoteAddr: multiaddr(`/ip${isIPv4(remoteHost) ? 4 : 6}/${remoteHost}/udp/${remotePort}/webrtc-direct`),
|
209
212
|
dataChannel: this.init.dataChannel,
|
210
213
|
upgrader: this.init.upgrader,
|
211
214
|
peerId: this.components.peerId,
|
@@ -238,19 +241,23 @@ export class WebRTCDirectListener extends TypedEventEmitter<ListenerEvents> impl
|
|
238
241
|
}
|
239
242
|
|
240
243
|
// add the certhash if it is missing
|
241
|
-
const
|
244
|
+
const components = ma.getComponents()
|
242
245
|
|
243
|
-
for (let j = 0; j <
|
244
|
-
if (
|
246
|
+
for (let j = 0; j < components.length; j++) {
|
247
|
+
if (components[j].code !== CODE_WEBRTC_DIRECT) {
|
245
248
|
continue
|
246
249
|
}
|
247
250
|
|
248
251
|
const certhashIndex = j + 1
|
249
252
|
|
250
|
-
if (
|
251
|
-
|
253
|
+
if (components[certhashIndex] == null || components[certhashIndex].code !== CODE_CERTHASH) {
|
254
|
+
components.splice(certhashIndex, 0, {
|
255
|
+
code: CODE_CERTHASH,
|
256
|
+
name: 'certhash',
|
257
|
+
value: this.certificate?.certhash
|
258
|
+
})
|
252
259
|
|
253
|
-
ma =
|
260
|
+
ma = multiaddr(components)
|
254
261
|
multiaddrs[i] = ma
|
255
262
|
}
|
256
263
|
}
|
@@ -1,6 +1,7 @@
|
|
1
1
|
import { generateKeyPair, privateKeyToCryptoKeyPair } from '@libp2p/crypto/keys'
|
2
2
|
import { InvalidParametersError, NotFoundError, NotStartedError, serviceCapabilities, transportSymbol } from '@libp2p/interface'
|
3
3
|
import { peerIdFromString } from '@libp2p/peer-id'
|
4
|
+
import { CODE_P2P } from '@multiformats/multiaddr'
|
4
5
|
import { WebRTCDirect } from '@multiformats/multiaddr-matcher'
|
5
6
|
import { BasicConstraintsExtension, X509Certificate, X509CertificateGenerator } from '@peculiar/x509'
|
6
7
|
import { Key } from 'interface-datastore'
|
@@ -164,7 +165,7 @@ export class WebRTCDirectTransport implements Transport, Startable {
|
|
164
165
|
options.signal.throwIfAborted()
|
165
166
|
|
166
167
|
let theirPeerId: PeerId | undefined
|
167
|
-
const remotePeerString = ma.
|
168
|
+
const remotePeerString = ma.getComponents().findLast(c => c.code === CODE_P2P)?.value
|
168
169
|
if (remotePeerString != null) {
|
169
170
|
theirPeerId = peerIdFromString(remotePeerString)
|
170
171
|
}
|
@@ -186,7 +187,7 @@ export class WebRTCDirectTransport implements Transport, Startable {
|
|
186
187
|
dataChannel: this.init.dataChannel,
|
187
188
|
upgrader: options.upgrader,
|
188
189
|
peerId: this.components.peerId,
|
189
|
-
|
190
|
+
remotePeer: theirPeerId,
|
190
191
|
privateKey: this.components.privateKey
|
191
192
|
})
|
192
193
|
} catch (err) {
|
@@ -1,8 +1,8 @@
|
|
1
|
-
import { noise } from '@
|
2
|
-
import {
|
1
|
+
import { noise } from '@libp2p/noise'
|
2
|
+
import { pEvent } from 'p-event'
|
3
3
|
import { WebRTCTransportError } from '../../error.js'
|
4
|
-
import { WebRTCMultiaddrConnection } from '../../maconn.js'
|
5
4
|
import { DataChannelMuxerFactory } from '../../muxer.js'
|
5
|
+
import { toMultiaddrConnection } from '../../rtcpeerconnection-to-conn.ts'
|
6
6
|
import { createStream } from '../../stream.js'
|
7
7
|
import { isFirefox } from '../../util.js'
|
8
8
|
import { generateNoisePrologue } from './generate-noise-prologue.js'
|
@@ -22,7 +22,7 @@ export interface ConnectOptions {
|
|
22
22
|
dataChannel?: DataChannelOptions
|
23
23
|
upgrader: Upgrader
|
24
24
|
peerId: PeerId
|
25
|
-
|
25
|
+
remotePeer?: PeerId
|
26
26
|
signal: AbortSignal
|
27
27
|
privateKey: PrivateKey
|
28
28
|
}
|
@@ -83,7 +83,7 @@ export async function connect (peerConnection: DirectRTCPeerConnection, ufrag: s
|
|
83
83
|
|
84
84
|
if (handshakeDataChannel.readyState !== 'open') {
|
85
85
|
options.log.trace('%s wait for handshake channel to open, starting status %s', options.role, handshakeDataChannel.readyState)
|
86
|
-
await
|
86
|
+
await pEvent(handshakeDataChannel, 'open', options)
|
87
87
|
}
|
88
88
|
|
89
89
|
options.log.trace('%s handshake channel opened', options.role)
|
@@ -116,20 +116,19 @@ export async function connect (peerConnection: DirectRTCPeerConnection, ufrag: s
|
|
116
116
|
const handshakeStream = createStream({
|
117
117
|
channel: handshakeDataChannel,
|
118
118
|
direction: 'outbound',
|
119
|
-
|
119
|
+
isHandshake: true,
|
120
120
|
log: options.log,
|
121
121
|
...(options.dataChannel ?? {})
|
122
122
|
})
|
123
123
|
|
124
124
|
// Creating the connection before completion of the noise
|
125
125
|
// handshake ensures that the stream opening callback is set up
|
126
|
-
const maConn =
|
126
|
+
const maConn = toMultiaddrConnection({
|
127
127
|
peerConnection,
|
128
128
|
remoteAddr: options.remoteAddr,
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
metrics: options.events
|
129
|
+
metrics: options.events,
|
130
|
+
direction: options.role === 'client' ? 'outbound' : 'inbound',
|
131
|
+
log: options.logger.forComponent('libp2p:webrtc-direct:connection')
|
133
132
|
})
|
134
133
|
|
135
134
|
peerConnection.addEventListener(CONNECTION_STATE_CHANGE_EVENT, () => {
|
@@ -150,7 +149,8 @@ export async function connect (peerConnection: DirectRTCPeerConnection, ufrag: s
|
|
150
149
|
// Track opened peer connection
|
151
150
|
options.events?.increment({ peer_connection: true })
|
152
151
|
|
153
|
-
const muxerFactory = new DataChannelMuxerFactory(
|
152
|
+
const muxerFactory = new DataChannelMuxerFactory({
|
153
|
+
// @ts-expect-error https://github.com/murat-dogan/node-datachannel/pull/370
|
154
154
|
peerConnection,
|
155
155
|
metrics: options.events,
|
156
156
|
dataChannelOptions: options.dataChannel
|
@@ -161,8 +161,8 @@ export async function connect (peerConnection: DirectRTCPeerConnection, ufrag: s
|
|
161
161
|
// handshake. Therefore, we need to secure an inbound noise connection
|
162
162
|
// from the server.
|
163
163
|
options.log.trace('%s secure inbound', options.role)
|
164
|
-
await connectionEncrypter.secureInbound(handshakeStream, {
|
165
|
-
remotePeer: options.
|
164
|
+
const result = await connectionEncrypter.secureInbound(handshakeStream, {
|
165
|
+
remotePeer: options.remotePeer,
|
166
166
|
signal: options.signal,
|
167
167
|
skipStreamMuxerNegotiation: true
|
168
168
|
})
|
@@ -171,6 +171,7 @@ export async function connect (peerConnection: DirectRTCPeerConnection, ufrag: s
|
|
171
171
|
return await options.upgrader.upgradeOutbound(maConn, {
|
172
172
|
skipProtection: true,
|
173
173
|
skipEncryption: true,
|
174
|
+
remotePeer: result.remotePeer,
|
174
175
|
muxerFactory,
|
175
176
|
signal: options.signal
|
176
177
|
})
|
@@ -181,7 +182,7 @@ export async function connect (peerConnection: DirectRTCPeerConnection, ufrag: s
|
|
181
182
|
// the client.
|
182
183
|
options.log.trace('%s secure outbound', options.role)
|
183
184
|
const result = await connectionEncrypter.secureOutbound(handshakeStream, {
|
184
|
-
remotePeer: options.
|
185
|
+
remotePeer: options.remotePeer,
|
185
186
|
signal: options.signal,
|
186
187
|
skipStreamMuxerNegotiation: true
|
187
188
|
})
|
@@ -193,11 +194,13 @@ export async function connect (peerConnection: DirectRTCPeerConnection, ufrag: s
|
|
193
194
|
await options.upgrader.upgradeInbound(maConn, {
|
194
195
|
skipProtection: true,
|
195
196
|
skipEncryption: true,
|
197
|
+
remotePeer: result.remotePeer,
|
196
198
|
muxerFactory,
|
197
199
|
signal: options.signal
|
198
200
|
})
|
199
201
|
} catch (err) {
|
200
202
|
handshakeDataChannel.close()
|
203
|
+
peerConnection.close()
|
201
204
|
|
202
205
|
throw err
|
203
206
|
}
|
@@ -1,10 +1,10 @@
|
|
1
|
-
import { PeerConnection } from '@ipshipyard/node-datachannel'
|
2
|
-
import { RTCPeerConnection } from '@ipshipyard/node-datachannel/polyfill'
|
3
1
|
import { Crypto } from '@peculiar/webcrypto'
|
2
|
+
import { PeerConnection } from 'node-datachannel'
|
3
|
+
import { RTCPeerConnection } from 'node-datachannel/polyfill'
|
4
4
|
import { DEFAULT_ICE_SERVERS, MAX_MESSAGE_SIZE } from '../../constants.js'
|
5
5
|
import { generateTransportCertificate } from './generate-certificates.js'
|
6
6
|
import type { TransportCertificate } from '../../index.js'
|
7
|
-
import type { CertificateFingerprint } from '
|
7
|
+
import type { CertificateFingerprint } from 'node-datachannel'
|
8
8
|
|
9
9
|
const crypto = new Crypto()
|
10
10
|
|
@@ -14,7 +14,7 @@ interface DirectRTCPeerConnectionInit extends RTCConfiguration {
|
|
14
14
|
}
|
15
15
|
|
16
16
|
export class DirectRTCPeerConnection extends RTCPeerConnection {
|
17
|
-
private
|
17
|
+
private peerConnection: PeerConnection
|
18
18
|
private readonly ufrag: string
|
19
19
|
|
20
20
|
constructor (init: DirectRTCPeerConnectionInit) {
|
@@ -22,6 +22,18 @@ export class DirectRTCPeerConnection extends RTCPeerConnection {
|
|
22
22
|
|
23
23
|
this.peerConnection = init.peerConnection
|
24
24
|
this.ufrag = init.ufrag
|
25
|
+
|
26
|
+
// make sure C++ peer connection is garbage collected
|
27
|
+
// https://github.com/murat-dogan/node-datachannel/issues/366#issuecomment-3228453155
|
28
|
+
this.addEventListener('connectionstatechange', () => {
|
29
|
+
switch (this.connectionState) {
|
30
|
+
case 'closed':
|
31
|
+
this.peerConnection.close()
|
32
|
+
break
|
33
|
+
default:
|
34
|
+
break
|
35
|
+
}
|
36
|
+
})
|
25
37
|
}
|
26
38
|
|
27
39
|
async createOffer (): Promise<globalThis.RTCSessionDescriptionInit | any> {
|
@@ -1,10 +1,11 @@
|
|
1
1
|
import { InvalidParametersError } from '@libp2p/interface'
|
2
|
-
import {
|
2
|
+
import { getNetConfig } from '@libp2p/utils'
|
3
|
+
import { CODE_CERTHASH, multiaddr } from '@multiformats/multiaddr'
|
3
4
|
import { base64url } from 'multiformats/bases/base64'
|
4
5
|
import { bases, digest } from 'multiformats/basics'
|
5
6
|
import * as Digest from 'multiformats/hashes/digest'
|
6
7
|
import { sha256 } from 'multiformats/hashes/sha2'
|
7
|
-
import {
|
8
|
+
import { MAX_MESSAGE_SIZE } from '../../constants.js'
|
8
9
|
import { InvalidFingerprintError, UnsupportedHashAlgorithmError } from '../../error.js'
|
9
10
|
import type { Multiaddr } from '@multiformats/multiaddr'
|
10
11
|
import type { MultihashDigest } from 'multiformats/hashes/interface'
|
@@ -27,8 +28,8 @@ export function getFingerprintFromSdp (sdp: string | undefined): string | undefi
|
|
27
28
|
|
28
29
|
// Extract the certhash from a multiaddr
|
29
30
|
export function certhash (ma: Multiaddr): string {
|
30
|
-
const
|
31
|
-
const certhash =
|
31
|
+
const components = ma.getComponents()
|
32
|
+
const certhash = components.find(c => c.code === CODE_CERTHASH)?.value
|
32
33
|
|
33
34
|
if (certhash === undefined || certhash === '') {
|
34
35
|
throw new InvalidParametersError(`Couldn't find a certhash component of multiaddr: ${ma.toString()}`)
|
@@ -100,15 +101,20 @@ export function toSupportedHashFunction (code: number): 'sha-1' | 'sha-256' | 's
|
|
100
101
|
* ice-lite mode and DTLS active mode.
|
101
102
|
*/
|
102
103
|
export function serverAnswerFromMultiaddr (ma: Multiaddr, ufrag: string): RTCSessionDescriptionInit {
|
103
|
-
const { host, port,
|
104
|
+
const { host, port, type } = getNetConfig(ma)
|
105
|
+
|
106
|
+
if (type !== 'ip4' && type !== 'ip6') {
|
107
|
+
throw new InvalidParametersError(`Multiaddr ${ma} was not an IPv4 or IPv6 address`)
|
108
|
+
}
|
109
|
+
|
104
110
|
const fingerprint = ma2Fingerprint(ma)
|
105
111
|
const sdp = `v=0
|
106
|
-
o=- 0 0 IN IP${
|
112
|
+
o=- 0 0 IN IP${type === 'ip4' ? 4 : 6} ${host}
|
107
113
|
s=-
|
108
114
|
t=0 0
|
109
115
|
a=ice-lite
|
110
116
|
m=application ${port} UDP/DTLS/SCTP webrtc-datachannel
|
111
|
-
c=IN IP${
|
117
|
+
c=IN IP${type === 'ip4' ? 4 : 6} ${host}
|
112
118
|
a=mid:0
|
113
119
|
a=ice-options:ice2
|
114
120
|
a=ice-ufrag:${ufrag}
|
@@ -131,11 +137,16 @@ a=end-of-candidates
|
|
131
137
|
* Create an offer SDP message from a multiaddr
|
132
138
|
*/
|
133
139
|
export function clientOfferFromMultiAddr (ma: Multiaddr, ufrag: string): RTCSessionDescriptionInit {
|
134
|
-
const { host, port,
|
140
|
+
const { host, port, type } = getNetConfig(ma)
|
141
|
+
|
142
|
+
if (type !== 'ip4' && type !== 'ip6') {
|
143
|
+
throw new InvalidParametersError(`Multiaddr ${ma} was not an IPv4 or IPv6 address`)
|
144
|
+
}
|
145
|
+
|
135
146
|
const sdp = `v=0
|
136
|
-
o=- 0 0 IN IP${
|
147
|
+
o=- 0 0 IN IP${type === 'ip4' ? 4 : 6} ${host}
|
137
148
|
s=-
|
138
|
-
c=IN IP${
|
149
|
+
c=IN IP${type === 'ip4' ? 4 : 6} ${host}
|
139
150
|
t=0 0
|
140
151
|
a=ice-options:ice2,trickle
|
141
152
|
m=application ${port} UDP/DTLS/SCTP webrtc-datachannel
|
@@ -166,8 +177,13 @@ export function munge (desc: RTCSessionDescriptionInit, ufrag: string): RTCSessi
|
|
166
177
|
|
167
178
|
const lineBreak = desc.sdp.includes('\r\n') ? '\r\n' : '\n'
|
168
179
|
|
169
|
-
|
170
|
-
.
|
171
|
-
|
180
|
+
try {
|
181
|
+
desc.sdp = desc.sdp
|
182
|
+
.replace(/\na=ice-ufrag:[^\n]*\n/, '\na=ice-ufrag:' + ufrag + lineBreak)
|
183
|
+
.replace(/\na=ice-pwd:[^\n]*\n/, '\na=ice-pwd:' + ufrag + lineBreak)
|
184
|
+
} catch {
|
185
|
+
// fails under Node.js
|
186
|
+
}
|
187
|
+
|
172
188
|
return desc
|
173
189
|
}
|
@@ -0,0 +1,62 @@
|
|
1
|
+
import { AbstractMultiaddrConnection } from '@libp2p/utils'
|
2
|
+
import type { RTCPeerConnection } from './webrtc/index.js'
|
3
|
+
import type { AbortOptions, MultiaddrConnection } from '@libp2p/interface'
|
4
|
+
import type { AbstractMultiaddrConnectionInit, SendResult } from '@libp2p/utils'
|
5
|
+
import type { Uint8ArrayList } from 'uint8arraylist'
|
6
|
+
|
7
|
+
export interface RTCPeerConnectionMultiaddrConnectionInit extends Omit<AbstractMultiaddrConnectionInit, 'stream'> {
|
8
|
+
peerConnection: RTCPeerConnection
|
9
|
+
}
|
10
|
+
|
11
|
+
class RTCPeerConnectionMultiaddrConnection extends AbstractMultiaddrConnection {
|
12
|
+
private peerConnection: RTCPeerConnection
|
13
|
+
|
14
|
+
constructor (init: RTCPeerConnectionMultiaddrConnectionInit) {
|
15
|
+
super(init)
|
16
|
+
|
17
|
+
this.peerConnection = init.peerConnection
|
18
|
+
|
19
|
+
const initialState = init.peerConnection.connectionState
|
20
|
+
|
21
|
+
this.peerConnection.onconnectionstatechange = () => {
|
22
|
+
this.log.trace('peer connection state change %s initial state %s', this.peerConnection.connectionState, initialState)
|
23
|
+
|
24
|
+
if (this.peerConnection.connectionState === 'disconnected' || this.peerConnection.connectionState === 'failed' || this.peerConnection.connectionState === 'closed') {
|
25
|
+
// nothing else to do but close the connection
|
26
|
+
this.onTransportClosed()
|
27
|
+
}
|
28
|
+
}
|
29
|
+
}
|
30
|
+
|
31
|
+
sendData (data: Uint8ArrayList): SendResult {
|
32
|
+
return {
|
33
|
+
sentBytes: data.byteLength,
|
34
|
+
canSendMore: true
|
35
|
+
}
|
36
|
+
}
|
37
|
+
|
38
|
+
async sendClose (options?: AbortOptions): Promise<void> {
|
39
|
+
this.peerConnection.close()
|
40
|
+
options?.signal?.throwIfAborted()
|
41
|
+
}
|
42
|
+
|
43
|
+
sendReset (): void {
|
44
|
+
this.peerConnection.close()
|
45
|
+
}
|
46
|
+
|
47
|
+
sendPause (): void {
|
48
|
+
// TODO: readable backpressure?
|
49
|
+
}
|
50
|
+
|
51
|
+
sendResume (): void {
|
52
|
+
// TODO: readable backpressure?
|
53
|
+
}
|
54
|
+
}
|
55
|
+
|
56
|
+
/**
|
57
|
+
* Convert a RTCPeerConnection into a MultiaddrConnection
|
58
|
+
* https://github.com/libp2p/interface-transport#multiaddrconnection
|
59
|
+
*/
|
60
|
+
export const toMultiaddrConnection = (init: RTCPeerConnectionMultiaddrConnectionInit): MultiaddrConnection => {
|
61
|
+
return new RTCPeerConnectionMultiaddrConnection(init)
|
62
|
+
}
|