@libp2p/webrtc 5.2.9 → 5.2.10-3833353bd

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 (40) hide show
  1. package/README.md +54 -0
  2. package/dist/index.min.js +153 -18
  3. package/dist/src/constants.d.ts +20 -0
  4. package/dist/src/constants.d.ts.map +1 -1
  5. package/dist/src/constants.js +20 -0
  6. package/dist/src/constants.js.map +1 -1
  7. package/dist/src/index.d.ts +54 -0
  8. package/dist/src/index.d.ts.map +1 -1
  9. package/dist/src/index.js +54 -0
  10. package/dist/src/index.js.map +1 -1
  11. package/dist/src/private-to-private/util.d.ts +2 -2
  12. package/dist/src/private-to-private/util.d.ts.map +1 -1
  13. package/dist/src/private-to-public/listener.d.ts +9 -4
  14. package/dist/src/private-to-public/listener.d.ts.map +1 -1
  15. package/dist/src/private-to-public/listener.js +8 -18
  16. package/dist/src/private-to-public/listener.js.map +1 -1
  17. package/dist/src/private-to-public/transport.d.ts +68 -10
  18. package/dist/src/private-to-public/transport.d.ts.map +1 -1
  19. package/dist/src/private-to-public/transport.js +204 -33
  20. package/dist/src/private-to-public/transport.js.map +1 -1
  21. package/dist/src/private-to-public/utils/connect.js +126 -124
  22. package/dist/src/private-to-public/utils/connect.js.map +1 -1
  23. package/dist/src/private-to-public/utils/pem.d.ts +6 -0
  24. package/dist/src/private-to-public/utils/pem.d.ts.map +1 -0
  25. package/dist/src/private-to-public/utils/pem.js +15 -0
  26. package/dist/src/private-to-public/utils/pem.js.map +1 -0
  27. package/dist/src/stream.d.ts +5 -0
  28. package/dist/src/stream.d.ts.map +1 -1
  29. package/dist/src/stream.js +14 -9
  30. package/dist/src/stream.js.map +1 -1
  31. package/package.json +12 -9
  32. package/src/constants.ts +25 -0
  33. package/src/index.ts +54 -0
  34. package/src/private-to-private/util.ts +2 -2
  35. package/src/private-to-public/listener.ts +18 -26
  36. package/src/private-to-public/transport.ts +304 -39
  37. package/src/private-to-public/utils/connect.ts +139 -135
  38. package/src/private-to-public/utils/pem.ts +18 -0
  39. package/src/stream.ts +20 -11
  40. package/dist/typedoc-urls.json +0 -14
@@ -1,20 +1,36 @@
1
- import { serviceCapabilities, transportSymbol } from '@libp2p/interface';
1
+ import { generateKeyPair, privateKeyToCryptoKeyPair } from '@libp2p/crypto/keys';
2
+ import { InvalidParametersError, NotFoundError, NotStartedError, TypedEventEmitter, serviceCapabilities, transportSymbol } from '@libp2p/interface';
2
3
  import { peerIdFromString } from '@libp2p/peer-id';
3
4
  import { WebRTCDirect } from '@multiformats/multiaddr-matcher';
4
- import { raceSignal } from 'race-signal';
5
+ import { BasicConstraintsExtension, X509Certificate, X509CertificateGenerator } from '@peculiar/x509';
6
+ import { Key } from 'interface-datastore';
7
+ import { base64url } from 'multiformats/bases/base64';
8
+ import { sha256 } from 'multiformats/hashes/sha2';
9
+ import { equals as uint8ArrayEquals } from 'uint8arrays/equals';
10
+ import { fromString as uint8ArrayFromString } from 'uint8arrays/from-string';
11
+ import { DEFAULT_CERTIFICATE_DATASTORE_KEY, DEFAULT_CERTIFICATE_LIFESPAN, DEFAULT_CERTIFICATE_PRIVATE_KEY_NAME, DEFAULT_CERTIFICATE_RENEWAL_THRESHOLD } from '../constants.js';
5
12
  import { genUfrag } from '../util.js';
6
13
  import { WebRTCDirectListener } from './listener.js';
7
14
  import { connect } from './utils/connect.js';
8
15
  import { createDialerRTCPeerConnection } from './utils/get-rtcpeerconnection.js';
16
+ import { formatAsPem } from './utils/pem.js';
9
17
  export class WebRTCDirectTransport {
10
18
  log;
11
19
  metrics;
12
20
  components;
13
21
  init;
22
+ certificate;
23
+ privateKey;
24
+ emitter;
25
+ renewCertificateTask;
14
26
  constructor(components, init = {}) {
15
27
  this.log = components.logger.forComponent('libp2p:webrtc-direct');
16
28
  this.components = components;
17
29
  this.init = init;
30
+ this.emitter = new TypedEventEmitter();
31
+ if (init.certificateLifespan != null && init.certificateRenewalThreshold != null && init.certificateRenewalThreshold >= init.certificateLifespan) {
32
+ throw new InvalidParametersError('Certificate renewal threshold must be less than certificate lifespan');
33
+ }
18
34
  if (components.metrics != null) {
19
35
  this.metrics = {
20
36
  dialerEvents: components.metrics.registerCounterGroup('libp2p_webrtc-direct_dialer_events_total', {
@@ -29,39 +45,20 @@ export class WebRTCDirectTransport {
29
45
  [serviceCapabilities] = [
30
46
  '@libp2p/transport'
31
47
  ];
32
- /**
33
- * Dial a given multiaddr
34
- */
35
- async dial(ma, options) {
36
- const rawConn = await this._connect(ma, options);
37
- this.log('dialing address: %a', ma);
38
- return rawConn;
39
- }
40
- /**
41
- * Create transport listeners no supported by browsers
42
- */
43
- createListener(options) {
44
- return new WebRTCDirectListener(this.components, {
45
- ...this.init,
46
- ...options
47
- });
48
- }
49
- /**
50
- * Filter check for all Multiaddrs that this transport can listen on
51
- */
52
- listenFilter(multiaddrs) {
53
- return multiaddrs.filter(WebRTCDirect.exactMatch);
48
+ async start() {
49
+ this.certificate = await this.getCertificate();
54
50
  }
55
- /**
56
- * Filter check for all Multiaddrs that this transport can dial
57
- */
58
- dialFilter(multiaddrs) {
59
- return this.listenFilter(multiaddrs);
51
+ async stop() {
52
+ if (this.renewCertificateTask != null) {
53
+ clearTimeout(this.renewCertificateTask);
54
+ }
55
+ this.certificate = undefined;
60
56
  }
61
57
  /**
62
- * Connect to a peer using a multiaddr
58
+ * Dial a given multiaddr
63
59
  */
64
- async _connect(ma, options) {
60
+ async dial(ma, options) {
61
+ this.log('dial %a', ma);
65
62
  // do not create RTCPeerConnection if the signal has already been aborted
66
63
  options.signal.throwIfAborted();
67
64
  let theirPeerId;
@@ -73,7 +70,7 @@ export class WebRTCDirectTransport {
73
70
  // https://github.com/libp2p/specs/blob/master/webrtc/webrtc-direct.md#browser-to-public-server
74
71
  const peerConnection = await createDialerRTCPeerConnection('client', ufrag, typeof this.init.rtcConfiguration === 'function' ? await this.init.rtcConfiguration() : this.init.rtcConfiguration ?? {});
75
72
  try {
76
- return await raceSignal(connect(peerConnection, ufrag, {
73
+ return await connect(peerConnection, ufrag, {
77
74
  role: 'client',
78
75
  log: this.log,
79
76
  logger: this.components.logger,
@@ -86,12 +83,186 @@ export class WebRTCDirectTransport {
86
83
  peerId: this.components.peerId,
87
84
  remotePeerId: theirPeerId,
88
85
  privateKey: this.components.privateKey
89
- }), options.signal);
86
+ });
90
87
  }
91
88
  catch (err) {
92
89
  peerConnection.close();
93
90
  throw err;
94
91
  }
95
92
  }
93
+ /**
94
+ * Create a transport listener - this will throw in browsers
95
+ */
96
+ createListener(options) {
97
+ if (this.certificate == null) {
98
+ throw new NotStartedError();
99
+ }
100
+ return new WebRTCDirectListener(this.components, {
101
+ ...this.init,
102
+ ...options,
103
+ certificate: this.certificate,
104
+ emitter: this.emitter
105
+ });
106
+ }
107
+ /**
108
+ * Filter check for all Multiaddrs that this transport can listen on
109
+ */
110
+ listenFilter(multiaddrs) {
111
+ return multiaddrs.filter(WebRTCDirect.exactMatch);
112
+ }
113
+ /**
114
+ * Filter check for all Multiaddrs that this transport can dial
115
+ */
116
+ dialFilter(multiaddrs) {
117
+ return this.listenFilter(multiaddrs);
118
+ }
119
+ async getCertificate(forceRenew) {
120
+ if (isTransportCertificate(this.init.certificate)) {
121
+ this.log('using provided TLS certificate');
122
+ return this.init.certificate;
123
+ }
124
+ const privateKey = await this.loadOrCreatePrivateKey();
125
+ const { pem, certhash } = await this.loadOrCreateCertificate(privateKey, forceRenew);
126
+ return {
127
+ privateKey: await formatAsPem(privateKey),
128
+ pem,
129
+ certhash
130
+ };
131
+ }
132
+ async loadOrCreatePrivateKey() {
133
+ if (this.privateKey != null) {
134
+ return this.privateKey;
135
+ }
136
+ const keychainName = this.init.certificateKeychainName ?? DEFAULT_CERTIFICATE_PRIVATE_KEY_NAME;
137
+ const keychain = this.getKeychain();
138
+ try {
139
+ if (keychain == null) {
140
+ this.log('no keychain configured - not checking for stored private key');
141
+ throw new NotFoundError();
142
+ }
143
+ this.log.trace('checking for stored private key');
144
+ this.privateKey = await keychain.exportKey(keychainName);
145
+ }
146
+ catch (err) {
147
+ if (err.name !== 'NotFoundError') {
148
+ throw err;
149
+ }
150
+ this.log.trace('generating private key');
151
+ this.privateKey = await generateKeyPair('ECDSA', 'P-256');
152
+ if (keychain != null) {
153
+ this.log.trace('storing private key');
154
+ await keychain.importKey(keychainName, this.privateKey);
155
+ }
156
+ else {
157
+ this.log('no keychain configured - not storing private key');
158
+ }
159
+ }
160
+ return this.privateKey;
161
+ }
162
+ async loadOrCreateCertificate(privateKey, forceRenew) {
163
+ if (this.certificate != null && forceRenew !== true) {
164
+ return this.certificate;
165
+ }
166
+ let cert;
167
+ const dsKey = new Key(this.init.certificateDatastoreKey ?? DEFAULT_CERTIFICATE_DATASTORE_KEY);
168
+ const keyPair = await privateKeyToCryptoKeyPair(privateKey);
169
+ try {
170
+ if (forceRenew === true) {
171
+ this.log.trace('forcing renewal of TLS certificate');
172
+ throw new NotFoundError();
173
+ }
174
+ this.log.trace('checking for stored TLS certificate');
175
+ cert = await this.loadCertificate(dsKey, keyPair);
176
+ }
177
+ catch (err) {
178
+ if (err.name !== 'NotFoundError') {
179
+ throw err;
180
+ }
181
+ this.log.trace('generating new TLS certificate');
182
+ cert = await this.createCertificate(dsKey, keyPair);
183
+ }
184
+ // set timeout to renew certificate
185
+ let renewTime = (cert.notAfter.getTime() - (this.init.certificateRenewalThreshold ?? DEFAULT_CERTIFICATE_RENEWAL_THRESHOLD)) - Date.now();
186
+ if (renewTime < 0) {
187
+ renewTime = 100;
188
+ }
189
+ this.log('will renew TLS certificate after %d ms', renewTime);
190
+ this.renewCertificateTask = setTimeout(() => {
191
+ this.log('renewing TLS certificate');
192
+ this.getCertificate(true)
193
+ .then(cert => {
194
+ this.certificate = cert;
195
+ this.emitter.safeDispatchEvent('certificate:renew', {
196
+ detail: cert
197
+ });
198
+ })
199
+ .catch(err => {
200
+ this.log.error('could not renew certificate - %e', err);
201
+ });
202
+ }, renewTime);
203
+ return {
204
+ pem: cert.toString('pem'),
205
+ certhash: base64url.encode((await sha256.digest(new Uint8Array(cert.rawData))).bytes)
206
+ };
207
+ }
208
+ async loadCertificate(dsKey, keyPair) {
209
+ const buf = await this.components.datastore.get(dsKey);
210
+ const cert = new X509Certificate(buf);
211
+ // check expiry date
212
+ const expiryTime = cert.notAfter.getTime() - (this.init.certificateRenewalThreshold ?? DEFAULT_CERTIFICATE_RENEWAL_THRESHOLD);
213
+ if (Date.now() > expiryTime) {
214
+ this.log('stored TLS certificate has expired');
215
+ // act as if no certificate was present
216
+ throw new NotFoundError();
217
+ }
218
+ this.log('loaded certificate, expires in %d ms', expiryTime);
219
+ // check public keys match
220
+ const exportedCertKey = await cert.publicKey.export(crypto);
221
+ const rawCertKey = await crypto.subtle.exportKey('raw', exportedCertKey);
222
+ const rawKeyPairKey = await crypto.subtle.exportKey('raw', keyPair.publicKey);
223
+ if (!uint8ArrayEquals(new Uint8Array(rawCertKey, 0, rawCertKey.byteLength), new Uint8Array(rawKeyPairKey, 0, rawKeyPairKey.byteLength))) {
224
+ this.log('stored TLS certificate public key did not match public key from private key');
225
+ throw new NotFoundError();
226
+ }
227
+ this.log('loaded certificate, expiry time is %o', expiryTime);
228
+ return cert;
229
+ }
230
+ async createCertificate(dsKey, keyPair) {
231
+ const notBefore = new Date();
232
+ const notAfter = new Date(Date.now() + (this.init.certificateLifespan ?? DEFAULT_CERTIFICATE_LIFESPAN));
233
+ // have to set ms to 0 to work around https://github.com/PeculiarVentures/x509/issues/73
234
+ notBefore.setMilliseconds(0);
235
+ notAfter.setMilliseconds(0);
236
+ const cert = await X509CertificateGenerator.createSelfSigned({
237
+ serialNumber: (BigInt(Math.random().toString().replace('.', '')) * 100000n).toString(16),
238
+ name: 'CN=example.com, C=US, L=CA, O=example, ST=CA',
239
+ notBefore,
240
+ notAfter,
241
+ keys: keyPair,
242
+ extensions: [
243
+ new BasicConstraintsExtension(false, undefined, true)
244
+ ]
245
+ }, crypto);
246
+ if (this.getKeychain() != null) {
247
+ this.log.trace('storing TLS certificate');
248
+ await this.components.datastore.put(dsKey, uint8ArrayFromString(cert.toString('pem')));
249
+ }
250
+ else {
251
+ this.log('no keychain is configured so not storing TLS certificate since the private key will not be reused');
252
+ }
253
+ return cert;
254
+ }
255
+ getKeychain() {
256
+ try {
257
+ return this.components.keychain;
258
+ }
259
+ catch { }
260
+ }
261
+ }
262
+ function isTransportCertificate(obj) {
263
+ if (obj == null) {
264
+ return false;
265
+ }
266
+ return typeof obj.privateKey === 'string' && typeof obj.pem === 'string' && typeof obj.certhash === 'string';
96
267
  }
97
268
  //# sourceMappingURL=transport.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../src/private-to-public/transport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../../src/private-to-public/transport.ts"],"names":[],"mappings":"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"}
@@ -10,142 +10,144 @@ import * as sdp from './sdp.js';
10
10
  const CONNECTION_STATE_CHANGE_EVENT = isFirefox ? 'iceconnectionstatechange' : 'connectionstatechange';
11
11
  export async function connect(peerConnection, ufrag, options) {
12
12
  // create data channel for running the noise handshake. Once the data
13
- // channel is opened, the remote will initiate the noise handshake. This
13
+ // channel is opened, the listener will initiate the noise handshake. This
14
14
  // is used to confirm the identity of the peer.
15
15
  const handshakeDataChannel = peerConnection.createDataChannel('', { negotiated: true, id: 0 });
16
- if (options.role === 'client') {
17
- // the client has to set the local offer before the remote answer
18
- // Create offer and munge sdp with ufrag == pwd. This allows the remote to
19
- // respond to STUN messages without performing an actual SDP exchange.
20
- // This is because it can infer the passwd field by reading the USERNAME
21
- // attribute of the STUN message.
22
- options.log.trace('client creating local offer');
23
- const offerSdp = await peerConnection.createOffer();
24
- options.log.trace('client created local offer %s', offerSdp.sdp);
25
- const mungedOfferSdp = sdp.munge(offerSdp, ufrag);
26
- options.log.trace('client setting local offer %s', mungedOfferSdp.sdp);
27
- await peerConnection.setLocalDescription(mungedOfferSdp);
28
- const answerSdp = sdp.serverAnswerFromMultiaddr(options.remoteAddr, ufrag);
29
- options.log.trace('client setting server description %s', answerSdp.sdp);
30
- await peerConnection.setRemoteDescription(answerSdp);
31
- }
32
- else {
33
- // the server has to set the remote offer before the local answer
34
- const offerSdp = sdp.clientOfferFromMultiAddr(options.remoteAddr, ufrag);
35
- options.log.trace('server setting client %s %s', offerSdp.type, offerSdp.sdp);
36
- await peerConnection.setRemoteDescription(offerSdp);
37
- // Create offer and munge sdp with ufrag == pwd. This allows the remote to
38
- // respond to STUN messages without performing an actual SDP exchange.
39
- // This is because it can infer the passwd field by reading the USERNAME
40
- // attribute of the STUN message.
41
- options.log.trace('server creating local answer');
42
- const answerSdp = await peerConnection.createAnswer();
43
- options.log.trace('server created local answer');
44
- const mungedAnswerSdp = sdp.munge(answerSdp, ufrag);
45
- options.log.trace('server setting local description %s', answerSdp.sdp);
46
- await peerConnection.setLocalDescription(mungedAnswerSdp);
47
- }
48
- options.log.trace('%s wait for handshake channel to open', options.role);
49
- await raceEvent(handshakeDataChannel, 'open', options.signal);
50
- options.log.trace('%s handshake channel opened', options.role);
51
- if (options.role === 'server') {
52
- // now that the connection has been opened, add the remote's certhash to
53
- // it's multiaddr so we can complete the noise handshake
54
- const remoteFingerprint = peerConnection.remoteFingerprint()?.value ?? '';
55
- options.remoteAddr = options.remoteAddr.encapsulate(sdp.fingerprint2Ma(remoteFingerprint));
56
- }
57
- // Do noise handshake.
58
- // Set the Noise Prologue to libp2p-webrtc-noise:<FINGERPRINTS> before
59
- // starting the actual Noise handshake.
60
- // <FINGERPRINTS> is the concatenation of the of the two TLS fingerprints
61
- // of A (responder) and B (initiator) in their byte representation.
62
- const localFingerprint = sdp.getFingerprintFromSdp(peerConnection.localDescription?.sdp);
63
- if (localFingerprint == null) {
64
- throw new WebRTCTransportError('Could not get fingerprint from local description sdp');
65
- }
66
- options.log.trace('%s performing noise handshake', options.role);
67
- const noisePrologue = generateNoisePrologue(localFingerprint, options.remoteAddr, options.role);
68
- // Since we use the default crypto interface and do not use a static key
69
- // or early data, we pass in undefined for these parameters.
70
- const connectionEncrypter = noise({ prologueBytes: noisePrologue })(options);
71
- const wrappedChannel = createStream({
72
- channel: handshakeDataChannel,
73
- direction: 'inbound',
74
- logger: options.logger,
75
- ...(options.dataChannel ?? {})
76
- });
77
- const wrappedDuplex = {
78
- ...wrappedChannel,
79
- sink: wrappedChannel.sink.bind(wrappedChannel),
80
- source: (async function* () {
81
- for await (const list of wrappedChannel.source) {
82
- for (const buf of list) {
83
- yield buf;
84
- }
16
+ try {
17
+ if (options.role === 'client') {
18
+ // the client has to set the local offer before the remote answer
19
+ // Create offer and munge sdp with ufrag == pwd. This allows the remote to
20
+ // respond to STUN messages without performing an actual SDP exchange.
21
+ // This is because it can infer the passwd field by reading the USERNAME
22
+ // attribute of the STUN message.
23
+ options.log.trace('client creating local offer');
24
+ const offerSdp = await peerConnection.createOffer();
25
+ options.log.trace('client created local offer %s', offerSdp.sdp);
26
+ const mungedOfferSdp = sdp.munge(offerSdp, ufrag);
27
+ options.log.trace('client setting local offer %s', mungedOfferSdp.sdp);
28
+ await peerConnection.setLocalDescription(mungedOfferSdp);
29
+ const answerSdp = sdp.serverAnswerFromMultiaddr(options.remoteAddr, ufrag);
30
+ options.log.trace('client setting server description %s', answerSdp.sdp);
31
+ await peerConnection.setRemoteDescription(answerSdp);
32
+ }
33
+ else {
34
+ // the server has to set the remote offer before the local answer
35
+ const offerSdp = sdp.clientOfferFromMultiAddr(options.remoteAddr, ufrag);
36
+ options.log.trace('server setting client %s %s', offerSdp.type, offerSdp.sdp);
37
+ await peerConnection.setRemoteDescription(offerSdp);
38
+ // Create offer and munge sdp with ufrag == pwd. This allows the remote to
39
+ // respond to STUN messages without performing an actual SDP exchange.
40
+ // This is because it can infer the passwd field by reading the USERNAME
41
+ // attribute of the STUN message.
42
+ options.log.trace('server creating local answer');
43
+ const answerSdp = await peerConnection.createAnswer();
44
+ options.log.trace('server created local answer');
45
+ const mungedAnswerSdp = sdp.munge(answerSdp, ufrag);
46
+ options.log.trace('server setting local description %s', answerSdp.sdp);
47
+ await peerConnection.setLocalDescription(mungedAnswerSdp);
48
+ }
49
+ if (handshakeDataChannel.readyState !== 'open') {
50
+ options.log.trace('%s wait for handshake channel to open, starting status %s', options.role, handshakeDataChannel.readyState);
51
+ await raceEvent(handshakeDataChannel, 'open', options.signal);
52
+ }
53
+ options.log.trace('%s handshake channel opened', options.role);
54
+ if (options.role === 'server') {
55
+ // now that the connection has been opened, add the remote's certhash to
56
+ // it's multiaddr so we can complete the noise handshake
57
+ const remoteFingerprint = peerConnection.remoteFingerprint()?.value ?? '';
58
+ options.remoteAddr = options.remoteAddr.encapsulate(sdp.fingerprint2Ma(remoteFingerprint));
59
+ }
60
+ // Do noise handshake.
61
+ // Set the Noise Prologue to libp2p-webrtc-noise:<FINGERPRINTS> before
62
+ // starting the actual Noise handshake.
63
+ // <FINGERPRINTS> is the concatenation of the of the two TLS fingerprints
64
+ // of A (responder) and B (initiator) in their byte representation.
65
+ const localFingerprint = sdp.getFingerprintFromSdp(peerConnection.localDescription?.sdp);
66
+ if (localFingerprint == null) {
67
+ throw new WebRTCTransportError('Could not get fingerprint from local description sdp');
68
+ }
69
+ options.log.trace('%s performing noise handshake', options.role);
70
+ const noisePrologue = generateNoisePrologue(localFingerprint, options.remoteAddr, options.role);
71
+ // Since we use the default crypto interface and do not use a static key
72
+ // or early data, we pass in undefined for these parameters.
73
+ const connectionEncrypter = noise({ prologueBytes: noisePrologue })(options);
74
+ const handshakeStream = createStream({
75
+ channel: handshakeDataChannel,
76
+ direction: 'outbound',
77
+ handshake: true,
78
+ logger: options.logger,
79
+ ...(options.dataChannel ?? {})
80
+ });
81
+ // Creating the connection before completion of the noise
82
+ // handshake ensures that the stream opening callback is set up
83
+ const maConn = new WebRTCMultiaddrConnection(options, {
84
+ peerConnection,
85
+ remoteAddr: options.remoteAddr,
86
+ timeline: {
87
+ open: Date.now()
88
+ },
89
+ metrics: options.events
90
+ });
91
+ peerConnection.addEventListener(CONNECTION_STATE_CHANGE_EVENT, () => {
92
+ switch (peerConnection.connectionState) {
93
+ case 'failed':
94
+ case 'disconnected':
95
+ case 'closed':
96
+ maConn.close().catch((err) => {
97
+ options.log.error('error closing connection', err);
98
+ maConn.abort(err);
99
+ });
100
+ break;
101
+ default:
102
+ break;
85
103
  }
86
- }())
87
- };
88
- // Creating the connection before completion of the noise
89
- // handshake ensures that the stream opening callback is set up
90
- const maConn = new WebRTCMultiaddrConnection(options, {
91
- peerConnection,
92
- remoteAddr: options.remoteAddr,
93
- timeline: {
94
- open: Date.now()
95
- },
96
- metrics: options.events
97
- });
98
- peerConnection.addEventListener(CONNECTION_STATE_CHANGE_EVENT, () => {
99
- switch (peerConnection.connectionState) {
100
- case 'failed':
101
- case 'disconnected':
102
- case 'closed':
103
- maConn.close().catch((err) => {
104
- options.log.error('error closing connection', err);
105
- maConn.abort(err);
106
- });
107
- break;
108
- default:
109
- break;
104
+ });
105
+ // Track opened peer connection
106
+ options.events?.increment({ peer_connection: true });
107
+ const muxerFactory = new DataChannelMuxerFactory(options, {
108
+ peerConnection,
109
+ metrics: options.events,
110
+ dataChannelOptions: options.dataChannel
111
+ });
112
+ if (options.role === 'client') {
113
+ // For outbound connections, the remote is expected to start the noise
114
+ // handshake. Therefore, we need to secure an inbound noise connection
115
+ // from the server.
116
+ options.log.trace('%s secure inbound', options.role);
117
+ await connectionEncrypter.secureInbound(handshakeStream, {
118
+ remotePeer: options.remotePeerId,
119
+ signal: options.signal
120
+ });
121
+ options.log.trace('%s closing handshake datachannel', options.role);
122
+ handshakeDataChannel.close();
123
+ options.log.trace('%s upgrade outbound', options.role);
124
+ return await options.upgrader.upgradeOutbound(maConn, {
125
+ skipProtection: true,
126
+ skipEncryption: true,
127
+ muxerFactory,
128
+ signal: options.signal
129
+ });
110
130
  }
111
- });
112
- // Track opened peer connection
113
- options.events?.increment({ peer_connection: true });
114
- const muxerFactory = new DataChannelMuxerFactory(options, {
115
- peerConnection,
116
- metrics: options.events,
117
- dataChannelOptions: options.dataChannel
118
- });
119
- if (options.role === 'client') {
120
- // For outbound connections, the remote is expected to start the noise handshake.
121
- // Therefore, we need to secure an inbound noise connection from the remote.
122
- options.log.trace('%s secure inbound', options.role);
123
- await connectionEncrypter.secureInbound(wrappedDuplex, {
131
+ // For inbound connections, the server is are expected to start the noise
132
+ // handshake. Therefore, we need to secure an outbound noise connection from
133
+ // the client.
134
+ options.log.trace('%s secure outbound', options.role);
135
+ const result = await connectionEncrypter.secureOutbound(handshakeStream, {
124
136
  remotePeer: options.remotePeerId,
125
137
  signal: options.signal
126
138
  });
127
- options.log.trace('%s upgrade outbound', options.role);
128
- return options.upgrader.upgradeOutbound(maConn, {
139
+ maConn.remoteAddr = maConn.remoteAddr.encapsulate(`/p2p/${result.remotePeer}`);
140
+ options.log.trace('%s upgrade inbound', options.role);
141
+ await options.upgrader.upgradeInbound(maConn, {
129
142
  skipProtection: true,
130
143
  skipEncryption: true,
131
144
  muxerFactory,
132
145
  signal: options.signal
133
146
  });
134
147
  }
135
- // For inbound connections, we are expected to start the noise handshake.
136
- // Therefore, we need to secure an outbound noise connection from the remote.
137
- options.log.trace('%s secure outbound', options.role);
138
- const result = await connectionEncrypter.secureOutbound(wrappedDuplex, {
139
- remotePeer: options.remotePeerId,
140
- signal: options.signal
141
- });
142
- maConn.remoteAddr = maConn.remoteAddr.encapsulate(`/p2p/${result.remotePeer}`);
143
- options.log.trace('%s upgrade inbound', options.role);
144
- await options.upgrader.upgradeInbound(maConn, {
145
- skipProtection: true,
146
- skipEncryption: true,
147
- muxerFactory,
148
- signal: options.signal
149
- });
148
+ catch (err) {
149
+ handshakeDataChannel.close();
150
+ throw err;
151
+ }
150
152
  }
151
153
  //# sourceMappingURL=connect.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"connect.js","sourceRoot":"","sources":["../../../../src/private-to-public/utils/connect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,yBAAyB,CAAA;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AACtC,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AACrD,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAA;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAA;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AACzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,8BAA8B,CAAA;AACpE,OAAO,KAAK,GAAG,MAAM,UAAU,CAAA;AA6B/B,MAAM,6BAA6B,GAAG,SAAS,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,uBAAuB,CAAA;AAItG,MAAM,CAAC,KAAK,UAAU,OAAO,CAAE,cAAuC,EAAE,KAAa,EAAE,OAAuB;IAC5G,qEAAqE;IACrE,wEAAwE;IACxE,+CAA+C;IAC/C,MAAM,oBAAoB,GAAG,cAAc,CAAC,iBAAiB,CAAC,EAAE,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAA;IAE9F,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC9B,iEAAiE;QAEjE,0EAA0E;QAC1E,sEAAsE;QACtE,wEAAwE;QACxE,iCAAiC;QACjC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAA;QAChD,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,WAAW,EAAE,CAAA;QACnD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,+BAA+B,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAA;QAChE,MAAM,cAAc,GAAG,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAA;QACjD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,+BAA+B,EAAE,cAAc,CAAC,GAAG,CAAC,CAAA;QACtE,MAAM,cAAc,CAAC,mBAAmB,CAAC,cAAc,CAAC,CAAA;QAExD,MAAM,SAAS,GAAG,GAAG,CAAC,yBAAyB,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,CAAA;QAC1E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,sCAAsC,EAAE,SAAS,CAAC,GAAG,CAAC,CAAA;QACxE,MAAM,cAAc,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAA;IACtD,CAAC;SAAM,CAAC;QACN,iEAAiE;QACjE,MAAM,QAAQ,GAAG,GAAG,CAAC,wBAAwB,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,CAAA;QACxE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,6BAA6B,EAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAA;QAC7E,MAAM,cAAc,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAA;QAEnD,0EAA0E;QAC1E,sEAAsE;QACtE,wEAAwE;QACxE,iCAAiC;QACjC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAA;QACjD,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,YAAY,EAAE,CAAA;QACrD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAA;QAChD,MAAM,eAAe,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;QACnD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,qCAAqC,EAAE,SAAS,CAAC,GAAG,CAAC,CAAA;QACvE,MAAM,cAAc,CAAC,mBAAmB,CAAC,eAAe,CAAC,CAAA;IAC3D,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,uCAAuC,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;IACxE,MAAM,SAAS,CAAC,oBAAoB,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAA;IAE7D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,6BAA6B,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;IAE9D,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC9B,wEAAwE;QACxE,wDAAwD;QACxD,MAAM,iBAAiB,GAAG,cAAc,CAAC,iBAAiB,EAAE,EAAE,KAAK,IAAI,EAAE,CAAA;QACzE,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC,CAAA;IAC5F,CAAC;IAED,sBAAsB;IACtB,sEAAsE;IACtE,uCAAuC;IACvC,yEAAyE;IACzE,mEAAmE;IACnE,MAAM,gBAAgB,GAAG,GAAG,CAAC,qBAAqB,CAAC,cAAc,CAAC,gBAAgB,EAAE,GAAG,CAAC,CAAA;IAExF,IAAI,gBAAgB,IAAI,IAAI,EAAE,CAAC;QAC7B,MAAM,IAAI,oBAAoB,CAAC,sDAAsD,CAAC,CAAA;IACxF,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,+BAA+B,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;IAChE,MAAM,aAAa,GAAG,qBAAqB,CAAC,gBAAgB,EAAE,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;IAE/F,wEAAwE;IACxE,4DAA4D;IAC5D,MAAM,mBAAmB,GAAG,KAAK,CAAC,EAAE,aAAa,EAAE,aAAa,EAAE,CAAC,CAAC,OAAO,CAAC,CAAA;IAE5E,MAAM,cAAc,GAAG,YAAY,CAAC;QAClC,OAAO,EAAE,oBAAoB;QAC7B,SAAS,EAAE,SAAS;QACpB,MAAM,EAAE,OAAO,CAAC,MAAM;QACtB,GAAG,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC;KAC/B,CAAC,CAAA;IACF,MAAM,aAAa,GAAG;QACpB,GAAG,cAAc;QACjB,IAAI,EAAE,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC;QAC9C,MAAM,EAAE,CAAC,KAAK,SAAU,CAAC;YACvB,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,cAAc,CAAC,MAAM,EAAE,CAAC;gBAC/C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;oBACvB,MAAM,GAAG,CAAA;gBACX,CAAC;YACH,CAAC;QACH,CAAC,EAAE,CAAC;KACL,CAAA;IAED,yDAAyD;IACzD,+DAA+D;IAC/D,MAAM,MAAM,GAAG,IAAI,yBAAyB,CAAC,OAAO,EAAE;QACpD,cAAc;QACd,UAAU,EAAE,OAAO,CAAC,UAAU;QAC9B,QAAQ,EAAE;YACR,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE;SACjB;QACD,OAAO,EAAE,OAAO,CAAC,MAAM;KACxB,CAAC,CAAA;IAEF,cAAc,CAAC,gBAAgB,CAAC,6BAA6B,EAAE,GAAG,EAAE;QAClE,QAAQ,cAAc,CAAC,eAAe,EAAE,CAAC;YACvC,KAAK,QAAQ,CAAC;YACd,KAAK,cAAc,CAAC;YACpB,KAAK,QAAQ;gBACX,MAAM,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;oBAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,0BAA0B,EAAE,GAAG,CAAC,CAAA;oBAClD,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;gBACnB,CAAC,CAAC,CAAA;gBACF,MAAK;YACP;gBACE,MAAK;QACT,CAAC;IACH,CAAC,CAAC,CAAA;IAEF,+BAA+B;IAC/B,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAA;IAEpD,MAAM,YAAY,GAAG,IAAI,uBAAuB,CAAC,OAAO,EAAE;QACxD,cAAc;QACd,OAAO,EAAE,OAAO,CAAC,MAAM;QACvB,kBAAkB,EAAE,OAAO,CAAC,WAAW;KACxC,CAAC,CAAA;IAEF,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC9B,iFAAiF;QACjF,4EAA4E;QAC5E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,mBAAmB,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;QACpD,MAAM,mBAAmB,CAAC,aAAa,CAAC,aAAa,EAAE;YACrD,UAAU,EAAE,OAAO,CAAC,YAAY;YAChC,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAA;QAEF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,qBAAqB,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;QACtD,OAAO,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,MAAM,EAAE;YAC9C,cAAc,EAAE,IAAI;YACpB,cAAc,EAAE,IAAI;YACpB,YAAY;YACZ,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAA;IACJ,CAAC;IAED,yEAAyE;IACzE,6EAA6E;IAC7E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,oBAAoB,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;IACrD,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,cAAc,CAAC,aAAa,EAAE;QACrE,UAAU,EAAE,OAAO,CAAC,YAAY;QAChC,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAA;IACF,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,QAAQ,MAAM,CAAC,UAAU,EAAE,CAAC,CAAA;IAE9E,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,oBAAoB,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;IAErD,MAAM,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC,MAAM,EAAE;QAC5C,cAAc,EAAE,IAAI;QACpB,cAAc,EAAE,IAAI;QACpB,YAAY;QACZ,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAA;AACJ,CAAC"}
1
+ {"version":3,"file":"connect.js","sourceRoot":"","sources":["../../../../src/private-to-public/utils/connect.ts"],"names":[],"mappings":"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"}