libp2p 0.46.4 → 0.46.5

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 (50) hide show
  1. package/dist/index.min.js +22 -22
  2. package/dist/src/connection-manager/auto-dial.d.ts +2 -0
  3. package/dist/src/connection-manager/auto-dial.d.ts.map +1 -1
  4. package/dist/src/connection-manager/auto-dial.js +20 -5
  5. package/dist/src/connection-manager/auto-dial.js.map +1 -1
  6. package/dist/src/connection-manager/constants.browser.d.ts +18 -0
  7. package/dist/src/connection-manager/constants.browser.d.ts.map +1 -0
  8. package/dist/src/connection-manager/constants.browser.js +18 -0
  9. package/dist/src/connection-manager/constants.browser.js.map +1 -0
  10. package/dist/src/connection-manager/constants.d.ts +1 -36
  11. package/dist/src/connection-manager/constants.d.ts.map +1 -1
  12. package/dist/src/connection-manager/constants.defaults.d.ts +50 -0
  13. package/dist/src/connection-manager/constants.defaults.d.ts.map +1 -0
  14. package/dist/src/connection-manager/constants.defaults.js +50 -0
  15. package/dist/src/connection-manager/constants.defaults.js.map +1 -0
  16. package/dist/src/connection-manager/constants.js +1 -36
  17. package/dist/src/connection-manager/constants.js.map +1 -1
  18. package/dist/src/connection-manager/dial-queue.d.ts.map +1 -1
  19. package/dist/src/connection-manager/dial-queue.js +16 -2
  20. package/dist/src/connection-manager/dial-queue.js.map +1 -1
  21. package/dist/src/connection-manager/index.d.ts +6 -4
  22. package/dist/src/connection-manager/index.d.ts.map +1 -1
  23. package/dist/src/connection-manager/index.js +1 -1
  24. package/dist/src/connection-manager/index.js.map +1 -1
  25. package/dist/src/dcutr/dcutr.d.ts +48 -0
  26. package/dist/src/dcutr/dcutr.d.ts.map +1 -0
  27. package/dist/src/dcutr/dcutr.js +335 -0
  28. package/dist/src/dcutr/dcutr.js.map +1 -0
  29. package/dist/src/dcutr/index.d.ts +92 -0
  30. package/dist/src/dcutr/index.d.ts.map +1 -0
  31. package/dist/src/dcutr/index.js +63 -0
  32. package/dist/src/dcutr/index.js.map +1 -0
  33. package/dist/src/dcutr/pb/message.d.ts +20 -0
  34. package/dist/src/dcutr/pb/message.d.ts.map +1 -0
  35. package/dist/src/dcutr/pb/message.js +77 -0
  36. package/dist/src/dcutr/pb/message.js.map +1 -0
  37. package/dist/src/version.d.ts +1 -1
  38. package/dist/src/version.js +1 -1
  39. package/package.json +18 -12
  40. package/src/connection-manager/auto-dial.ts +26 -5
  41. package/src/connection-manager/constants.browser.ts +21 -0
  42. package/src/connection-manager/constants.defaults.ts +59 -0
  43. package/src/connection-manager/constants.ts +1 -44
  44. package/src/connection-manager/dial-queue.ts +17 -2
  45. package/src/connection-manager/index.ts +8 -6
  46. package/src/dcutr/dcutr.ts +406 -0
  47. package/src/dcutr/index.ts +102 -0
  48. package/src/dcutr/pb/message.proto +12 -0
  49. package/src/dcutr/pb/message.ts +96 -0
  50. package/src/version.ts +1 -1
@@ -0,0 +1,406 @@
1
+ import { CodeError } from '@libp2p/interface/errors'
2
+ import { logger } from '@libp2p/logger'
3
+ import { type Multiaddr, multiaddr } from '@multiformats/multiaddr'
4
+ import { Circuit, IP, DNS } from '@multiformats/multiaddr-matcher'
5
+ import delay from 'delay'
6
+ import { pbStream } from 'it-protobuf-stream'
7
+ import isPrivate from 'private-ip'
8
+ import { codes } from '../errors.js'
9
+ import { HolePunch } from './pb/message.js'
10
+ import { multicodec } from './index.js'
11
+ import type { DCUtRServiceComponents, DCUtRServiceInit } from './index.js'
12
+ import type { Connection, Stream } from '@libp2p/interface/connection'
13
+ import type { PeerStore } from '@libp2p/interface/peer-store'
14
+ import type { Startable } from '@libp2p/interface/startable'
15
+ import type { AddressManager } from '@libp2p/interface-internal/address-manager'
16
+ import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
17
+ import type { Registrar } from '@libp2p/interface-internal/registrar'
18
+ import type { TransportManager } from '@libp2p/interface-internal/src/transport-manager/index.js'
19
+
20
+ const log = logger('libp2p:dcutr')
21
+
22
+ // https://github.com/libp2p/specs/blob/master/relay/DCUtR.md#rpc-messages
23
+ const MAX_DCUTR_MESSAGE_SIZE = 1024 * 4
24
+ // ensure the dial has a high priority to jump to the head of the dial queue
25
+ const DCUTR_DIAL_PRIORITY = 100
26
+
27
+ const defaultValues = {
28
+ // https://github.com/libp2p/go-libp2p/blob/8d2e54e1637041d5cf4fac1e531287560bd1f4ac/p2p/protocol/holepunch/holepuncher.go#L27
29
+ timeout: 5000,
30
+ // https://github.com/libp2p/go-libp2p/blob/8d2e54e1637041d5cf4fac1e531287560bd1f4ac/p2p/protocol/holepunch/holepuncher.go#L28
31
+ retries: 3,
32
+ maxInboundStreams: 1,
33
+ maxOutboundStreams: 1
34
+ }
35
+
36
+ export class DefaultDCUtRService implements Startable {
37
+ private started: boolean
38
+ private readonly timeout: number
39
+ private readonly retries: number
40
+ private readonly maxInboundStreams: number
41
+ private readonly maxOutboundStreams: number
42
+ private readonly peerStore: PeerStore
43
+ private readonly registrar: Registrar
44
+ private readonly connectionManager: ConnectionManager
45
+ private readonly addressManager: AddressManager
46
+ private readonly transportManager: TransportManager
47
+ private topologyId?: string
48
+
49
+ constructor (components: DCUtRServiceComponents, init: DCUtRServiceInit) {
50
+ this.started = false
51
+ this.peerStore = components.peerStore
52
+ this.registrar = components.registrar
53
+ this.addressManager = components.addressManager
54
+ this.connectionManager = components.connectionManager
55
+ this.transportManager = components.transportManager
56
+
57
+ this.timeout = init.timeout ?? defaultValues.timeout
58
+ this.retries = init.retries ?? defaultValues.retries
59
+ this.maxInboundStreams = init.maxInboundStreams ?? defaultValues.maxInboundStreams
60
+ this.maxOutboundStreams = init.maxOutboundStreams ?? defaultValues.maxOutboundStreams
61
+ }
62
+
63
+ isStarted (): boolean {
64
+ return this.started
65
+ }
66
+
67
+ async start (): Promise<void> {
68
+ if (this.started) {
69
+ return
70
+ }
71
+
72
+ // register for notifications of when peers that support DCUtR connect
73
+ // nb. requires the identify service to be enabled
74
+ this.topologyId = await this.registrar.register(multicodec, {
75
+ onConnect: (peerId, connection) => {
76
+ if (!connection.transient) {
77
+ // the connection is already direct, no upgrade is required
78
+ return
79
+ }
80
+
81
+ // the inbound peer starts the connection upgrade
82
+ if (connection.direction !== 'inbound') {
83
+ return
84
+ }
85
+
86
+ this.upgradeInbound(connection)
87
+ .catch(err => {
88
+ log.error('error during outgoing DCUtR attempt', err)
89
+ })
90
+ }
91
+ })
92
+
93
+ await this.registrar.handle(multicodec, (data) => {
94
+ void this.handleIncomingUpgrade(data.stream, data.connection).catch(err => {
95
+ log.error('error during incoming DCUtR attempt', err)
96
+ data.stream.abort(err)
97
+ })
98
+ }, {
99
+ maxInboundStreams: this.maxInboundStreams,
100
+ maxOutboundStreams: this.maxOutboundStreams,
101
+ runOnTransientConnection: true
102
+ })
103
+
104
+ this.started = true
105
+ }
106
+
107
+ async stop (): Promise<void> {
108
+ await this.registrar.unhandle(multicodec)
109
+
110
+ if (this.topologyId != null) {
111
+ this.registrar.unregister(this.topologyId)
112
+ }
113
+
114
+ this.started = false
115
+ }
116
+
117
+ /**
118
+ * Perform the inbound connection upgrade as B
119
+ *
120
+ * @see https://github.com/libp2p/specs/blob/master/relay/DCUtR.md#the-protocol
121
+ */
122
+ async upgradeInbound (relayedConnection: Connection): Promise<void> {
123
+ // Upon observing the new connection, the inbound peer (here B) checks the
124
+ // addresses advertised by A via identify.
125
+ //
126
+ // If that set includes public addresses, then A may be reachable by a direct
127
+ // connection, in which case B attempts a unilateral connection upgrade by
128
+ // initiating a direct connection to A.
129
+ if (await this.attemptUnilateralConnectionUpgrade(relayedConnection)) {
130
+ return
131
+ }
132
+
133
+ let stream: Stream | undefined
134
+
135
+ for (let i = 0; i < this.retries; i++) {
136
+ const options = {
137
+ signal: AbortSignal.timeout(this.timeout)
138
+ }
139
+
140
+ try {
141
+ // 1. B opens a stream to A using the /libp2p/dcutr protocol.
142
+ stream = await relayedConnection.newStream([multicodec], {
143
+ signal: options.signal,
144
+ runOnTransientConnection: true
145
+ })
146
+
147
+ const pb = pbStream(stream, {
148
+ maxDataLength: MAX_DCUTR_MESSAGE_SIZE
149
+ }).pb(HolePunch)
150
+
151
+ // 2. B sends to A a Connect message containing its observed (and
152
+ // possibly predicted) addresses from identify and starts a timer
153
+ // to measure RTT of the relay connection.
154
+ log('B sending connect to %p', relayedConnection.remotePeer)
155
+ const connectTimer = Date.now()
156
+ await pb.write({
157
+ type: HolePunch.Type.CONNECT,
158
+ observedAddresses: this.addressManager.getAddresses().map(ma => ma.bytes)
159
+ }, options)
160
+
161
+ log('B receiving connect from %p', relayedConnection.remotePeer)
162
+ // 4. Upon receiving the Connect, B sends a Sync message
163
+ const connect = await pb.read(options)
164
+
165
+ if (connect.type !== HolePunch.Type.CONNECT) {
166
+ log('A sent wrong message type')
167
+ throw new CodeError('DCUtR message type was incorrect', codes.ERR_INVALID_MESSAGE)
168
+ }
169
+
170
+ const multiaddrs = this.getDialableMultiaddrs(connect.observedAddresses)
171
+
172
+ if (multiaddrs.length === 0) {
173
+ log('A did not have any dialable multiaddrs')
174
+ throw new CodeError('DCUtR connect message had no multiaddrs', codes.ERR_INVALID_MESSAGE)
175
+ }
176
+
177
+ const rtt = Date.now() - connectTimer
178
+
179
+ log('A sending sync, rtt %dms', rtt)
180
+ await pb.write({
181
+ type: HolePunch.Type.SYNC,
182
+ observedAddresses: []
183
+ }, options)
184
+
185
+ log('A waiting for half RTT')
186
+ // ..and starts a timer for half the RTT measured from the time between
187
+ // sending the initial Connect and receiving the response
188
+ await delay(rtt / 2)
189
+
190
+ // TODO: when we have a QUIC transport, the dial step is different - for
191
+ // now we only have tcp support
192
+ // https://github.com/libp2p/specs/blob/master/relay/DCUtR.md#the-protocol
193
+
194
+ log('B dialing', multiaddrs)
195
+ // Upon expiry of the timer, B dials the address to A.
196
+ const conn = await this.connectionManager.openConnection(multiaddrs, {
197
+ signal: options.signal,
198
+ priority: DCUTR_DIAL_PRIORITY
199
+ })
200
+
201
+ log('DCUtR to %p succeeded to address %a, closing relayed connection', relayedConnection.remotePeer, conn.remoteAddr)
202
+ await relayedConnection.close(options)
203
+
204
+ break
205
+ } catch (err: any) {
206
+ log.error('error while attempting DCUtR on attempt %d of %d', i + 1, this.retries, err)
207
+ stream?.abort(err)
208
+
209
+ if (i === this.retries) {
210
+ throw err
211
+ }
212
+ } finally {
213
+ if (stream != null) {
214
+ await stream.close(options)
215
+ }
216
+ }
217
+ }
218
+ }
219
+
220
+ /**
221
+ * This is performed when A has dialed B via a relay but A also has a public
222
+ * address that B can dial directly
223
+ */
224
+ async attemptUnilateralConnectionUpgrade (relayedConnection: Connection): Promise<boolean> {
225
+ // Upon observing the new connection, the inbound peer (here B) checks the
226
+ // addresses advertised by A via identify.
227
+ const peerInfo = await this.peerStore.get(relayedConnection.remotePeer)
228
+
229
+ // If that set includes public addresses, then A may be reachable by a direct
230
+ // connection, in which case B attempts a unilateral connection upgrade by
231
+ // initiating a direct connection to A.
232
+ const publicAddresses = peerInfo.addresses
233
+ .map(address => {
234
+ const ma = address.multiaddr
235
+
236
+ // ensure all multiaddrs have the peer id
237
+ if (ma.getPeerId() == null) {
238
+ return ma.encapsulate(`/p2p/${relayedConnection.remotePeer}`)
239
+ }
240
+
241
+ return ma
242
+ })
243
+ .filter(ma => {
244
+ return this.isPublicAndDialable(ma)
245
+ })
246
+
247
+ if (publicAddresses.length > 0) {
248
+ const signal = AbortSignal.timeout(this.timeout)
249
+
250
+ try {
251
+ log('attempting unilateral connection upgrade to %a', publicAddresses)
252
+
253
+ // force-dial the multiaddr(s), otherwise `connectionManager.openConnection`
254
+ // will return the existing relayed connection
255
+ const connection = await this.connectionManager.openConnection(publicAddresses, {
256
+ signal,
257
+ force: true
258
+ })
259
+
260
+ if (connection.transient) {
261
+ throw new Error('Could not open a new, non-transient, connection')
262
+ }
263
+
264
+ log('unilateral connection upgrade to %p succeeded via %a, closing relayed connection', relayedConnection.remotePeer, connection.remoteAddr)
265
+ await relayedConnection.close()
266
+
267
+ return true
268
+ } catch (err) {
269
+ log.error('unilateral connection upgrade to %p on addresses %a failed', relayedConnection.remotePeer, publicAddresses, err)
270
+ }
271
+ } else {
272
+ log('peer %p has no public addresses, not attempting unilateral connection upgrade', relayedConnection.remotePeer)
273
+ }
274
+
275
+ // no public addresses or failed to dial public addresses
276
+ return false
277
+ }
278
+
279
+ /**
280
+ * Perform the connection upgrade as A
281
+ *
282
+ * @see https://github.com/libp2p/specs/blob/master/relay/DCUtR.md#the-protocol
283
+ */
284
+ async handleIncomingUpgrade (stream: Stream, relayedConnection: Connection): Promise<void> {
285
+ const options = {
286
+ signal: AbortSignal.timeout(this.timeout)
287
+ }
288
+
289
+ try {
290
+ const pb = pbStream(stream, {
291
+ maxDataLength: MAX_DCUTR_MESSAGE_SIZE
292
+ }).pb(HolePunch)
293
+
294
+ log('A receiving connect')
295
+ // 3. Upon receiving the Connect, A responds back with a Connect message
296
+ // containing its observed (and possibly predicted) addresses.
297
+ const connect = await pb.read(options)
298
+
299
+ if (connect.type !== HolePunch.Type.CONNECT) {
300
+ log('B sent wrong message type')
301
+ throw new CodeError('DCUtR message type was incorrect', codes.ERR_INVALID_MESSAGE)
302
+ }
303
+
304
+ if (connect.observedAddresses.length === 0) {
305
+ log('B sent no multiaddrs')
306
+ throw new CodeError('DCUtR connect message had no multiaddrs', codes.ERR_INVALID_MESSAGE)
307
+ }
308
+
309
+ const multiaddrs = this.getDialableMultiaddrs(connect.observedAddresses)
310
+
311
+ if (multiaddrs.length === 0) {
312
+ log('B had no dialable multiaddrs')
313
+ throw new CodeError('DCUtR connect message had no dialable multiaddrs', codes.ERR_INVALID_MESSAGE)
314
+ }
315
+
316
+ log('A sending connect')
317
+ await pb.write({
318
+ type: HolePunch.Type.CONNECT,
319
+ observedAddresses: this.addressManager.getAddresses().map(ma => ma.bytes)
320
+ })
321
+
322
+ log('A receiving sync')
323
+ const sync = await pb.read(options)
324
+
325
+ if (sync.type !== HolePunch.Type.SYNC) {
326
+ throw new CodeError('DCUtR message type was incorrect', codes.ERR_INVALID_MESSAGE)
327
+ }
328
+
329
+ // TODO: when we have a QUIC transport, the dial step is different - for
330
+ // now we only have tcp support
331
+ // https://github.com/libp2p/specs/blob/master/relay/DCUtR.md#the-protocol
332
+
333
+ // Upon receiving the Sync, A immediately dials the address to B
334
+ log('A dialing', multiaddrs)
335
+ const connection = await this.connectionManager.openConnection(multiaddrs, {
336
+ signal: options.signal,
337
+ priority: DCUTR_DIAL_PRIORITY,
338
+ force: true
339
+ })
340
+
341
+ log('DCUtR to %p succeeded via %a, closing relayed connection', relayedConnection.remotePeer, connection.remoteAddr)
342
+ await relayedConnection.close(options)
343
+ } catch (err: any) {
344
+ log.error('incoming DCUtR from %p failed', relayedConnection.remotePeer, err)
345
+ stream.abort(err)
346
+ } finally {
347
+ await stream.close(options)
348
+ }
349
+ }
350
+
351
+ /**
352
+ * Takes the `addr` and converts it to a Multiaddr if possible
353
+ */
354
+ getDialableMultiaddrs (addrs: Array<Uint8Array | string | null | undefined>): Multiaddr[] {
355
+ const output = []
356
+
357
+ for (const addr of addrs) {
358
+ if (addr == null || addr.length === 0) {
359
+ continue
360
+ }
361
+
362
+ try {
363
+ const ma = multiaddr(addr)
364
+
365
+ if (!this.isPublicAndDialable(ma)) {
366
+ continue
367
+ }
368
+
369
+ output.push(ma)
370
+ } catch {}
371
+ }
372
+
373
+ return output
374
+ }
375
+
376
+ /**
377
+ * Returns true if the passed multiaddr is public, not relayed and we have a
378
+ * transport that can dial it
379
+ */
380
+ isPublicAndDialable (ma: Multiaddr): boolean {
381
+ // ignore circuit relay
382
+ if (Circuit.matches(ma)) {
383
+ return false
384
+ }
385
+
386
+ // dns addresses are probably public?
387
+ if (DNS.matches(ma)) {
388
+ return true
389
+ }
390
+
391
+ // ensure we have only IPv4/IPv6 addresses
392
+ if (!IP.matches(ma)) {
393
+ return false
394
+ }
395
+
396
+ const transport = this.transportManager.transportForMultiaddr(ma)
397
+
398
+ if (transport == null) {
399
+ return false
400
+ }
401
+
402
+ const options = ma.toOptions()
403
+
404
+ return isPrivate(options.host) === false
405
+ }
406
+ }
@@ -0,0 +1,102 @@
1
+ /**
2
+ * @packageDocumentation
3
+ *
4
+ * Direct Connection Upgrade through Relay (DCUtR) is a protocol that allows two
5
+ * nodes to connect to each other who would otherwise be prevented doing so due
6
+ * to being behind NATed connections or firewalls.
7
+ *
8
+ * The protocol involves making a relayed connection between the two peers and
9
+ * using the relay to synchronise connection timings so that they dial each other
10
+ * at precisely the same moment.
11
+ *
12
+ * @example
13
+ *
14
+ * ```ts
15
+ * import { createLibp2p } from 'libp2p'
16
+ * import { circuitRelayTransport } from 'libp2p/circuit-relay'
17
+ * import { tcp } from '@libp2p/tcp'
18
+ * import { identifyService } from 'libp2p/identify'
19
+ * import { dCUtRService } from 'libp2p/dcutr'
20
+ *
21
+ * const node = await createLibp2p({
22
+ * transports: [
23
+ * circuitRelayTransport(),
24
+ * tcp()
25
+ * ],
26
+ * services: {
27
+ * identify: identifyService(),
28
+ * dcutr: dcutrService()
29
+ * }
30
+ * })
31
+ *
32
+ * // QmTarget is a peer that is behind a NAT, supports TCP and has a relay
33
+ * // reservation
34
+ * await node.dial('/ip4/.../p2p/QmRelay/p2p-circuit/p2p/QmTarget')
35
+ *
36
+ * // after a while the connection should automatically get upgraded to a
37
+ * // direct connection (e.g. non-transient)
38
+ * while (true) {
39
+ * const connections = node.getConnections()
40
+ *
41
+ * if (connections.find(conn => conn.transient === false)) {
42
+ * console.info('have direct connection')
43
+ * break
44
+ * } else {
45
+ * console.info('have relayed connection')
46
+ *
47
+ * // wait a few seconds to see if it's succeeded yet
48
+ * await new Promise((resolve) => {
49
+ * setTimeout(() => resolve(), 5000)
50
+ * })
51
+ * }
52
+ * }
53
+ * ```
54
+ */
55
+
56
+ import { DefaultDCUtRService } from './dcutr.js'
57
+ import type { PeerStore } from '@libp2p/interface/peer-store'
58
+ import type { AddressManager } from '@libp2p/interface-internal/address-manager'
59
+ import type { ConnectionManager } from '@libp2p/interface-internal/connection-manager'
60
+ import type { Registrar } from '@libp2p/interface-internal/registrar'
61
+ import type { TransportManager } from '@libp2p/interface-internal/transport-manager'
62
+
63
+ export interface DCUtRServiceInit {
64
+ /**
65
+ * How long we should wait for the connection upgrade to complete (default: 5s)
66
+ */
67
+ timeout?: number
68
+
69
+ /**
70
+ * How many times to retry the connection upgrade (default: 3)
71
+ */
72
+ retries?: number
73
+
74
+ /**
75
+ * How many simultaneous inbound DCUtR protocol streams to allow on each
76
+ * connection (default: 1)
77
+ */
78
+ maxInboundStreams?: number
79
+
80
+ /**
81
+ * How many simultaneous outbound DCUtR protocol streams to allow on each
82
+ * connection (default: 1)
83
+ */
84
+ maxOutboundStreams?: number
85
+ }
86
+
87
+ export interface DCUtRServiceComponents {
88
+ peerStore: PeerStore
89
+ connectionManager: ConnectionManager
90
+ registrar: Registrar
91
+ addressManager: AddressManager
92
+ transportManager: TransportManager
93
+ }
94
+
95
+ /**
96
+ * The DCUtR protocol
97
+ */
98
+ export const multicodec = '/libp2p/dcutr'
99
+
100
+ export function dcutrService (init: DCUtRServiceInit = {}): (components: DCUtRServiceComponents) => unknown {
101
+ return (components) => new DefaultDCUtRService(components, init)
102
+ }
@@ -0,0 +1,12 @@
1
+ syntax = "proto3";
2
+
3
+ message HolePunch {
4
+ enum Type {
5
+ UNUSED = 0;
6
+ CONNECT = 100;
7
+ SYNC = 300;
8
+ }
9
+
10
+ optional Type type = 1;
11
+ repeated bytes observed_addresses = 2;
12
+ }
@@ -0,0 +1,96 @@
1
+ /* eslint-disable import/export */
2
+ /* eslint-disable complexity */
3
+ /* eslint-disable @typescript-eslint/no-namespace */
4
+ /* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
5
+ /* eslint-disable @typescript-eslint/no-empty-interface */
6
+
7
+ import { enumeration, encodeMessage, decodeMessage, message } from 'protons-runtime'
8
+ import type { Codec } from 'protons-runtime'
9
+ import type { Uint8ArrayList } from 'uint8arraylist'
10
+
11
+ export interface HolePunch {
12
+ type?: HolePunch.Type
13
+ observedAddresses: Uint8Array[]
14
+ }
15
+
16
+ export namespace HolePunch {
17
+ export enum Type {
18
+ UNUSED = 'UNUSED',
19
+ CONNECT = 'CONNECT',
20
+ SYNC = 'SYNC'
21
+ }
22
+
23
+ enum __TypeValues {
24
+ UNUSED = 0,
25
+ CONNECT = 100,
26
+ SYNC = 300
27
+ }
28
+
29
+ export namespace Type {
30
+ export const codec = (): Codec<Type> => {
31
+ return enumeration<Type>(__TypeValues)
32
+ }
33
+ }
34
+
35
+ let _codec: Codec<HolePunch>
36
+
37
+ export const codec = (): Codec<HolePunch> => {
38
+ if (_codec == null) {
39
+ _codec = message<HolePunch>((obj, w, opts = {}) => {
40
+ if (opts.lengthDelimited !== false) {
41
+ w.fork()
42
+ }
43
+
44
+ if (obj.type != null) {
45
+ w.uint32(8)
46
+ HolePunch.Type.codec().encode(obj.type, w)
47
+ }
48
+
49
+ if (obj.observedAddresses != null) {
50
+ for (const value of obj.observedAddresses) {
51
+ w.uint32(18)
52
+ w.bytes(value)
53
+ }
54
+ }
55
+
56
+ if (opts.lengthDelimited !== false) {
57
+ w.ldelim()
58
+ }
59
+ }, (reader, length) => {
60
+ const obj: any = {
61
+ observedAddresses: []
62
+ }
63
+
64
+ const end = length == null ? reader.len : reader.pos + length
65
+
66
+ while (reader.pos < end) {
67
+ const tag = reader.uint32()
68
+
69
+ switch (tag >>> 3) {
70
+ case 1:
71
+ obj.type = HolePunch.Type.codec().decode(reader)
72
+ break
73
+ case 2:
74
+ obj.observedAddresses.push(reader.bytes())
75
+ break
76
+ default:
77
+ reader.skipType(tag & 7)
78
+ break
79
+ }
80
+ }
81
+
82
+ return obj
83
+ })
84
+ }
85
+
86
+ return _codec
87
+ }
88
+
89
+ export const encode = (obj: Partial<HolePunch>): Uint8Array => {
90
+ return encodeMessage(obj, HolePunch.codec())
91
+ }
92
+
93
+ export const decode = (buf: Uint8Array | Uint8ArrayList): HolePunch => {
94
+ return decodeMessage(buf, HolePunch.codec())
95
+ }
96
+ }
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
- export const version = '0.46.4'
1
+ export const version = '0.46.5'
2
2
  export const name = 'libp2p'