@streamr/dht 0.0.1-tatum.1 → 0.0.1-tatum.2

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 (64) hide show
  1. package/dist/src/connection/ConnectionManager.d.ts +6 -0
  2. package/dist/src/connection/ConnectionManager.js +6 -3
  3. package/dist/src/connection/ConnectionManager.js.map +1 -1
  4. package/dist/src/connection/ConnectivityChecker.d.ts +3 -2
  5. package/dist/src/connection/ConnectivityChecker.js +21 -19
  6. package/dist/src/connection/ConnectivityChecker.js.map +1 -1
  7. package/dist/src/connection/WebRTC/WebRtcConnector.d.ts +2 -0
  8. package/dist/src/connection/WebRTC/WebRtcConnector.js +14 -1
  9. package/dist/src/connection/WebRTC/WebRtcConnector.js.map +1 -1
  10. package/dist/src/connection/WebSocket/WebSocketConnector.d.ts +5 -3
  11. package/dist/src/connection/WebSocket/WebSocketConnector.js +18 -12
  12. package/dist/src/connection/WebSocket/WebSocketConnector.js.map +1 -1
  13. package/dist/src/connection/WebSocket/WebSocketServer.d.ts +2 -2
  14. package/dist/src/connection/WebSocket/WebSocketServer.js +27 -36
  15. package/dist/src/connection/WebSocket/WebSocketServer.js.map +1 -1
  16. package/dist/src/dht/DhtNode.d.ts +6 -2
  17. package/dist/src/dht/DhtNode.js +8 -6
  18. package/dist/src/dht/DhtNode.js.map +1 -1
  19. package/dist/src/dht/discovery/PeerDiscovery.d.ts +4 -2
  20. package/dist/src/dht/discovery/PeerDiscovery.js +18 -33
  21. package/dist/src/dht/discovery/PeerDiscovery.js.map +1 -1
  22. package/dist/src/exports.d.ts +1 -1
  23. package/dist/src/exports.js.map +1 -1
  24. package/dist/src/helpers/errors.d.ts +1 -1
  25. package/dist/src/helpers/errors.js +3 -3
  26. package/dist/src/helpers/errors.js.map +1 -1
  27. package/dist/src/helpers/protoClasses.js +0 -2
  28. package/dist/src/helpers/protoClasses.js.map +1 -1
  29. package/dist/src/proto/packages/dht/protos/DhtRpc.client.js +1 -1
  30. package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +10 -50
  31. package/dist/src/proto/packages/dht/protos/DhtRpc.js +8 -35
  32. package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
  33. package/dist/src/proto/packages/proto-rpc/protos/ProtoRpc.js +1 -1
  34. package/package.json +4 -4
  35. package/protos/DhtRpc.proto +5 -15
  36. package/src/connection/ConnectionManager.ts +15 -3
  37. package/src/connection/ConnectivityChecker.ts +25 -23
  38. package/src/connection/WebRTC/WebRtcConnector.ts +14 -0
  39. package/src/connection/WebSocket/WebSocketConnector.ts +22 -12
  40. package/src/connection/WebSocket/WebSocketServer.ts +31 -19
  41. package/src/dht/DhtNode.ts +13 -7
  42. package/src/dht/discovery/PeerDiscovery.ts +17 -8
  43. package/src/exports.ts +1 -1
  44. package/src/helpers/errors.ts +1 -1
  45. package/src/helpers/protoClasses.ts +1 -5
  46. package/src/proto/google/protobuf/any.ts +1 -1
  47. package/src/proto/google/protobuf/empty.ts +1 -1
  48. package/src/proto/google/protobuf/timestamp.ts +1 -1
  49. package/src/proto/packages/dht/protos/DhtRpc.client.ts +1 -1
  50. package/src/proto/packages/dht/protos/DhtRpc.server.ts +1 -1
  51. package/src/proto/packages/dht/protos/DhtRpc.ts +17 -69
  52. package/src/proto/packages/proto-rpc/protos/ProtoRpc.ts +1 -1
  53. package/test/end-to-end/Layer0-Layer1.test.ts +1 -1
  54. package/test/end-to-end/Layer0.test.ts +1 -1
  55. package/test/end-to-end/Layer0MixedConnectionTypes.test.ts +1 -1
  56. package/test/end-to-end/Layer0WebRTC-Layer1.test.ts +3 -2
  57. package/test/end-to-end/Layer0WebRTC.test.ts +1 -1
  58. package/test/end-to-end/Layer1-Scale-WebRTC.test.ts +1 -1
  59. package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +1 -1
  60. package/test/end-to-end/WebSocketConnectionRequest.test.ts +1 -1
  61. package/test/integration/ConnectionManager.test.ts +9 -9
  62. package/test/integration/SimultaneousConnections.test.ts +9 -6
  63. package/test/integration/WebSocketConnectionManagement.test.ts +3 -2
  64. package/test/unit/webrtcReplaceInternalIpWithExternalIp.ts +18 -0
@@ -4,6 +4,7 @@ import { ITransport } from '../../transport/ITransport'
4
4
  import { ListeningRpcCommunicator } from '../../transport/ListeningRpcCommunicator'
5
5
  import { RemoteWebSocketConnector } from './RemoteWebSocketConnector'
6
6
  import {
7
+ ConnectivityMethod,
7
8
  ConnectivityResponse,
8
9
  PeerDescriptor,
9
10
  WebSocketConnectionRequest,
@@ -16,7 +17,7 @@ import { ServerCallContext } from '@protobuf-ts/runtime-rpc'
16
17
  import { ManagedConnection } from '../ManagedConnection'
17
18
  import { WebSocketServer } from './WebSocketServer'
18
19
  import { ConnectivityChecker } from '../ConnectivityChecker'
19
- import { NatType, PortRange } from '../ConnectionManager'
20
+ import { NatType, PortRange, TlsCertificate } from '../ConnectionManager'
20
21
  import { PeerIDKey } from '../../helpers/PeerID'
21
22
  import { ServerWebSocket } from './ServerWebSocket'
22
23
  import { toProtoRpcClient } from '@streamr/proto-rpc'
@@ -27,6 +28,12 @@ import { sample } from 'lodash'
27
28
 
28
29
  const logger = new Logger(module)
29
30
 
31
+ export const connectivityMethodToWebSocketUrl = (ws: ConnectivityMethod): string => {
32
+ return (ws.tls ? 'wss://' : 'ws://') + ws.host + ':' + ws.port
33
+ }
34
+
35
+ const ENTRY_POINT_CONNECTION_ATTEMPTS = 5
36
+
30
37
  export class WebSocketConnector implements IWebSocketConnectorService {
31
38
  private static readonly WEBSOCKET_CONNECTOR_SERVICE_ID = 'system/websocketconnector'
32
39
  private readonly rpcCommunicator: ListeningRpcCommunicator
@@ -38,6 +45,7 @@ export class WebSocketConnector implements IWebSocketConnectorService {
38
45
  private portRange?: PortRange
39
46
  private host?: string
40
47
  private entrypoints?: PeerDescriptor[]
48
+ private readonly tlsCertificate?: TlsCertificate
41
49
  private selectedPort?: number
42
50
  private readonly protocolVersion: string
43
51
  private ownPeerDescriptor?: PeerDescriptor
@@ -51,7 +59,8 @@ export class WebSocketConnector implements IWebSocketConnectorService {
51
59
  incomingConnectionCallback: (connection: ManagedConnection) => boolean,
52
60
  portRange?: PortRange,
53
61
  host?: string,
54
- entrypoints?: PeerDescriptor[]
62
+ entrypoints?: PeerDescriptor[],
63
+ tlsCertificate?: TlsCertificate
55
64
  ) {
56
65
  this.protocolVersion = protocolVersion
57
66
  this.webSocketServer = portRange ? new WebSocketServer() : undefined
@@ -59,6 +68,7 @@ export class WebSocketConnector implements IWebSocketConnectorService {
59
68
  this.portRange = portRange
60
69
  this.host = host
61
70
  this.entrypoints = entrypoints
71
+ this.tlsCertificate = tlsCertificate
62
72
 
63
73
  this.canConnectFunction = fnCanConnect.bind(this)
64
74
 
@@ -101,16 +111,16 @@ export class WebSocketConnector implements IWebSocketConnectorService {
101
111
  this.attachHandshaker(connection)
102
112
  }
103
113
  })
104
- const port = await this.webSocketServer.start(this.portRange!, this.host)
114
+ const port = await this.webSocketServer.start(this.portRange!, this.host, this.tlsCertificate)
105
115
  this.selectedPort = port
106
- this.connectivityChecker = new ConnectivityChecker(this.selectedPort)
116
+ this.connectivityChecker = new ConnectivityChecker(this.selectedPort, this.tlsCertificate !== undefined)
107
117
  }
108
118
  }
109
119
 
110
120
  public async checkConnectivity(reattempt = 0): Promise<ConnectivityResponse> {
111
121
  const noServerConnectivityResponse: ConnectivityResponse = {
112
122
  openInternet: false,
113
- ip: '127.0.0.1',
123
+ host: '127.0.0.1',
114
124
  natType: NatType.UNKNOWN
115
125
  }
116
126
  if (this.destroyed) {
@@ -125,9 +135,9 @@ export class WebSocketConnector implements IWebSocketConnectorService {
125
135
  // return connectivity info given in config
126
136
  const preconfiguredConnectivityResponse: ConnectivityResponse = {
127
137
  openInternet: true,
128
- ip: this.host!,
138
+ host: this.host!,
129
139
  natType: NatType.OPEN_INTERNET,
130
- websocket: { ip: this.host!, port: this.selectedPort! }
140
+ websocket: { host: this.host!, port: this.selectedPort!, tls: this.tlsCertificate !== undefined }
131
141
  }
132
142
  return preconfiguredConnectivityResponse
133
143
  } else {
@@ -136,7 +146,8 @@ export class WebSocketConnector implements IWebSocketConnectorService {
136
146
  }
137
147
  }
138
148
  } catch (err) {
139
- if (reattempt < 5) {
149
+ if (reattempt < ENTRY_POINT_CONNECTION_ATTEMPTS) {
150
+ logger.error('Failed to connect to the entrypoint', { error: err })
140
151
  await wait(2000)
141
152
  return this.checkConnectivity(reattempt + 1)
142
153
  } else {
@@ -158,8 +169,7 @@ export class WebSocketConnector implements IWebSocketConnectorService {
158
169
  } else {
159
170
  const socket = new ClientWebSocket()
160
171
 
161
- const address = 'ws://' + targetPeerDescriptor.websocket!.ip + ':' +
162
- targetPeerDescriptor.websocket!.port
172
+ const url = connectivityMethodToWebSocketUrl(targetPeerDescriptor.websocket!)
163
173
 
164
174
  const managedConnection = new ManagedConnection(this.ownPeerDescriptor!, this.protocolVersion,
165
175
  ConnectionType.WEBSOCKET_CLIENT, socket, undefined)
@@ -177,7 +187,7 @@ export class WebSocketConnector implements IWebSocketConnectorService {
177
187
  socket.on('disconnected', delFunc)
178
188
  managedConnection.on('handshakeCompleted', delFunc)
179
189
 
180
- socket.connect(address)
190
+ socket.connect(url)
181
191
 
182
192
  return managedConnection
183
193
  }
@@ -189,7 +199,7 @@ export class WebSocketConnector implements IWebSocketConnectorService {
189
199
  targetPeerDescriptor,
190
200
  toProtoRpcClient(new WebSocketConnectorServiceClient(this.rpcCommunicator.getRpcClientTransport()))
191
201
  )
192
- remoteConnector.requestConnection(ownPeerDescriptor, ownPeerDescriptor.websocket!.ip, ownPeerDescriptor.websocket!.port)
202
+ remoteConnector.requestConnection(ownPeerDescriptor, ownPeerDescriptor.websocket!.host, ownPeerDescriptor.websocket!.port)
193
203
  })
194
204
  const managedConnection = new ManagedConnection(this.ownPeerDescriptor!, this.protocolVersion, ConnectionType.WEBSOCKET_SERVER)
195
205
  managedConnection.on('disconnected', () => this.ongoingConnectRequests.delete(keyFromPeerDescriptor(targetPeerDescriptor)))
@@ -1,4 +1,5 @@
1
- import * as http from 'http'
1
+ import { createServer as createHttpServer, Server as HttpServer, IncomingMessage, ServerResponse } from 'http'
2
+ import { createServer as createHttpsServer, Server as HttpsServer } from 'https'
2
3
  import EventEmitter from 'eventemitter3'
3
4
  import { server as WsServer } from 'websocket'
4
5
  import { ServerWebSocket } from './ServerWebSocket'
@@ -7,9 +8,10 @@ import {
7
8
  } from '../IConnectionSource'
8
9
 
9
10
  import { Logger, asAbortable } from '@streamr/utils'
10
- import { StartingWebSocketServerFailed } from '../../helpers/errors'
11
- import { PortRange } from '../ConnectionManager'
11
+ import { WebSocketServerStartError } from '../../helpers/errors'
12
+ import { PortRange, TlsCertificate } from '../ConnectionManager'
12
13
  import { range } from 'lodash'
14
+ import fs from 'fs'
13
15
 
14
16
  const logger = new Logger(module)
15
17
 
@@ -22,30 +24,41 @@ declare class NodeJsWsServer extends WsServer { }
22
24
 
23
25
  export class WebSocketServer extends EventEmitter<ConnectionSourceEvents> {
24
26
 
25
- private httpServer?: http.Server
27
+ private httpServer?: HttpServer | HttpsServer
26
28
  private wsServer?: WsServer
27
29
  private readonly abortController = new AbortController()
28
-
29
- public async start(portRange: PortRange, host?: string): Promise<number> {
30
+
31
+ public async start(portRange: PortRange, host?: string, tlsCertificate?: TlsCertificate): Promise<number> {
30
32
  const ports = range(portRange.min, portRange.max + 1)
31
33
  for (const port of ports) {
32
34
  try {
33
- await asAbortable(this.startServer(port, host), this.abortController.signal)
35
+ await asAbortable(this.startServer(port, host, tlsCertificate), this.abortController.signal)
34
36
  return port
35
37
  } catch (err) {
36
- logger.debug(`failed to start WebSocket server on port: ${port} reattempting on next port`)
38
+ if (err.originalError?.code === 'EADDRINUSE') {
39
+ logger.debug(`failed to start WebSocket server on port: ${port} reattempting on next port`)
40
+ } else {
41
+ throw new WebSocketServerStartError(err)
42
+ }
37
43
  }
38
44
  }
39
- throw new StartingWebSocketServerFailed('Failed to start WebSocket server on any port in range')
45
+ throw new WebSocketServerStartError('Failed to start WebSocket server on any port in range')
40
46
  }
41
47
 
42
- private startServer(port: number, host?: string): Promise<void> {
48
+ private startServer(port: number, host?: string, tlsCertificate?: TlsCertificate): Promise<void> {
49
+ const requestListener = (request: IncomingMessage, response: ServerResponse<IncomingMessage>) => {
50
+ logger.trace('Received request for ' + request.url)
51
+ response.writeHead(404)
52
+ response.end()
53
+ }
43
54
  return new Promise((resolve, reject) => {
44
- this.httpServer = http.createServer((request, response) => {
45
- logger.trace('Received request for ' + request.url)
46
- response.writeHead(404)
47
- response.end()
48
- })
55
+ this.httpServer = tlsCertificate ?
56
+ createHttpsServer({
57
+ key: fs.readFileSync(tlsCertificate.privateKeyFileName),
58
+ cert: fs.readFileSync(tlsCertificate.certFileName)
59
+ }, requestListener)
60
+ :
61
+ createHttpServer(requestListener)
49
62
 
50
63
  function originIsAllowed(_uorigin: string) {
51
64
  return true
@@ -67,9 +80,8 @@ export class WebSocketServer extends EventEmitter<ConnectionSourceEvents> {
67
80
 
68
81
  this.emit('connected', new ServerWebSocket(connection, request.resourceURL))
69
82
  })
70
-
71
83
  this.httpServer.once('error', (err: Error) => {
72
- reject(new StartingWebSocketServerFailed('Starting Websocket server failed', err))
84
+ reject(new WebSocketServerStartError('Starting Websocket server failed', err))
73
85
  })
74
86
 
75
87
  this.httpServer.once('listening', () => {
@@ -80,7 +92,7 @@ export class WebSocketServer extends EventEmitter<ConnectionSourceEvents> {
80
92
  try {
81
93
  this.httpServer.listen(port, host)
82
94
  } catch (e) {
83
- reject(new StartingWebSocketServerFailed('Websocket server threw an exception', e))
95
+ reject(new WebSocketServerStartError('Websocket server threw an exception', e))
84
96
  }
85
97
  })
86
98
  }
@@ -96,7 +108,7 @@ export class WebSocketServer extends EventEmitter<ConnectionSourceEvents> {
96
108
  })
97
109
  }
98
110
 
99
- private createWsServer(httpServer: http.Server): WsServer {
111
+ private createWsServer(httpServer: HttpServer | HttpsServer): WsServer {
100
112
  // Use the real nodejs WebSocket server in Electron tests
101
113
 
102
114
  if (typeof NodeJsWsServer !== 'undefined') {
@@ -20,7 +20,7 @@ import {
20
20
  } from '../proto/packages/dht/protos/DhtRpc'
21
21
  import * as Err from '../helpers/errors'
22
22
  import { DisconnectionType, ITransport, TransportEvents } from '../transport/ITransport'
23
- import { ConnectionManager, ConnectionManagerConfig, PortRange } from '../connection/ConnectionManager'
23
+ import { ConnectionManager, ConnectionManagerConfig, PortRange, TlsCertificate } from '../connection/ConnectionManager'
24
24
  import { DhtRpcServiceClient, ExternalApiServiceClient } from '../proto/packages/dht/protos/DhtRpc.client'
25
25
  import {
26
26
  Logger,
@@ -82,6 +82,8 @@ export interface DhtNodeOptions {
82
82
  webrtcNewConnectionTimeout?: number
83
83
  webrtcPortRange?: PortRange
84
84
  maxConnections?: number
85
+ tlsCertificate?: TlsCertificate
86
+ externalIp?: string
85
87
  }
86
88
 
87
89
  export class DhtNodeConfig {
@@ -111,7 +113,9 @@ export class DhtNodeConfig {
111
113
  webrtcDatachannelBufferThresholdLow?: number
112
114
  webrtcDatachannelBufferThresholdHigh?: number
113
115
  webrtcNewConnectionTimeout?: number
116
+ externalIp?: string
114
117
  webrtcPortRange?: PortRange
118
+ tlsCertificate?: TlsCertificate
115
119
 
116
120
  constructor(conf: Partial<DhtNodeOptions>) {
117
121
  // assign given non-undefined config vars over defaults
@@ -132,13 +136,13 @@ export type Events = TransportEvents & DhtNodeEvents
132
136
  export const createPeerDescriptor = (msg?: ConnectivityResponse, peerIdString?: string, nodeName?: string): PeerDescriptor => {
133
137
  let peerId: Uint8Array
134
138
  if (msg) {
135
- peerId = peerIdString ? PeerID.fromString(peerIdString).value : PeerID.fromIp(msg.ip).value
139
+ peerId = peerIdString ? PeerID.fromString(peerIdString).value : PeerID.fromIp(msg.host).value
136
140
  } else {
137
141
  peerId = PeerID.fromString(peerIdString!).value
138
142
  }
139
143
  const ret: PeerDescriptor = { kademliaId: peerId, nodeName: nodeName, type: NodeType.NODEJS }
140
144
  if (msg && msg.websocket) {
141
- ret.websocket = { ip: msg.websocket.ip, port: msg.websocket.port }
145
+ ret.websocket = { host: msg.websocket.host, port: msg.websocket.port, tls: msg.websocket.tls }
142
146
  ret.openInternet = true
143
147
  }
144
148
  return ret
@@ -208,11 +212,13 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
208
212
  webrtcNewConnectionTimeout: this.config.webrtcNewConnectionTimeout,
209
213
  webrtcPortRange: this.config.webrtcPortRange,
210
214
  nodeName: this.getNodeName(),
211
- maxConnections: this.config.maxConnections
215
+ maxConnections: this.config.maxConnections,
216
+ tlsCertificate: this.config.tlsCertificate,
217
+ externalIp: this.config.externalIp
212
218
  }
213
219
  // If own PeerDescriptor is given in config, create a ConnectionManager with ws server
214
220
  if (this.config.peerDescriptor?.websocket) {
215
- connectionManagerConfig.websocketHost = this.config.peerDescriptor.websocket.ip
221
+ connectionManagerConfig.websocketHost = this.config.peerDescriptor.websocket.host
216
222
  connectionManagerConfig.websocketPortRange = {
217
223
  min: this.config.peerDescriptor.websocket.port,
218
224
  max: this.config.peerDescriptor.websocket.port
@@ -619,12 +625,12 @@ export class DhtNode extends EventEmitter<Events> implements ITransport {
619
625
  await this.router!.send(msg, reachableThrough)
620
626
  }
621
627
 
622
- public async joinDht(entryPointDescriptors: PeerDescriptor[], doRandomJoin?: boolean): Promise<void> {
628
+ public async joinDht(entryPointDescriptors: PeerDescriptor[], doRandomJoin?: boolean, retry?: boolean): Promise<void> {
623
629
  if (!this.started) {
624
630
  throw new Error('Cannot join DHT before calling start() on DhtNode')
625
631
  }
626
632
  await Promise.all(entryPointDescriptors.map((entryPoint) =>
627
- this.peerDiscovery!.joinDht(entryPoint, doRandomJoin)
633
+ this.peerDiscovery!.joinDht(entryPoint, doRandomJoin, retry)
628
634
  ))
629
635
  }
630
636
 
@@ -1,7 +1,6 @@
1
1
  import { DiscoverySession } from './DiscoverySession'
2
2
  import { DhtPeer } from '../DhtPeer'
3
3
  import crypto from 'crypto'
4
- import * as Err from '../../helpers/errors'
5
4
  import { isSamePeerDescriptor, keyFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
6
5
  import { PeerDescriptor } from '../../proto/packages/dht/protos/DhtRpc'
7
6
  import { Logger, scheduleAtInterval, setAbortableTimeout } from '@streamr/utils'
@@ -41,13 +40,14 @@ export class PeerDiscovery {
41
40
 
42
41
  private rejoinTimeoutRef?: NodeJS.Timeout
43
42
  private readonly abortController: AbortController
43
+ private recoveryIntervalStarted = false
44
44
 
45
45
  constructor(config: PeerDiscoveryConfig) {
46
46
  this.config = config
47
47
  this.abortController = new AbortController()
48
48
  }
49
49
 
50
- async joinDht(entryPointDescriptor: PeerDescriptor, doRandomJoin = true): Promise<void> {
50
+ async joinDht(entryPointDescriptor: PeerDescriptor, doRandomJoin = true, retry = true): Promise<void> {
51
51
  if (this.stopped) {
52
52
  return
53
53
  }
@@ -90,16 +90,18 @@ export class PeerDiscovery {
90
90
  if (randomSession) {
91
91
  await randomSession.findClosestNodes(this.config.joinTimeout)
92
92
  }
93
+ } catch (_e) {
94
+ logger.debug(`DHT join on ${this.config.serviceId} timed out`)
95
+ } finally {
93
96
  if (!this.stopped) {
94
97
  if (this.config.bucket.count() === 0) {
95
- this.rejoinDht(entryPointDescriptor).catch(() => {})
98
+ if (retry) {
99
+ setAbortableTimeout(() => this.rejoinDht(entryPointDescriptor), 1000, this.abortController.signal)
100
+ }
96
101
  } else {
97
- await scheduleAtInterval(() => this.getClosestPeersFromBucket(), 60000, true, this.abortController.signal)
102
+ await this.ensureRecoveryIntervalIsRunning()
98
103
  }
99
104
  }
100
- } catch (_e) {
101
- throw new Err.DhtJoinTimeout('join timed out')
102
- } finally {
103
105
  this.ongoingDiscoverySessions.delete(session.sessionId)
104
106
  if (randomSession) {
105
107
  this.ongoingDiscoverySessions.delete(randomSession.sessionId)
@@ -128,7 +130,14 @@ export class PeerDiscovery {
128
130
  }
129
131
  }
130
132
 
131
- private async getClosestPeersFromBucket(): Promise<void> {
133
+ private async ensureRecoveryIntervalIsRunning(): Promise<void> {
134
+ if (!this.recoveryIntervalStarted) {
135
+ this.recoveryIntervalStarted = true
136
+ await scheduleAtInterval(() => this.fetchClosestPeersFromBucket(), 60000, true, this.abortController.signal)
137
+ }
138
+ }
139
+
140
+ private async fetchClosestPeersFromBucket(): Promise<void> {
132
141
  if (this.stopped) {
133
142
  return
134
143
  }
package/src/exports.ts CHANGED
@@ -5,7 +5,7 @@ export { SimulatorTransport } from './connection/Simulator/SimulatorTransport'
5
5
  export { getRandomRegion, getRegionDelayMatrix } from './connection/Simulator/pings'
6
6
  export { PeerDescriptor, Message, NodeType, DataEntry } from './proto/packages/dht/protos/DhtRpc'
7
7
  export { ITransport } from './transport/ITransport'
8
- export { ConnectionManager, ConnectionLocker, PortRange } from './connection/ConnectionManager'
8
+ export { ConnectionManager, ConnectionLocker, PortRange, TlsCertificate } from './connection/ConnectionManager'
9
9
  export { PeerID, PeerIDKey } from './helpers/PeerID'
10
10
  export { DhtPeer } from './dht/DhtPeer'
11
11
  export { UUID } from './helpers/UUID'
@@ -33,7 +33,7 @@ class Err extends Error {
33
33
 
34
34
  export class ConnectionFailed extends Err { constructor( message?: string, originalError?: Error | string) { super(ErrorCode.CONNECTION_FAILED, message, originalError) } }
35
35
  export class CouldNotRoute extends Err { constructor(message?: string, originalError?: Error | string) { super(ErrorCode.COULD_NOT_ROUTE, message, originalError) } }
36
- export class StartingWebSocketServerFailed extends Err { constructor(message?: string, originalError?: Error | string) { super(ErrorCode.STARTING_WEBSOCKET_SERVER_FAILED, message, originalError) } }
36
+ export class WebSocketServerStartError extends Err { constructor(message?: string, originalError?: Error | string) { super(ErrorCode.STARTING_WEBSOCKET_SERVER_FAILED, message, originalError) } }
37
37
  export class WebSocketConnectionRequestRejected extends Err { constructor(message?: string, originalError?: Error | string) { super(ErrorCode.WEBSOCKET_CONNECTION_REQUEST_REJECTED, message, originalError) } }
38
38
  export class CouldNotStart extends Err { constructor(message?: string, originalError?: Error | string) { super(ErrorCode.COULD_NOT_START, message, originalError) } }
39
39
  export class CouldNotStop extends Err { constructor(message?: string, originalError?: Error | string) { super(ErrorCode.COULD_NOT_STOP, message, originalError) } }
@@ -2,9 +2,7 @@ import { IMessageType } from '@protobuf-ts/runtime'
2
2
  import {
3
3
  ClosestPeersRequest,
4
4
  ClosestPeersResponse,
5
- ConnectivityMethod,
6
- ConnectivityReportRequest,
7
- ConnectivityReportResponse,
5
+ ConnectivityMethod,
8
6
  ConnectivityRequest,
9
7
  ConnectivityResponse,
10
8
  DisconnectNotice,
@@ -41,8 +39,6 @@ export const protoClasses: Array<IMessageType<any>> = [
41
39
  LeaveNotice,
42
40
  PeerDescriptor,
43
41
  ConnectivityMethod,
44
- ConnectivityReportRequest,
45
- ConnectivityReportResponse,
46
42
  DisconnectNotice,
47
43
  RouteMessageWrapper,
48
44
  RouteMessageAck,
@@ -1,4 +1,4 @@
1
- // @generated by protobuf-ts 2.8.2 with parameter server_generic,generate_dependencies,long_type_number
1
+ // @generated by protobuf-ts 2.9.1 with parameter server_generic,generate_dependencies,long_type_number
2
2
  // @generated from protobuf file "google/protobuf/any.proto" (package "google.protobuf", syntax proto3)
3
3
  // tslint:disable
4
4
  //
@@ -1,4 +1,4 @@
1
- // @generated by protobuf-ts 2.8.2 with parameter server_generic,generate_dependencies,long_type_number
1
+ // @generated by protobuf-ts 2.9.1 with parameter server_generic,generate_dependencies,long_type_number
2
2
  // @generated from protobuf file "google/protobuf/empty.proto" (package "google.protobuf", syntax proto3)
3
3
  // tslint:disable
4
4
  //
@@ -1,4 +1,4 @@
1
- // @generated by protobuf-ts 2.8.2 with parameter server_generic,generate_dependencies,long_type_number
1
+ // @generated by protobuf-ts 2.9.1 with parameter server_generic,generate_dependencies,long_type_number
2
2
  // @generated from protobuf file "google/protobuf/timestamp.proto" (package "google.protobuf", syntax proto3)
3
3
  // tslint:disable
4
4
  //
@@ -1,4 +1,4 @@
1
- // @generated by protobuf-ts 2.8.2 with parameter server_generic,generate_dependencies,long_type_number
1
+ // @generated by protobuf-ts 2.9.1 with parameter server_generic,generate_dependencies,long_type_number
2
2
  // @generated from protobuf file "packages/dht/protos/DhtRpc.proto" (package "dht", syntax proto3)
3
3
  // tslint:disable
4
4
  import { ExternalApiService } from "./DhtRpc";
@@ -1,4 +1,4 @@
1
- // @generated by protobuf-ts 2.8.2 with parameter server_generic,generate_dependencies,long_type_number
1
+ // @generated by protobuf-ts 2.9.1 with parameter server_generic,generate_dependencies,long_type_number
2
2
  // @generated from protobuf file "packages/dht/protos/DhtRpc.proto" (package "dht", syntax proto3)
3
3
  // tslint:disable
4
4
  import { FindDataResponse } from "./DhtRpc";
@@ -1,4 +1,4 @@
1
- // @generated by protobuf-ts 2.8.2 with parameter server_generic,generate_dependencies,long_type_number
1
+ // @generated by protobuf-ts 2.9.1 with parameter server_generic,generate_dependencies,long_type_number
2
2
  // @generated from protobuf file "packages/dht/protos/DhtRpc.proto" (package "dht", syntax proto3)
3
3
  // tslint:disable
4
4
  import { Empty } from "../../../google/protobuf/empty";
@@ -240,48 +240,18 @@ export interface PeerDescriptor {
240
240
  * @generated from protobuf message dht.ConnectivityMethod
241
241
  */
242
242
  export interface ConnectivityMethod {
243
- /**
244
- * @generated from protobuf field: uint32 port = 2;
245
- */
246
- port: number;
247
- /**
248
- * @generated from protobuf field: string ip = 3;
249
- */
250
- ip: string;
251
- }
252
- /**
253
- * @generated from protobuf message dht.ConnectivityReportRequest
254
- */
255
- export interface ConnectivityReportRequest {
256
243
  /**
257
244
  * @generated from protobuf field: uint32 port = 1;
258
245
  */
259
246
  port: number;
260
247
  /**
261
- * @generated from protobuf field: string requestId = 2;
262
- */
263
- requestId: string;
264
- }
265
- /**
266
- * @generated from protobuf message dht.ConnectivityReportResponse
267
- */
268
- export interface ConnectivityReportResponse {
269
- /**
270
- * @generated from protobuf field: string open_internet = 1;
271
- */
272
- openInternet: string;
273
- /**
274
- * @generated from protobuf field: string ip = 2;
275
- */
276
- ip: string;
277
- /**
278
- * @generated from protobuf field: string natType = 3;
248
+ * @generated from protobuf field: string host = 2;
279
249
  */
280
- natType: string;
250
+ host: string;
281
251
  /**
282
- * @generated from protobuf field: string requestId = 4;
252
+ * @generated from protobuf field: bool tls = 3;
283
253
  */
284
- requestId: string;
254
+ tls: boolean;
285
255
  }
286
256
  /**
287
257
  * @generated from protobuf message dht.RouteMessageWrapper
@@ -347,6 +317,10 @@ export interface ConnectivityRequest {
347
317
  * @generated from protobuf field: uint32 port = 1;
348
318
  */
349
319
  port: number;
320
+ /**
321
+ * @generated from protobuf field: bool tls = 2;
322
+ */
323
+ tls: boolean;
350
324
  }
351
325
  /**
352
326
  * @generated from protobuf message dht.ConnectivityResponse
@@ -357,9 +331,9 @@ export interface ConnectivityResponse {
357
331
  */
358
332
  openInternet: boolean;
359
333
  /**
360
- * @generated from protobuf field: string ip = 2;
334
+ * @generated from protobuf field: string host = 2;
361
335
  */
362
- ip: string;
336
+ host: string;
363
337
  /**
364
338
  * @generated from protobuf field: string natType = 3;
365
339
  */
@@ -1007,8 +981,9 @@ export const PeerDescriptor = new PeerDescriptor$Type();
1007
981
  class ConnectivityMethod$Type extends MessageType$<ConnectivityMethod> {
1008
982
  constructor() {
1009
983
  super("dht.ConnectivityMethod", [
1010
- { no: 2, name: "port", kind: "scalar", T: 13 /*ScalarType.UINT32*/ },
1011
- { no: 3, name: "ip", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
984
+ { no: 1, name: "port", kind: "scalar", T: 13 /*ScalarType.UINT32*/ },
985
+ { no: 2, name: "host", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
986
+ { no: 3, name: "tls", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }
1012
987
  ]);
1013
988
  }
1014
989
  }
@@ -1017,34 +992,6 @@ class ConnectivityMethod$Type extends MessageType$<ConnectivityMethod> {
1017
992
  */
1018
993
  export const ConnectivityMethod = new ConnectivityMethod$Type();
1019
994
  // @generated message type with reflection information, may provide speed optimized methods
1020
- class ConnectivityReportRequest$Type extends MessageType$<ConnectivityReportRequest> {
1021
- constructor() {
1022
- super("dht.ConnectivityReportRequest", [
1023
- { no: 1, name: "port", kind: "scalar", T: 13 /*ScalarType.UINT32*/ },
1024
- { no: 2, name: "requestId", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
1025
- ]);
1026
- }
1027
- }
1028
- /**
1029
- * @generated MessageType for protobuf message dht.ConnectivityReportRequest
1030
- */
1031
- export const ConnectivityReportRequest = new ConnectivityReportRequest$Type();
1032
- // @generated message type with reflection information, may provide speed optimized methods
1033
- class ConnectivityReportResponse$Type extends MessageType$<ConnectivityReportResponse> {
1034
- constructor() {
1035
- super("dht.ConnectivityReportResponse", [
1036
- { no: 1, name: "open_internet", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
1037
- { no: 2, name: "ip", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
1038
- { no: 3, name: "natType", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
1039
- { no: 4, name: "requestId", kind: "scalar", T: 9 /*ScalarType.STRING*/ }
1040
- ]);
1041
- }
1042
- }
1043
- /**
1044
- * @generated MessageType for protobuf message dht.ConnectivityReportResponse
1045
- */
1046
- export const ConnectivityReportResponse = new ConnectivityReportResponse$Type();
1047
- // @generated message type with reflection information, may provide speed optimized methods
1048
995
  class RouteMessageWrapper$Type extends MessageType$<RouteMessageWrapper> {
1049
996
  constructor() {
1050
997
  super("dht.RouteMessageWrapper", [
@@ -1081,7 +1028,8 @@ export const RouteMessageAck = new RouteMessageAck$Type();
1081
1028
  class ConnectivityRequest$Type extends MessageType$<ConnectivityRequest> {
1082
1029
  constructor() {
1083
1030
  super("dht.ConnectivityRequest", [
1084
- { no: 1, name: "port", kind: "scalar", T: 13 /*ScalarType.UINT32*/ }
1031
+ { no: 1, name: "port", kind: "scalar", T: 13 /*ScalarType.UINT32*/ },
1032
+ { no: 2, name: "tls", kind: "scalar", T: 8 /*ScalarType.BOOL*/ }
1085
1033
  ]);
1086
1034
  }
1087
1035
  }
@@ -1094,7 +1042,7 @@ class ConnectivityResponse$Type extends MessageType$<ConnectivityResponse> {
1094
1042
  constructor() {
1095
1043
  super("dht.ConnectivityResponse", [
1096
1044
  { no: 1, name: "open_internet", kind: "scalar", T: 8 /*ScalarType.BOOL*/ },
1097
- { no: 2, name: "ip", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
1045
+ { no: 2, name: "host", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
1098
1046
  { no: 3, name: "natType", kind: "scalar", T: 9 /*ScalarType.STRING*/ },
1099
1047
  { no: 4, name: "websocket", kind: "message", T: () => ConnectivityMethod }
1100
1048
  ]);
@@ -1,4 +1,4 @@
1
- // @generated by protobuf-ts 2.8.2 with parameter server_generic,generate_dependencies,long_type_number
1
+ // @generated by protobuf-ts 2.9.1 with parameter server_generic,generate_dependencies,long_type_number
2
2
  // @generated from protobuf file "packages/proto-rpc/protos/ProtoRpc.proto" (package "protorpc", syntax proto3)
3
3
  // tslint:disable
4
4
  import { MessageType } from "@protobuf-ts/runtime";
@@ -6,7 +6,7 @@ describe('Layer0-Layer1', () => {
6
6
  const epPeerDescriptor: PeerDescriptor = {
7
7
  kademliaId: Uint8Array.from([1, 2, 3]),
8
8
  type: NodeType.NODEJS,
9
- websocket: { ip: '127.0.0.1', port: 10016 }
9
+ websocket: { host: '127.0.0.1', port: 10016, tls: false }
10
10
  }
11
11
 
12
12
  const STREAM_ID1 = 'stream1'
@@ -6,7 +6,7 @@ describe('Layer0', () => {
6
6
  const epPeerDescriptor: PeerDescriptor = {
7
7
  kademliaId: Uint8Array.from([1, 2, 3]),
8
8
  type: NodeType.NODEJS,
9
- websocket: { ip: '127.0.0.1', port: 10011 }
9
+ websocket: { host: '127.0.0.1', port: 10011, tls: false }
10
10
  }
11
11
 
12
12
  let epDhtNode: DhtNode
@@ -8,7 +8,7 @@ describe('Layer0MixedConnectionTypes', () => {
8
8
  const epPeerDescriptor: PeerDescriptor = {
9
9
  kademliaId: Uint8Array.from([1, 2, 3]),
10
10
  type: NodeType.NODEJS,
11
- websocket: { ip: '127.0.0.1', port: 11221 }
11
+ websocket: { host: '127.0.0.1', port: 11221, tls: false }
12
12
  }
13
13
 
14
14
  let epDhtNode: DhtNode
@@ -9,8 +9,9 @@ describe('Layer 1 on Layer 0 with mocked connections', () => {
9
9
  kademliaId: PeerID.fromString(entryPointId).value,
10
10
  type: NodeType.NODEJS,
11
11
  websocket: {
12
- ip: '127.0.0.1',
13
- port: 23232
12
+ host: '127.0.0.1',
13
+ port: 23232,
14
+ tls: false
14
15
  }
15
16
  }
16
17
 
@@ -11,7 +11,7 @@ describe('Layer0 with WebRTC connections', () => {
11
11
  kademliaId: PeerID.fromString('entrypoint').value,
12
12
  nodeName: 'entrypoint',
13
13
  type: NodeType.NODEJS,
14
- websocket: { ip: '127.0.0.1', port: 10029 }
14
+ websocket: { host: '127.0.0.1', port: 10029, tls: false }
15
15
  }
16
16
  let epDhtNode: DhtNode
17
17
  let node1: DhtNode