@libp2p/webrtc 3.0.0 → 3.1.0-c858ca7f

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.
Files changed (54) hide show
  1. package/dist/index.min.js +17 -18
  2. package/dist/src/private-to-private/handler.d.ts +1 -0
  3. package/dist/src/private-to-private/handler.d.ts.map +1 -1
  4. package/dist/src/private-to-private/handler.js +102 -85
  5. package/dist/src/private-to-private/handler.js.map +1 -1
  6. package/dist/src/private-to-private/transport.d.ts.map +1 -1
  7. package/dist/src/private-to-private/transport.js +2 -0
  8. package/dist/src/private-to-private/transport.js.map +1 -1
  9. package/dist/src/private-to-private/util.d.ts.map +1 -1
  10. package/dist/src/private-to-private/util.js +1 -0
  11. package/dist/src/private-to-private/util.js.map +1 -1
  12. package/dist/src/private-to-public/transport.d.ts.map +1 -1
  13. package/dist/src/private-to-public/transport.js +98 -91
  14. package/dist/src/private-to-public/transport.js.map +1 -1
  15. package/dist/src/webrtc/index.browser.d.ts +15 -0
  16. package/dist/src/webrtc/index.browser.d.ts.map +1 -0
  17. package/dist/src/webrtc/index.browser.js +5 -0
  18. package/dist/src/webrtc/index.browser.js.map +1 -0
  19. package/dist/src/webrtc/index.d.ts +8 -0
  20. package/dist/src/webrtc/index.d.ts.map +1 -0
  21. package/dist/src/webrtc/index.js +11 -0
  22. package/dist/src/webrtc/index.js.map +1 -0
  23. package/dist/src/webrtc/rtc-data-channel.d.ts +29 -0
  24. package/dist/src/webrtc/rtc-data-channel.d.ts.map +1 -0
  25. package/dist/src/webrtc/rtc-data-channel.js +115 -0
  26. package/dist/src/webrtc/rtc-data-channel.js.map +1 -0
  27. package/dist/src/webrtc/rtc-events.d.ts +9 -0
  28. package/dist/src/webrtc/rtc-events.d.ts.map +1 -0
  29. package/dist/src/webrtc/rtc-events.js +15 -0
  30. package/dist/src/webrtc/rtc-events.js.map +1 -0
  31. package/dist/src/webrtc/rtc-ice-candidate.d.ts +22 -0
  32. package/dist/src/webrtc/rtc-ice-candidate.d.ts.map +1 -0
  33. package/dist/src/webrtc/rtc-ice-candidate.js +47 -0
  34. package/dist/src/webrtc/rtc-ice-candidate.js.map +1 -0
  35. package/dist/src/webrtc/rtc-peer-connection.d.ts +47 -0
  36. package/dist/src/webrtc/rtc-peer-connection.d.ts.map +1 -0
  37. package/dist/src/webrtc/rtc-peer-connection.js +245 -0
  38. package/dist/src/webrtc/rtc-peer-connection.js.map +1 -0
  39. package/dist/src/webrtc/rtc-session-description.d.ts +10 -0
  40. package/dist/src/webrtc/rtc-session-description.d.ts.map +1 -0
  41. package/dist/src/webrtc/rtc-session-description.js +18 -0
  42. package/dist/src/webrtc/rtc-session-description.js.map +1 -0
  43. package/package.json +15 -10
  44. package/src/private-to-private/handler.ts +120 -102
  45. package/src/private-to-private/transport.ts +2 -0
  46. package/src/private-to-private/util.ts +1 -0
  47. package/src/private-to-public/transport.ts +109 -103
  48. package/src/webrtc/index.browser.ts +4 -0
  49. package/src/webrtc/index.ts +12 -0
  50. package/src/webrtc/rtc-data-channel.ts +140 -0
  51. package/src/webrtc/rtc-events.ts +19 -0
  52. package/src/webrtc/rtc-ice-candidate.ts +50 -0
  53. package/src/webrtc/rtc-peer-connection.ts +306 -0
  54. package/src/webrtc/rtc-session-description.ts +19 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rtc-peer-connection.js","sourceRoot":"","sources":["../../../src/webrtc/rtc-peer-connection.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @see https://developer.mozilla.org/docs/Web/API/RTCSessionDescription
3
+ */
4
+ export declare class SessionDescription implements RTCSessionDescription {
5
+ readonly sdp: string;
6
+ readonly type: RTCSdpType;
7
+ constructor(init: RTCSessionDescriptionInit);
8
+ toJSON(): RTCSessionDescriptionInit;
9
+ }
10
+ //# sourceMappingURL=rtc-session-description.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rtc-session-description.d.ts","sourceRoot":"","sources":["../../../src/webrtc/rtc-session-description.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,kBAAmB,YAAW,qBAAqB;IAC9D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;gBAEZ,IAAI,EAAE,yBAAyB;IAK5C,MAAM,IAAK,yBAAyB;CAMrC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @see https://developer.mozilla.org/docs/Web/API/RTCSessionDescription
3
+ */
4
+ export class SessionDescription {
5
+ sdp;
6
+ type;
7
+ constructor(init) {
8
+ this.sdp = init.sdp ?? '';
9
+ this.type = init.type;
10
+ }
11
+ toJSON() {
12
+ return {
13
+ sdp: this.sdp,
14
+ type: this.type
15
+ };
16
+ }
17
+ }
18
+ //# sourceMappingURL=rtc-session-description.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rtc-session-description.js","sourceRoot":"","sources":["../../../src/webrtc/rtc-session-description.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,OAAO,kBAAkB;IACpB,GAAG,CAAQ;IACX,IAAI,CAAY;IAEzB,YAAa,IAA+B;QAC1C,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,EAAE,CAAA;QACzB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;IACvB,CAAC;IAED,MAAM;QACJ,OAAO;YACL,GAAG,EAAE,IAAI,CAAC,GAAG;YACb,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB,CAAA;IACH,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@libp2p/webrtc",
3
- "version": "3.0.0",
3
+ "version": "3.1.0-c858ca7f",
4
4
  "description": "A libp2p transport using WebRTC connections",
5
5
  "author": "",
6
6
  "license": "Apache-2.0 OR MIT",
@@ -35,7 +35,8 @@
35
35
  "scripts": {
36
36
  "generate": "protons src/private-to-private/pb/message.proto src/pb/message.proto",
37
37
  "build": "aegir build",
38
- "test": "aegir test -t browser",
38
+ "test": "aegir test -t node -t browser -t electron-main",
39
+ "test:node": "aegir test -t node --cov",
39
40
  "test:chrome": "aegir test -t browser --cov",
40
41
  "test:firefox": "aegir test -t browser -- --browser firefox",
41
42
  "lint": "aegir lint",
@@ -45,10 +46,10 @@
45
46
  },
46
47
  "dependencies": {
47
48
  "@chainsafe/libp2p-noise": "^12.0.0",
48
- "@libp2p/interface": "^0.1.0",
49
- "@libp2p/interface-internal": "^0.1.0",
50
- "@libp2p/logger": "^3.0.0",
51
- "@libp2p/peer-id": "^3.0.0",
49
+ "@libp2p/interface": "0.1.0-c858ca7f",
50
+ "@libp2p/interface-internal": "0.1.0-c858ca7f",
51
+ "@libp2p/logger": "3.0.0-c858ca7f",
52
+ "@libp2p/peer-id": "3.0.0-c858ca7f",
52
53
  "@multiformats/mafmt": "^12.1.2",
53
54
  "@multiformats/multiaddr": "^12.1.3",
54
55
  "abortable-iterator": "^5.0.1",
@@ -61,6 +62,7 @@
61
62
  "it-to-buffer": "^4.0.2",
62
63
  "multiformats": "^12.0.1",
63
64
  "multihashes": "^4.0.3",
65
+ "node-datachannel": "^0.4.3",
64
66
  "p-defer": "^4.0.0",
65
67
  "p-event": "^6.0.0",
66
68
  "protons-runtime": "^5.0.0",
@@ -69,18 +71,21 @@
69
71
  },
70
72
  "devDependencies": {
71
73
  "@chainsafe/libp2p-yamux": "^4.0.0",
72
- "@libp2p/interface-compliance-tests": "^4.0.0",
73
- "@libp2p/peer-id-factory": "^3.0.0",
74
- "@libp2p/websockets": "^7.0.0",
74
+ "@libp2p/interface-compliance-tests": "4.0.0-c858ca7f",
75
+ "@libp2p/peer-id-factory": "3.0.0-c858ca7f",
76
+ "@libp2p/websockets": "7.0.0-c858ca7f",
75
77
  "@types/sinon": "^10.0.15",
76
78
  "aegir": "^40.0.1",
77
79
  "delay": "^6.0.0",
78
80
  "it-length": "^3.0.2",
79
81
  "it-map": "^3.0.3",
80
82
  "it-pair": "^2.0.6",
81
- "libp2p": "^0.46.0",
83
+ "libp2p": "0.46.0-c858ca7f",
82
84
  "protons": "^7.0.2",
83
85
  "sinon": "^15.1.2",
84
86
  "sinon-ts": "^1.0.0"
87
+ },
88
+ "browser": {
89
+ "./dist/src/webrtc/index.js": "./dist/src/webrtc/index.browser.js"
85
90
  }
86
91
  }
@@ -1,8 +1,10 @@
1
+ import { CodeError } from '@libp2p/interface/errors'
1
2
  import { logger } from '@libp2p/logger'
2
3
  import { abortableDuplex } from 'abortable-iterator'
3
4
  import { pbStream } from 'it-protobuf-stream'
4
5
  import pDefer, { type DeferredPromise } from 'p-defer'
5
6
  import { DataChannelMuxerFactory } from '../muxer.js'
7
+ import { RTCPeerConnection, RTCSessionDescription } from '../webrtc/index.js'
6
8
  import { Message } from './pb/message.js'
7
9
  import { readCandidatesUntilConnected, resolveOnConnected } from './util.js'
8
10
  import type { DataChannelOpts } from '../stream.js'
@@ -20,66 +22,75 @@ export async function handleIncomingStream ({ rtcConfiguration, dataChannelOptio
20
22
  const signal = AbortSignal.timeout(DEFAULT_TIMEOUT)
21
23
  const stream = pbStream(abortableDuplex(rawStream, signal)).pb(Message)
22
24
  const pc = new RTCPeerConnection(rtcConfiguration)
23
- const muxerFactory = new DataChannelMuxerFactory({ peerConnection: pc, dataChannelOptions })
24
- const connectedPromise: DeferredPromise<void> = pDefer()
25
- const answerSentPromise: DeferredPromise<void> = pDefer()
26
-
27
- signal.onabort = () => { connectedPromise.reject() }
28
- // candidate callbacks
29
- pc.onicecandidate = ({ candidate }) => {
30
- answerSentPromise.promise.then(
31
- async () => {
32
- await stream.write({
33
- type: Message.Type.ICE_CANDIDATE,
34
- data: (candidate != null) ? JSON.stringify(candidate.toJSON()) : ''
35
- })
36
- },
37
- (err) => {
38
- log.error('cannot set candidate since sending answer failed', err)
39
- }
40
- )
41
- }
42
25
 
43
- resolveOnConnected(pc, connectedPromise)
26
+ try {
27
+ const muxerFactory = new DataChannelMuxerFactory({ peerConnection: pc, dataChannelOptions })
28
+ const connectedPromise: DeferredPromise<void> = pDefer()
29
+ const answerSentPromise: DeferredPromise<void> = pDefer()
30
+
31
+ signal.onabort = () => {
32
+ connectedPromise.reject(new CodeError('Timed out while trying to connect', 'ERR_TIMEOUT'))
33
+ }
34
+ // candidate callbacks
35
+ pc.onicecandidate = ({ candidate }) => {
36
+ answerSentPromise.promise.then(
37
+ async () => {
38
+ await stream.write({
39
+ type: Message.Type.ICE_CANDIDATE,
40
+ data: (candidate != null) ? JSON.stringify(candidate.toJSON()) : ''
41
+ })
42
+ },
43
+ (err) => {
44
+ log.error('cannot set candidate since sending answer failed', err)
45
+ connectedPromise.reject(err)
46
+ }
47
+ )
48
+ }
49
+
50
+ resolveOnConnected(pc, connectedPromise)
51
+
52
+ // read an SDP offer
53
+ const pbOffer = await stream.read()
54
+ if (pbOffer.type !== Message.Type.SDP_OFFER) {
55
+ throw new Error(`expected message type SDP_OFFER, received: ${pbOffer.type ?? 'undefined'} `)
56
+ }
57
+ const offer = new RTCSessionDescription({
58
+ type: 'offer',
59
+ sdp: pbOffer.data
60
+ })
61
+
62
+ await pc.setRemoteDescription(offer).catch(err => {
63
+ log.error('could not execute setRemoteDescription', err)
64
+ throw new Error('Failed to set remoteDescription')
65
+ })
66
+
67
+ // create and write an SDP answer
68
+ const answer = await pc.createAnswer().catch(err => {
69
+ log.error('could not execute createAnswer', err)
70
+ answerSentPromise.reject(err)
71
+ throw new Error('Failed to create answer')
72
+ })
73
+ // write the answer to the remote
74
+ await stream.write({ type: Message.Type.SDP_ANSWER, data: answer.sdp })
75
+
76
+ await pc.setLocalDescription(answer).catch(err => {
77
+ log.error('could not execute setLocalDescription', err)
78
+ answerSentPromise.reject(err)
79
+ throw new Error('Failed to set localDescription')
80
+ })
81
+
82
+ answerSentPromise.resolve()
83
+
84
+ // wait until candidates are connected
85
+ await readCandidatesUntilConnected(connectedPromise, pc, stream)
44
86
 
45
- // read an SDP offer
46
- const pbOffer = await stream.read()
47
- if (pbOffer.type !== Message.Type.SDP_OFFER) {
48
- throw new Error(`expected message type SDP_OFFER, received: ${pbOffer.type ?? 'undefined'} `)
87
+ const remoteAddress = parseRemoteAddress(pc.currentRemoteDescription?.sdp ?? '')
88
+
89
+ return { pc, muxerFactory, remoteAddress }
90
+ } catch (err) {
91
+ pc.close()
92
+ throw err
49
93
  }
50
- const offer = new RTCSessionDescription({
51
- type: 'offer',
52
- sdp: pbOffer.data
53
- })
54
-
55
- await pc.setRemoteDescription(offer).catch(err => {
56
- log.error('could not execute setRemoteDescription', err)
57
- throw new Error('Failed to set remoteDescription')
58
- })
59
-
60
- // create and write an SDP answer
61
- const answer = await pc.createAnswer().catch(err => {
62
- log.error('could not execute createAnswer', err)
63
- answerSentPromise.reject(err)
64
- throw new Error('Failed to create answer')
65
- })
66
- // write the answer to the remote
67
- await stream.write({ type: Message.Type.SDP_ANSWER, data: answer.sdp })
68
-
69
- await pc.setLocalDescription(answer).catch(err => {
70
- log.error('could not execute setLocalDescription', err)
71
- answerSentPromise.reject(err)
72
- throw new Error('Failed to set localDescription')
73
- })
74
-
75
- answerSentPromise.resolve()
76
-
77
- // wait until candidates are connected
78
- await readCandidatesUntilConnected(connectedPromise, pc, stream)
79
-
80
- const remoteAddress = parseRemoteAddress(pc.currentRemoteDescription?.sdp ?? '')
81
-
82
- return { pc, muxerFactory, remoteAddress }
83
94
  }
84
95
 
85
96
  export interface ConnectOptions {
@@ -93,56 +104,63 @@ export async function initiateConnection ({ rtcConfiguration, dataChannelOptions
93
104
  const stream = pbStream(abortableDuplex(rawStream, signal)).pb(Message)
94
105
  // setup peer connection
95
106
  const pc = new RTCPeerConnection(rtcConfiguration)
96
- const muxerFactory = new DataChannelMuxerFactory({ peerConnection: pc, dataChannelOptions })
97
-
98
- const connectedPromise: DeferredPromise<void> = pDefer()
99
- resolveOnConnected(pc, connectedPromise)
100
-
101
- // reject the connectedPromise if the signal aborts
102
- signal.onabort = connectedPromise.reject
103
- // we create the channel so that the peerconnection has a component for which
104
- // to collect candidates. The label is not relevant to connection initiation
105
- // but can be useful for debugging
106
- const channel = pc.createDataChannel('init')
107
- // setup callback to write ICE candidates to the remote
108
- // peer
109
- pc.onicecandidate = ({ candidate }) => {
110
- void stream.write({
111
- type: Message.Type.ICE_CANDIDATE,
112
- data: (candidate != null) ? JSON.stringify(candidate.toJSON()) : ''
113
- })
114
- .catch(err => {
115
- log.error('error sending ICE candidate', err)
107
+
108
+ try {
109
+ const muxerFactory = new DataChannelMuxerFactory({ peerConnection: pc, dataChannelOptions })
110
+
111
+ const connectedPromise: DeferredPromise<void> = pDefer()
112
+ resolveOnConnected(pc, connectedPromise)
113
+
114
+ // reject the connectedPromise if the signal aborts
115
+ signal.onabort = connectedPromise.reject
116
+ // we create the channel so that the peerconnection has a component for which
117
+ // to collect candidates. The label is not relevant to connection initiation
118
+ // but can be useful for debugging
119
+ const channel = pc.createDataChannel('init')
120
+ // setup callback to write ICE candidates to the remote
121
+ // peer
122
+ pc.onicecandidate = ({ candidate }) => {
123
+ void stream.write({
124
+ type: Message.Type.ICE_CANDIDATE,
125
+ data: (candidate != null) ? JSON.stringify(candidate.toJSON()) : ''
116
126
  })
117
- }
118
- // create an offer
119
- const offerSdp = await pc.createOffer()
120
- // write the offer to the stream
121
- await stream.write({ type: Message.Type.SDP_OFFER, data: offerSdp.sdp })
122
- // set offer as local description
123
- await pc.setLocalDescription(offerSdp).catch(err => {
124
- log.error('could not execute setLocalDescription', err)
125
- throw new Error('Failed to set localDescription')
126
- })
127
-
128
- // read answer
129
- const answerMessage = await stream.read()
130
- if (answerMessage.type !== Message.Type.SDP_ANSWER) {
131
- throw new Error('remote should send an SDP answer')
132
- }
127
+ .catch(err => {
128
+ log.error('error sending ICE candidate', err)
129
+ })
130
+ }
131
+
132
+ // create an offer
133
+ const offerSdp = await pc.createOffer()
134
+ // write the offer to the stream
135
+ await stream.write({ type: Message.Type.SDP_OFFER, data: offerSdp.sdp })
136
+ // set offer as local description
137
+ await pc.setLocalDescription(offerSdp).catch(err => {
138
+ log.error('could not execute setLocalDescription', err)
139
+ throw new Error('Failed to set localDescription')
140
+ })
133
141
 
134
- const answerSdp = new RTCSessionDescription({ type: 'answer', sdp: answerMessage.data })
135
- await pc.setRemoteDescription(answerSdp).catch(err => {
136
- log.error('could not execute setRemoteDescription', err)
137
- throw new Error('Failed to set remoteDescription')
138
- })
142
+ // read answer
143
+ const answerMessage = await stream.read()
144
+ if (answerMessage.type !== Message.Type.SDP_ANSWER) {
145
+ throw new Error('remote should send an SDP answer')
146
+ }
139
147
 
140
- await readCandidatesUntilConnected(connectedPromise, pc, stream)
141
- channel.close()
148
+ const answerSdp = new RTCSessionDescription({ type: 'answer', sdp: answerMessage.data })
149
+ await pc.setRemoteDescription(answerSdp).catch(err => {
150
+ log.error('could not execute setRemoteDescription', err)
151
+ throw new Error('Failed to set remoteDescription')
152
+ })
142
153
 
143
- const remoteAddress = parseRemoteAddress(pc.currentRemoteDescription?.sdp ?? '')
154
+ await readCandidatesUntilConnected(connectedPromise, pc, stream)
155
+ channel.close()
144
156
 
145
- return { pc, muxerFactory, remoteAddress }
157
+ const remoteAddress = parseRemoteAddress(pc.currentRemoteDescription?.sdp ?? '')
158
+
159
+ return { pc, muxerFactory, remoteAddress }
160
+ } catch (err) {
161
+ pc.close()
162
+ throw err
163
+ }
146
164
  }
147
165
 
148
166
  function parseRemoteAddress (sdp: string): string {
@@ -5,6 +5,7 @@ import { peerIdFromString } from '@libp2p/peer-id'
5
5
  import { multiaddr, type Multiaddr, protocols } from '@multiformats/multiaddr'
6
6
  import { codes } from '../error.js'
7
7
  import { WebRTCMultiaddrConnection } from '../maconn.js'
8
+ import { cleanup } from '../webrtc/index.js'
8
9
  import { initiateConnection, handleIncomingStream } from './handler.js'
9
10
  import { WebRTCPeerListener } from './listener.js'
10
11
  import type { DataChannelOpts } from '../stream.js'
@@ -57,6 +58,7 @@ export class WebRTCTransport implements Transport, Startable {
57
58
 
58
59
  async stop (): Promise<void> {
59
60
  await this.components.registrar.unhandle(SIGNALING_PROTO_ID)
61
+ cleanup()
60
62
  this._started = false
61
63
  }
62
64
 
@@ -1,5 +1,6 @@
1
1
  import { logger } from '@libp2p/logger'
2
2
  import { isFirefox } from '../util.js'
3
+ import { RTCIceCandidate } from '../webrtc/index.js'
3
4
  import { Message } from './pb/message.js'
4
5
  import type { DeferredPromise } from 'p-defer'
5
6
 
@@ -11,6 +11,7 @@ import { WebRTCMultiaddrConnection } from '../maconn.js'
11
11
  import { DataChannelMuxerFactory } from '../muxer.js'
12
12
  import { createStream } from '../stream.js'
13
13
  import { isFirefox } from '../util.js'
14
+ import { RTCPeerConnection } from '../webrtc/index.js'
14
15
  import * as sdp from './sdp.js'
15
16
  import { genUfrag } from './util.js'
16
17
  import type { WebRTCDialOptions } from './options.js'
@@ -134,116 +135,121 @@ export class WebRTCDirectTransport implements Transport {
134
135
 
135
136
  const peerConnection = new RTCPeerConnection({ certificates: [certificate] })
136
137
 
137
- // create data channel for running the noise handshake. Once the data channel is opened,
138
- // the remote will initiate the noise handshake. This is used to confirm the identity of
139
- // the peer.
140
- const dataChannelOpenPromise = new Promise<RTCDataChannel>((resolve, reject) => {
141
- const handshakeDataChannel = peerConnection.createDataChannel('', { negotiated: true, id: 0 })
142
- const handshakeTimeout = setTimeout(() => {
143
- const error = `Data channel was never opened: state: ${handshakeDataChannel.readyState}`
144
- log.error(error)
145
- this.metrics?.dialerEvents.increment({ open_error: true })
146
- reject(dataChannelError('data', error))
147
- }, HANDSHAKE_TIMEOUT_MS)
148
-
149
- handshakeDataChannel.onopen = (_) => {
150
- clearTimeout(handshakeTimeout)
151
- resolve(handshakeDataChannel)
152
- }
153
-
154
- // ref: https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel/error_event
155
- handshakeDataChannel.onerror = (event: Event) => {
156
- clearTimeout(handshakeTimeout)
157
- const errorTarget = event.target?.toString() ?? 'not specified'
158
- const error = `Error opening a data channel for handshaking: ${errorTarget}`
159
- log.error(error)
160
- // NOTE: We use unknown error here but this could potentially be considered a reset by some standards.
161
- this.metrics?.dialerEvents.increment({ unknown_error: true })
162
- reject(dataChannelError('data', error))
163
- }
164
- })
165
-
166
- const ufrag = 'libp2p+webrtc+v1/' + genUfrag(32)
167
-
168
- // Create offer and munge sdp with ufrag == pwd. This allows the remote to
169
- // respond to STUN messages without performing an actual SDP exchange.
170
- // This is because it can infer the passwd field by reading the USERNAME
171
- // attribute of the STUN message.
172
- const offerSdp = await peerConnection.createOffer()
173
- const mungedOfferSdp = sdp.munge(offerSdp, ufrag)
174
- await peerConnection.setLocalDescription(mungedOfferSdp)
175
-
176
- // construct answer sdp from multiaddr and ufrag
177
- const answerSdp = sdp.fromMultiAddr(ma, ufrag)
178
- await peerConnection.setRemoteDescription(answerSdp)
179
-
180
- // wait for peerconnection.onopen to fire, or for the datachannel to open
181
- const handshakeDataChannel = await dataChannelOpenPromise
182
-
183
- const myPeerId = this.components.peerId
184
-
185
- // Do noise handshake.
186
- // Set the Noise Prologue to libp2p-webrtc-noise:<FINGERPRINTS> before starting the actual Noise handshake.
187
- // <FINGERPRINTS> is the concatenation of the of the two TLS fingerprints of A and B in their multihash byte representation, sorted in ascending order.
188
- const fingerprintsPrologue = this.generateNoisePrologue(peerConnection, remoteCerthash.code, ma)
189
-
190
- // Since we use the default crypto interface and do not use a static key or early data,
191
- // we pass in undefined for these parameters.
192
- const noise = Noise({ prologueBytes: fingerprintsPrologue })()
193
-
194
- const wrappedChannel = createStream({ channel: handshakeDataChannel, direction: 'inbound', dataChannelOptions: this.init.dataChannel })
195
- const wrappedDuplex = {
196
- ...wrappedChannel,
197
- sink: wrappedChannel.sink.bind(wrappedChannel),
198
- source: (async function * () {
199
- for await (const list of wrappedChannel.source) {
200
- for (const buf of list) {
201
- yield buf
202
- }
138
+ try {
139
+ // create data channel for running the noise handshake. Once the data channel is opened,
140
+ // the remote will initiate the noise handshake. This is used to confirm the identity of
141
+ // the peer.
142
+ const dataChannelOpenPromise = new Promise<RTCDataChannel>((resolve, reject) => {
143
+ const handshakeDataChannel = peerConnection.createDataChannel('', { negotiated: true, id: 0 })
144
+ const handshakeTimeout = setTimeout(() => {
145
+ const error = `Data channel was never opened: state: ${handshakeDataChannel.readyState}`
146
+ log.error(error)
147
+ this.metrics?.dialerEvents.increment({ open_error: true })
148
+ reject(dataChannelError('data', error))
149
+ }, HANDSHAKE_TIMEOUT_MS)
150
+
151
+ handshakeDataChannel.onopen = (_) => {
152
+ clearTimeout(handshakeTimeout)
153
+ resolve(handshakeDataChannel)
203
154
  }
204
- }())
205
- }
206
155
 
207
- // Creating the connection before completion of the noise
208
- // handshake ensures that the stream opening callback is set up
209
- const maConn = new WebRTCMultiaddrConnection({
210
- peerConnection,
211
- remoteAddr: ma,
212
- timeline: {
213
- open: Date.now()
214
- },
215
- metrics: this.metrics?.dialerEvents
216
- })
217
-
218
- const eventListeningName = isFirefox ? 'iceconnectionstatechange' : 'connectionstatechange'
219
-
220
- peerConnection.addEventListener(eventListeningName, () => {
221
- switch (peerConnection.connectionState) {
222
- case 'failed':
223
- case 'disconnected':
224
- case 'closed':
225
- maConn.close().catch((err) => {
226
- log.error('error closing connection', err)
227
- }).finally(() => {
228
- // Remove the event listener once the connection is closed
229
- controller.abort()
230
- })
231
- break
232
- default:
233
- break
156
+ // ref: https://developer.mozilla.org/en-US/docs/Web/API/RTCDataChannel/error_event
157
+ handshakeDataChannel.onerror = (event: Event) => {
158
+ clearTimeout(handshakeTimeout)
159
+ const errorTarget = event.target?.toString() ?? 'not specified'
160
+ const error = `Error opening a data channel for handshaking: ${errorTarget}`
161
+ log.error(error)
162
+ // NOTE: We use unknown error here but this could potentially be considered a reset by some standards.
163
+ this.metrics?.dialerEvents.increment({ unknown_error: true })
164
+ reject(dataChannelError('data', error))
165
+ }
166
+ })
167
+
168
+ const ufrag = 'libp2p+webrtc+v1/' + genUfrag(32)
169
+
170
+ // Create offer and munge sdp with ufrag == pwd. This allows the remote to
171
+ // respond to STUN messages without performing an actual SDP exchange.
172
+ // This is because it can infer the passwd field by reading the USERNAME
173
+ // attribute of the STUN message.
174
+ const offerSdp = await peerConnection.createOffer()
175
+ const mungedOfferSdp = sdp.munge(offerSdp, ufrag)
176
+ await peerConnection.setLocalDescription(mungedOfferSdp)
177
+
178
+ // construct answer sdp from multiaddr and ufrag
179
+ const answerSdp = sdp.fromMultiAddr(ma, ufrag)
180
+ await peerConnection.setRemoteDescription(answerSdp)
181
+
182
+ // wait for peerconnection.onopen to fire, or for the datachannel to open
183
+ const handshakeDataChannel = await dataChannelOpenPromise
184
+
185
+ const myPeerId = this.components.peerId
186
+
187
+ // Do noise handshake.
188
+ // Set the Noise Prologue to libp2p-webrtc-noise:<FINGERPRINTS> before starting the actual Noise handshake.
189
+ // <FINGERPRINTS> is the concatenation of the of the two TLS fingerprints of A and B in their multihash byte representation, sorted in ascending order.
190
+ const fingerprintsPrologue = this.generateNoisePrologue(peerConnection, remoteCerthash.code, ma)
191
+
192
+ // Since we use the default crypto interface and do not use a static key or early data,
193
+ // we pass in undefined for these parameters.
194
+ const noise = Noise({ prologueBytes: fingerprintsPrologue })()
195
+
196
+ const wrappedChannel = createStream({ channel: handshakeDataChannel, direction: 'inbound', dataChannelOptions: this.init.dataChannel })
197
+ const wrappedDuplex = {
198
+ ...wrappedChannel,
199
+ sink: wrappedChannel.sink.bind(wrappedChannel),
200
+ source: (async function * () {
201
+ for await (const list of wrappedChannel.source) {
202
+ for (const buf of list) {
203
+ yield buf
204
+ }
205
+ }
206
+ }())
234
207
  }
235
- }, { signal })
236
208
 
237
- // Track opened peer connection
238
- this.metrics?.dialerEvents.increment({ peer_connection: true })
209
+ // Creating the connection before completion of the noise
210
+ // handshake ensures that the stream opening callback is set up
211
+ const maConn = new WebRTCMultiaddrConnection({
212
+ peerConnection,
213
+ remoteAddr: ma,
214
+ timeline: {
215
+ open: Date.now()
216
+ },
217
+ metrics: this.metrics?.dialerEvents
218
+ })
219
+
220
+ const eventListeningName = isFirefox ? 'iceconnectionstatechange' : 'connectionstatechange'
221
+
222
+ peerConnection.addEventListener(eventListeningName, () => {
223
+ switch (peerConnection.connectionState) {
224
+ case 'failed':
225
+ case 'disconnected':
226
+ case 'closed':
227
+ maConn.close().catch((err) => {
228
+ log.error('error closing connection', err)
229
+ }).finally(() => {
230
+ // Remove the event listener once the connection is closed
231
+ controller.abort()
232
+ })
233
+ break
234
+ default:
235
+ break
236
+ }
237
+ }, { signal })
239
238
 
240
- const muxerFactory = new DataChannelMuxerFactory({ peerConnection, metrics: this.metrics?.dialerEvents, dataChannelOptions: this.init.dataChannel })
239
+ // Track opened peer connection
240
+ this.metrics?.dialerEvents.increment({ peer_connection: true })
241
241
 
242
- // For outbound connections, the remote is expected to start the noise handshake.
243
- // Therefore, we need to secure an inbound noise connection from the remote.
244
- await noise.secureInbound(myPeerId, wrappedDuplex, theirPeerId)
242
+ const muxerFactory = new DataChannelMuxerFactory({ peerConnection, metrics: this.metrics?.dialerEvents, dataChannelOptions: this.init.dataChannel })
245
243
 
246
- return options.upgrader.upgradeOutbound(maConn, { skipProtection: true, skipEncryption: true, muxerFactory })
244
+ // For outbound connections, the remote is expected to start the noise handshake.
245
+ // Therefore, we need to secure an inbound noise connection from the remote.
246
+ await noise.secureInbound(myPeerId, wrappedDuplex, theirPeerId)
247
+
248
+ return await options.upgrader.upgradeOutbound(maConn, { skipProtection: true, skipEncryption: true, muxerFactory })
249
+ } catch (err) {
250
+ peerConnection.close()
251
+ throw err
252
+ }
247
253
  }
248
254
 
249
255
  /**
@@ -0,0 +1,4 @@
1
+ export const RTCPeerConnection = globalThis.RTCPeerConnection
2
+ export const RTCSessionDescription = globalThis.RTCSessionDescription
3
+ export const RTCIceCandidate = globalThis.RTCIceCandidate
4
+ export function cleanup (): void {}