@streamr/dht 102.0.0-beta.1 → 102.0.0-beta.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 (210) hide show
  1. package/dist/generated/google/protobuf/any.d.ts +180 -0
  2. package/dist/generated/google/protobuf/any.js +155 -0
  3. package/dist/generated/google/protobuf/any.js.map +1 -0
  4. package/dist/generated/google/protobuf/empty.d.ts +31 -0
  5. package/dist/generated/google/protobuf/empty.js +32 -0
  6. package/dist/generated/google/protobuf/empty.js.map +1 -0
  7. package/dist/generated/google/protobuf/timestamp.d.ts +155 -0
  8. package/dist/generated/google/protobuf/timestamp.js +136 -0
  9. package/dist/generated/google/protobuf/timestamp.js.map +1 -0
  10. package/dist/generated/packages/dht/protos/DhtRpc.client.d.ts +361 -0
  11. package/dist/generated/packages/dht/protos/DhtRpc.client.js +285 -0
  12. package/dist/generated/packages/dht/protos/DhtRpc.client.js.map +1 -0
  13. package/dist/generated/packages/dht/protos/DhtRpc.d.ts +999 -0
  14. package/dist/generated/packages/dht/protos/DhtRpc.js +677 -0
  15. package/dist/generated/packages/dht/protos/DhtRpc.js.map +1 -0
  16. package/dist/generated/packages/dht/protos/DhtRpc.server.d.ts +162 -0
  17. package/dist/generated/packages/dht/protos/DhtRpc.server.js +3 -0
  18. package/dist/generated/packages/dht/protos/DhtRpc.server.js.map +1 -0
  19. package/dist/generated/packages/proto-rpc/protos/ProtoRpc.d.ts +87 -0
  20. package/dist/generated/packages/proto-rpc/protos/ProtoRpc.js +66 -0
  21. package/dist/generated/packages/proto-rpc/protos/ProtoRpc.js.map +1 -0
  22. package/dist/package.json +7 -7
  23. package/package.json +7 -7
  24. package/src/connection/Connection.ts +0 -28
  25. package/src/connection/ConnectionLockRpcLocal.ts +0 -78
  26. package/src/connection/ConnectionLockRpcRemote.ts +0 -64
  27. package/src/connection/ConnectionLockStates.ts +0 -131
  28. package/src/connection/ConnectionManager.ts +0 -661
  29. package/src/connection/ConnectionsView.ts +0 -8
  30. package/src/connection/ConnectorFacade.ts +0 -217
  31. package/src/connection/Handshaker.ts +0 -209
  32. package/src/connection/IConnection.ts +0 -40
  33. package/src/connection/ManagedConnection.ts +0 -113
  34. package/src/connection/OutputBuffer.ts +0 -28
  35. package/src/connection/PendingConnection.ts +0 -68
  36. package/src/connection/connectivityChecker.ts +0 -108
  37. package/src/connection/connectivityRequestHandler.ts +0 -116
  38. package/src/connection/simulator/Simulator.ts +0 -369
  39. package/src/connection/simulator/SimulatorConnection.ts +0 -137
  40. package/src/connection/simulator/SimulatorConnector.ts +0 -98
  41. package/src/connection/simulator/SimulatorTransport.ts +0 -15
  42. package/src/connection/simulator/pings.ts +0 -42
  43. package/src/connection/webrtc/BrowserWebrtcConnection.ts +0 -242
  44. package/src/connection/webrtc/IWebrtcConnection.ts +0 -24
  45. package/src/connection/webrtc/NodeWebrtcConnection.ts +0 -245
  46. package/src/connection/webrtc/WebrtcConnector.ts +0 -234
  47. package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +0 -108
  48. package/src/connection/webrtc/WebrtcConnectorRpcRemote.ts +0 -60
  49. package/src/connection/webrtc/iceServerAsString.ts +0 -15
  50. package/src/connection/websocket/AbstractWebsocketClientConnection.ts +0 -122
  51. package/src/connection/websocket/AutoCertifierClientFacade.ts +0 -89
  52. package/src/connection/websocket/BrowserWebsocketClientConnection.ts +0 -44
  53. package/src/connection/websocket/NodeWebsocketClientConnection.ts +0 -39
  54. package/src/connection/websocket/WebsocketClientConnector.ts +0 -119
  55. package/src/connection/websocket/WebsocketClientConnectorRpcLocal.ts +0 -38
  56. package/src/connection/websocket/WebsocketClientConnectorRpcRemote.ts +0 -19
  57. package/src/connection/websocket/WebsocketServer.ts +0 -164
  58. package/src/connection/websocket/WebsocketServerConnection.ts +0 -109
  59. package/src/connection/websocket/WebsocketServerConnector.ts +0 -290
  60. package/src/dht/DhtNode.ts +0 -683
  61. package/src/dht/DhtNodeRpcLocal.ts +0 -84
  62. package/src/dht/DhtNodeRpcRemote.ts +0 -107
  63. package/src/dht/ExternalApiRpcLocal.ts +0 -58
  64. package/src/dht/ExternalApiRpcRemote.ts +0 -41
  65. package/src/dht/PeerManager.ts +0 -305
  66. package/src/dht/contact/Contact.ts +0 -19
  67. package/src/dht/contact/ContactList.ts +0 -43
  68. package/src/dht/contact/RandomContactList.ts +0 -56
  69. package/src/dht/contact/RingContactList.ts +0 -143
  70. package/src/dht/contact/RpcRemote.ts +0 -72
  71. package/src/dht/contact/SortedContactList.ts +0 -173
  72. package/src/dht/contact/getClosestNodes.ts +0 -24
  73. package/src/dht/contact/ringIdentifiers.ts +0 -62
  74. package/src/dht/discovery/DiscoverySession.ts +0 -129
  75. package/src/dht/discovery/PeerDiscovery.ts +0 -244
  76. package/src/dht/discovery/RingDiscoverySession.ts +0 -148
  77. package/src/dht/recursive-operation/RecursiveOperationManager.ts +0 -251
  78. package/src/dht/recursive-operation/RecursiveOperationRpcLocal.ts +0 -34
  79. package/src/dht/recursive-operation/RecursiveOperationRpcRemote.ts +0 -43
  80. package/src/dht/recursive-operation/RecursiveOperationSession.ts +0 -231
  81. package/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.ts +0 -35
  82. package/src/dht/recursive-operation/RecursiveOperationSessionRpcRemote.ts +0 -30
  83. package/src/dht/routing/DuplicateDetector.ts +0 -34
  84. package/src/dht/routing/Router.ts +0 -246
  85. package/src/dht/routing/RouterRpcLocal.ts +0 -78
  86. package/src/dht/routing/RouterRpcRemote.ts +0 -80
  87. package/src/dht/routing/RoutingSession.ts +0 -243
  88. package/src/dht/routing/RoutingTablesCache.ts +0 -60
  89. package/src/dht/routing/getPreviousPeer.ts +0 -6
  90. package/src/dht/store/LocalDataStore.ts +0 -84
  91. package/src/dht/store/StoreManager.ts +0 -170
  92. package/src/dht/store/StoreRpcLocal.ts +0 -89
  93. package/src/dht/store/StoreRpcRemote.ts +0 -32
  94. package/src/exports.ts +0 -33
  95. package/src/helpers/AddressTools.ts +0 -28
  96. package/src/helpers/Connectivity.ts +0 -19
  97. package/src/helpers/browser/isBrowserEnvironment.ts +0 -1
  98. package/src/helpers/browser/isBrowserEnvironment_override.ts +0 -3
  99. package/src/helpers/createPeerDescriptor.ts +0 -57
  100. package/src/helpers/createPeerDescriptorSignaturePayload.ts +0 -28
  101. package/src/helpers/debugHelpers.ts +0 -9
  102. package/src/helpers/errors.ts +0 -49
  103. package/src/helpers/offering.ts +0 -15
  104. package/src/helpers/protoClasses.ts +0 -57
  105. package/src/helpers/protoToString.ts +0 -21
  106. package/src/helpers/version.ts +0 -32
  107. package/src/identifiers.ts +0 -29
  108. package/src/rpc-protocol/DhtCallContext.ts +0 -14
  109. package/src/rpc-protocol/DhtRpcOptions.ts +0 -10
  110. package/src/transport/ITransport.ts +0 -37
  111. package/src/transport/ListeningRpcCommunicator.ts +0 -32
  112. package/src/transport/RoutingRpcCommunicator.ts +0 -66
  113. package/src/types/ServiceID.ts +0 -1
  114. package/src/types/textencoding.d.ts +0 -6
  115. package/test/benchmark/Find.test.ts +0 -72
  116. package/test/benchmark/KademliaCorrectness.test.ts +0 -114
  117. package/test/benchmark/RingCorrectness.test.ts +0 -157
  118. package/test/benchmark/SortedContactListBenchmark.test.ts +0 -108
  119. package/test/benchmark/WebsocketServerMemoryLeak.test.ts +0 -41
  120. package/test/benchmark/hybrid-network-simulation/RingContactList.test.ts +0 -71
  121. package/test/end-to-end/GeoIpLayer0.test.ts +0 -55
  122. package/test/end-to-end/Layer0-Layer1.test.ts +0 -93
  123. package/test/end-to-end/Layer0.test.ts +0 -76
  124. package/test/end-to-end/Layer0MixedConnectionTypes.test.ts +0 -110
  125. package/test/end-to-end/Layer0Webrtc-Layer1.test.ts +0 -137
  126. package/test/end-to-end/Layer0Webrtc.test.ts +0 -85
  127. package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +0 -82
  128. package/test/end-to-end/Layer1-Scale-Webrtc.test.ts +0 -76
  129. package/test/end-to-end/RecoveryFromFailedAutoCertification.test.ts +0 -52
  130. package/test/end-to-end/WebsocketConnectionRequest.test.ts +0 -69
  131. package/test/end-to-end/memory-leak.test.ts +0 -80
  132. package/test/integration/ConnectionLocking.test.ts +0 -192
  133. package/test/integration/ConnectionManager.test.ts +0 -528
  134. package/test/integration/ConnectivityChecking.test.ts +0 -53
  135. package/test/integration/DhtJoinPeerDiscovery.test.ts +0 -49
  136. package/test/integration/DhtNode.test.ts +0 -66
  137. package/test/integration/DhtNodeExternalAPI.test.ts +0 -48
  138. package/test/integration/DhtNodeRpcRemote.test.ts +0 -66
  139. package/test/integration/DhtRpc.test.ts +0 -121
  140. package/test/integration/Find.test.ts +0 -45
  141. package/test/integration/GeoIpConnectivityChecking.test.ts +0 -72
  142. package/test/integration/Layer1-scale.test.ts +0 -189
  143. package/test/integration/Mock-Layer1-Layer0.test.ts +0 -85
  144. package/test/integration/MultipleEntryPointJoining.test.ts +0 -105
  145. package/test/integration/ReplicateData.test.ts +0 -104
  146. package/test/integration/RouteMessage.test.ts +0 -230
  147. package/test/integration/RouterRpcRemote.test.ts +0 -77
  148. package/test/integration/SimultaneousConnections.test.ts +0 -316
  149. package/test/integration/Store.test.ts +0 -85
  150. package/test/integration/StoreAndDelete.test.ts +0 -77
  151. package/test/integration/StoreOnDhtWithThreeNodes.test.ts +0 -59
  152. package/test/integration/StoreOnDhtWithTwoNodes.test.ts +0 -51
  153. package/test/integration/StoreRpcRemote.test.ts +0 -54
  154. package/test/integration/WebrtcConnectionManagement.test.ts +0 -191
  155. package/test/integration/WebrtcConnectorRpc.test.ts +0 -125
  156. package/test/integration/Websocket.test.ts +0 -65
  157. package/test/integration/WebsocketClientConnectorRpc.test.ts +0 -69
  158. package/test/integration/WebsocketConnectionManagement.test.ts +0 -191
  159. package/test/integration/rpc-connections-over-webrtc.test.ts +0 -123
  160. package/test/kademlia-simulation/data/nodeids.json +0 -13002
  161. package/test/kademlia-simulation/data/orderedneighbors.json +0 -1001
  162. package/test/types/global.d.ts +0 -1
  163. package/test/unit/AddressTools.test.ts +0 -44
  164. package/test/unit/AutoCertifierClientFacade.test.ts +0 -58
  165. package/test/unit/ConnectionManager.test.ts +0 -65
  166. package/test/unit/ConnectivityHelpers.test.ts +0 -61
  167. package/test/unit/DiscoverySession.test.ts +0 -87
  168. package/test/unit/DuplicateDetector.test.ts +0 -31
  169. package/test/unit/Handshaker.test.ts +0 -169
  170. package/test/unit/ListeningRpcCommunicator.test.ts +0 -52
  171. package/test/unit/LocalDataStore.test.ts +0 -108
  172. package/test/unit/ManagedConnection.test.ts +0 -58
  173. package/test/unit/PeerManager.test.ts +0 -93
  174. package/test/unit/PendingConnection.test.ts +0 -57
  175. package/test/unit/ProtobufMessage.test.ts +0 -21
  176. package/test/unit/RandomContactList.test.ts +0 -58
  177. package/test/unit/RecursiveOperationManager.test.ts +0 -161
  178. package/test/unit/RecursiveOperationSession.test.ts +0 -68
  179. package/test/unit/Router.test.ts +0 -137
  180. package/test/unit/RoutingSession.test.ts +0 -86
  181. package/test/unit/SortedContactList.test.ts +0 -115
  182. package/test/unit/StoreManager.test.ts +0 -146
  183. package/test/unit/StoreRpcLocal.test.ts +0 -167
  184. package/test/unit/WebrtcConnection.test.ts +0 -29
  185. package/test/unit/WebrtcConnector.test.ts +0 -56
  186. package/test/unit/WebsocketClientConnector.test.ts +0 -101
  187. package/test/unit/WebsocketServer.test.ts +0 -66
  188. package/test/unit/WebsocketServerConnector.test.ts +0 -102
  189. package/test/unit/connectivityRequestHandler.test.ts +0 -104
  190. package/test/unit/createPeerDescriptor.test.ts +0 -69
  191. package/test/unit/customMatchers.test.ts +0 -34
  192. package/test/unit/getClosestNodes.test.ts +0 -30
  193. package/test/unit/version.test.ts +0 -18
  194. package/test/unit/webrtcReplaceInternalIpWithExternalIp.test.ts +0 -18
  195. package/test/utils/FakeConnectorFacade.ts +0 -41
  196. package/test/utils/FakeRpcCommunicator.ts +0 -23
  197. package/test/utils/FakeTransport.ts +0 -79
  198. package/test/utils/customMatchers.ts +0 -71
  199. package/test/utils/mock/MockConnection.ts +0 -26
  200. package/test/utils/mock/MockConnectionsView.ts +0 -18
  201. package/test/utils/mock/MockRouter.ts +0 -62
  202. package/test/utils/mock/MockRpcCommunicator.ts +0 -7
  203. package/test/utils/mock/MockTransport.ts +0 -26
  204. package/test/utils/mock/mockDataEntry.ts +0 -38
  205. package/test/utils/topology.ts +0 -79
  206. package/test/utils/utils.ts +0 -268
  207. package/tsconfig.browser.json +0 -17
  208. package/tsconfig.jest.json +0 -25
  209. package/tsconfig.json +0 -3
  210. package/tsconfig.node.json +0 -24
@@ -1,122 +0,0 @@
1
- import EventEmitter from 'eventemitter3'
2
- import { createRandomConnectionId } from '../Connection'
3
- import { ConnectionEvents, ConnectionID, ConnectionType, IConnection } from '../IConnection'
4
- import { Logger } from '@streamr/utils'
5
-
6
- export interface Socket {
7
- binaryType: string
8
- readyState: number
9
- close(code?: number, reason?: string): void
10
- send(data: string | Buffer | ArrayBuffer | ArrayBufferView): void
11
- }
12
-
13
- // https://kapeli.com/cheat_sheets/WebSocket_Status_Codes.docset/Contents/Resources/Documents/index
14
- // Browsers send this automatically when closing a tab
15
- export const GOING_AWAY = 1001
16
- // The GOING_AWAY is a reserved code and we shouldn't send that from the application. Therefore
17
- // we have a custom counterpart
18
- export const CUSTOM_GOING_AWAY = 3001
19
- // https://github.com/websockets/ws/blob/master/doc/ws.md#ready-state-constants
20
- const OPEN = 1
21
-
22
- const logger = new Logger(module)
23
-
24
- export abstract class AbstractWebsocketClientConnection extends EventEmitter<ConnectionEvents> implements IConnection {
25
-
26
- public readonly connectionId: ConnectionID
27
- protected abstract socket?: Socket
28
- public connectionType = ConnectionType.WEBSOCKET_CLIENT
29
- protected destroyed = false
30
-
31
- constructor() {
32
- super()
33
- this.connectionId = createRandomConnectionId()
34
- }
35
-
36
- // TODO explicit default value for "selfSigned" or make it required
37
- public abstract connect(address: string, allowSelfSignedCertificate: boolean): void
38
-
39
- protected abstract stopListening(): void
40
-
41
- public send(data: Uint8Array): void {
42
- if (!this.destroyed) {
43
- if (this.socket && this.socket.readyState === OPEN) {
44
- logger.trace(`Sending data with size ${data.byteLength}`)
45
- this.socket?.send(data)
46
- } else {
47
- // Could this throw for faster feedback on RPC calls?
48
- // Currently this log line is seen if a connection is closing but the disconnected event has not been emitted yet.
49
- logger.debug('Tried to send data on a non-open connection', {
50
- id: this.connectionId,
51
- readyState: this.socket!.readyState,
52
- destroyed: this.destroyed
53
- })
54
- }
55
- } else {
56
- logger.debug('Tried to send() on stopped connection')
57
- }
58
- }
59
-
60
- public async close(gracefulLeave: boolean): Promise<void> {
61
- this.emit('disconnected', gracefulLeave, undefined, 'close() called')
62
- this.removeAllListeners()
63
- if (!this.destroyed) {
64
- logger.trace(`Closing socket for connection ${this.connectionId}`)
65
- this.socket?.close(gracefulLeave ? CUSTOM_GOING_AWAY : undefined)
66
- } else {
67
- logger.debug('Tried to close() a stopped connection', { id: this.connectionId })
68
- }
69
- }
70
-
71
- public destroy(): void {
72
- logger.trace('destroy() a connection')
73
- if (!this.destroyed) {
74
- this.removeAllListeners()
75
- if (this.socket) {
76
- this.stopListening()
77
- this.socket.close()
78
- this.socket = undefined
79
- }
80
- this.destroyed = true
81
- } else {
82
- logger.debug('Tried to destroy() a stopped connection')
83
- }
84
- }
85
-
86
- protected onOpen(): void {
87
- if (!this.destroyed) {
88
- logger.trace('WebSocket Client Connected')
89
- if (this.socket && this.socket.readyState === OPEN) {
90
- this.emit('connected')
91
- }
92
- }
93
- }
94
-
95
- protected onMessage(message: Uint8Array): void {
96
- this.emit('data', message)
97
- }
98
-
99
- protected onClose(code: number, reason: string): void {
100
- if (!this.destroyed) {
101
- logger.trace('Websocket Closed')
102
- this.doDisconnect(code, reason)
103
- }
104
- }
105
-
106
- protected onError(error: Error): void {
107
- if (!this.destroyed) {
108
- logger.trace('WebSocket Client error: ' + error?.message, { error })
109
- this.emit('error', error.name)
110
- }
111
- }
112
-
113
- protected doDisconnect(code?: number, reason?: string): void {
114
- this.destroyed = true
115
- this.stopListening()
116
- this.socket = undefined
117
- const gracefulLeave = (code === GOING_AWAY) || (code === CUSTOM_GOING_AWAY)
118
- this.emit('disconnected', gracefulLeave, code, reason)
119
- this.removeAllListeners()
120
- }
121
-
122
- }
@@ -1,89 +0,0 @@
1
- import {
2
- AutoCertifierClient,
3
- HasSessionRequest,
4
- HasSessionResponse,
5
- CertifiedSubdomain,
6
- SERVICE_ID as AUTO_CERTIFIER_SERVICE_ID,
7
- HasSession
8
- } from '@streamr/autocertifier-client'
9
- import { ListeningRpcCommunicator } from '../../transport/ListeningRpcCommunicator'
10
- import { Logger, waitForEvent3 } from '@streamr/utils'
11
- import { ITransport } from '../../transport/ITransport'
12
-
13
- const START_TIMEOUT = 60 * 1000
14
-
15
- const defaultAutoCertifierClientFactory = (
16
- configFile: string,
17
- autoCertifierUrl: string,
18
- autoCertifierRpcCommunicator: ListeningRpcCommunicator,
19
- wsServerPort: number
20
- ) => new AutoCertifierClient(
21
- configFile,
22
- wsServerPort,
23
- autoCertifierUrl,
24
- (_serviceId: string, rpcMethodName: string, method: HasSession) => {
25
- autoCertifierRpcCommunicator.registerRpcMethod(
26
- HasSessionRequest,
27
- HasSessionResponse,
28
- rpcMethodName,
29
- method
30
- )
31
- }
32
- )
33
-
34
- export interface IAutoCertifierClient {
35
- start(): Promise<void>
36
- stop(): void
37
- on(eventName: string, cb: (subdomain: CertifiedSubdomain) => void): void
38
- }
39
-
40
- interface AutoCertifierClientFacadeOptions {
41
- url: string
42
- configFile: string
43
- transport: ITransport
44
- wsServerPort: number
45
- // TODO: setHost and updateCertificate could be passed in a single onCertificateUpdated function.
46
- setHost: (host: string) => void
47
- updateCertificate: (certificate: string, privateKey: string) => void
48
- // TOD: could just pass the client?
49
- createClientFactory?: () => IAutoCertifierClient
50
- }
51
-
52
- const logger = new Logger(module)
53
-
54
- export class AutoCertifierClientFacade {
55
-
56
- private autoCertifierClient: IAutoCertifierClient
57
- private readonly rpcCommunicator: ListeningRpcCommunicator
58
- private readonly options: AutoCertifierClientFacadeOptions
59
-
60
- constructor(options: AutoCertifierClientFacadeOptions) {
61
- this.options = options
62
- this.rpcCommunicator = new ListeningRpcCommunicator(AUTO_CERTIFIER_SERVICE_ID, options.transport)
63
- this.autoCertifierClient = options.createClientFactory ? options.createClientFactory()
64
- : defaultAutoCertifierClientFactory(
65
- options.configFile,
66
- options.url,
67
- this.rpcCommunicator,
68
- options.wsServerPort
69
- )
70
- }
71
-
72
- async start(): Promise<void> {
73
- this.autoCertifierClient.on('updatedCertificate', (subdomain: CertifiedSubdomain) => {
74
- this.options.setHost(subdomain.fqdn)
75
- this.options.updateCertificate(subdomain.certificate, subdomain.privateKey)
76
- logger.trace(`Updated certificate`)
77
- })
78
- await Promise.all([
79
- waitForEvent3(this.autoCertifierClient as any, 'updatedCertificate', START_TIMEOUT),
80
- this.autoCertifierClient.start()
81
- ])
82
- }
83
-
84
- stop(): void {
85
- this.autoCertifierClient.stop()
86
- this.rpcCommunicator.destroy()
87
- }
88
-
89
- }
@@ -1,44 +0,0 @@
1
- import { Logger } from '@streamr/utils'
2
- import { ICloseEvent, IMessageEvent, w3cwebsocket as Websocket } from 'websocket'
3
- import { AbstractWebsocketClientConnection } from './AbstractWebsocketClientConnection'
4
-
5
- const logger = new Logger(module)
6
-
7
- const BINARY_TYPE = 'arraybuffer'
8
-
9
- export class WebsocketClientConnection extends AbstractWebsocketClientConnection {
10
-
11
- protected socket?: Websocket
12
-
13
- // TODO explicit default value for "selfSigned" or make it required
14
- public connect(address: string, selfSigned?: boolean): void {
15
- if (!this.destroyed) {
16
- this.socket = new Websocket(address, undefined, undefined, undefined, { rejectUnauthorized: !selfSigned })
17
- this.socket.binaryType = BINARY_TYPE
18
- this.socket.onerror = (error: Error) => this.onError(error)
19
- this.socket.onopen = () => this.onOpen()
20
- this.socket.onclose = (event: ICloseEvent) => this.onClose(event.code, event.reason)
21
- this.socket.onmessage = (message: IMessageEvent) => {
22
- if (!this.destroyed) {
23
- if (typeof message.data === 'string') {
24
- logger.debug('Received string data, only binary data is supported')
25
- } else {
26
- this.onMessage(new Uint8Array(message.data))
27
- }
28
- }
29
- }
30
- } else {
31
- logger.debug('Tried to connect() a stopped connection')
32
- }
33
- }
34
-
35
- protected stopListening(): void {
36
- if (this.socket) {
37
- this.socket.onopen = undefined as unknown as (() => void)
38
- this.socket.onclose = undefined as unknown as (() => void)
39
- this.socket.onerror = undefined as unknown as (() => void)
40
- this.socket.onmessage = undefined as unknown as (() => void)
41
- }
42
- }
43
-
44
- }
@@ -1,39 +0,0 @@
1
- import { Logger, binaryToUtf8 } from '@streamr/utils'
2
- import { WebSocket } from 'ws'
3
- import { AbstractWebsocketClientConnection } from './AbstractWebsocketClientConnection'
4
-
5
- const logger = new Logger(module)
6
-
7
- const BINARY_TYPE = 'nodebuffer'
8
-
9
- export class WebsocketClientConnection extends AbstractWebsocketClientConnection {
10
-
11
- protected socket?: WebSocket
12
-
13
- // TODO explicit default value for "selfSigned" or make it required
14
- public connect(address: string, selfSigned?: boolean): void {
15
- if (!this.destroyed) {
16
- this.socket = new WebSocket(address, { rejectUnauthorized: !selfSigned })
17
- this.socket.binaryType = BINARY_TYPE
18
- this.socket.on('error', (error: Error) => this.onError(error))
19
- this.socket.on('open', () => this.onOpen())
20
- this.socket.on('close', (code: number, reason: Buffer) => this.onClose(code, binaryToUtf8(reason)))
21
- this.socket.on('message', (message: Buffer, isBinary: boolean) => {
22
- if (!this.destroyed) {
23
- if (isBinary === false) {
24
- logger.debug('Received string data, only binary data is supported')
25
- } else {
26
- this.onMessage(new Uint8Array(message))
27
- }
28
- }
29
- })
30
- } else {
31
- logger.debug('Tried to connect() a stopped connection', { id: this.connectionId })
32
- }
33
- }
34
-
35
- protected stopListening(): void {
36
- this.socket?.removeAllListeners()
37
- }
38
-
39
- }
@@ -1,119 +0,0 @@
1
- import { WebsocketClientConnection } from './NodeWebsocketClientConnection'
2
- import { ConnectionType } from '../IConnection'
3
- import { ListeningRpcCommunicator } from '../../transport/ListeningRpcCommunicator'
4
- import { WebsocketClientConnectorRpcLocal } from './WebsocketClientConnectorRpcLocal'
5
- import {
6
- ConnectivityMethod,
7
- PeerDescriptor,
8
- WebsocketConnectionRequest
9
- } from '../../../generated/packages/dht/protos/DhtRpc'
10
- import { WebsocketServer } from './WebsocketServer'
11
- import { createOutgoingHandshaker } from '../Handshaker'
12
- import { ServerCallContext } from '@protobuf-ts/runtime-rpc'
13
- import { expectedConnectionType } from '../../helpers/Connectivity'
14
- import { Empty } from '../../../generated/google/protobuf/empty'
15
- import { DhtAddress, toNodeId } from '../../identifiers'
16
- import { GeoIpLocator } from '@streamr/geoip-location'
17
- import { PendingConnection } from '../PendingConnection'
18
-
19
- export type Action = 'connectivityRequest' | 'connectivityProbe'
20
-
21
- export const connectivityMethodToWebsocketUrl = (ws: ConnectivityMethod, action?: Action): string => {
22
- return (ws.tls ? 'wss://' : 'ws://') + ws.host + ':' + ws.port + ((action !== undefined) ? '?action=' + action : '')
23
- }
24
-
25
- export interface WebsocketClientConnectorOptions {
26
- onNewConnection: (connection: PendingConnection) => boolean
27
- hasConnection: (nodeId: DhtAddress) => boolean
28
- rpcCommunicator: ListeningRpcCommunicator
29
- }
30
-
31
- export class WebsocketClientConnector {
32
-
33
- public static readonly WEBSOCKET_CONNECTOR_SERVICE_ID = 'system/websocket-connector'
34
- private readonly websocketServer?: WebsocketServer
35
- private geoIpLocator?: GeoIpLocator
36
-
37
- private localPeerDescriptor?: PeerDescriptor
38
- private connectingConnections: Map<DhtAddress, PendingConnection> = new Map()
39
- private abortController = new AbortController()
40
- private readonly options: WebsocketClientConnectorOptions
41
-
42
- constructor(options: WebsocketClientConnectorOptions) {
43
- this.options = options
44
-
45
- this.registerLocalRpcMethods()
46
- }
47
-
48
- private registerLocalRpcMethods() {
49
- const rpcLocal = new WebsocketClientConnectorRpcLocal({
50
- connect: (targetPeerDescriptor: PeerDescriptor) => this.connect(targetPeerDescriptor),
51
- hasConnection: (nodeId: DhtAddress): boolean => (this.connectingConnections.has(nodeId)
52
- || this.options.hasConnection(nodeId))
53
- ,
54
- onNewConnection: (connection: PendingConnection) => this.options.onNewConnection(connection),
55
- abortSignal: this.abortController.signal
56
- })
57
- this.options.rpcCommunicator.registerRpcNotification(
58
- WebsocketConnectionRequest,
59
- 'requestConnection',
60
- async (req: WebsocketConnectionRequest, context: ServerCallContext): Promise<Empty> => {
61
- if (!this.abortController.signal.aborted) {
62
- return rpcLocal.requestConnection(req, context)
63
- } else {
64
- return {}
65
- }
66
- }
67
- )
68
- }
69
-
70
- public isPossibleToFormConnection(targetPeerDescriptor: PeerDescriptor): boolean {
71
- const connectionType = expectedConnectionType(this.localPeerDescriptor!, targetPeerDescriptor)
72
- return connectionType === ConnectionType.WEBSOCKET_CLIENT
73
- }
74
-
75
- public connect(targetPeerDescriptor: PeerDescriptor): PendingConnection {
76
- const nodeId = toNodeId(targetPeerDescriptor)
77
- const existingConnection = this.connectingConnections.get(nodeId)
78
- if (existingConnection) {
79
- return existingConnection
80
- }
81
- const socket = new WebsocketClientConnection()
82
-
83
- const url = connectivityMethodToWebsocketUrl(targetPeerDescriptor.websocket!)
84
-
85
- const pendingConnection = new PendingConnection(targetPeerDescriptor)
86
- createOutgoingHandshaker(this.localPeerDescriptor!, pendingConnection, socket, targetPeerDescriptor)
87
- this.connectingConnections.set(nodeId, pendingConnection)
88
-
89
- const delFunc = () => {
90
- if (this.connectingConnections.has(nodeId)) {
91
- this.connectingConnections.delete(nodeId)
92
- }
93
- socket.off('disconnected', delFunc)
94
- pendingConnection.off('disconnected', delFunc)
95
- pendingConnection.off('connected', delFunc)
96
- }
97
- socket.on('disconnected', delFunc)
98
- pendingConnection.on('disconnected', delFunc)
99
- pendingConnection.on('connected', delFunc)
100
-
101
- socket.connect(url, false)
102
-
103
- return pendingConnection
104
- }
105
-
106
- public setLocalPeerDescriptor(peerDescriptor: PeerDescriptor): void {
107
- this.localPeerDescriptor = peerDescriptor
108
- }
109
-
110
- public async destroy(): Promise<void> {
111
- this.abortController.abort()
112
-
113
- const requests = Array.from(this.connectingConnections.values())
114
- await Promise.allSettled(requests.map((conn) => conn.close(true)))
115
-
116
- await this.websocketServer?.stop()
117
- this.geoIpLocator?.stop()
118
- }
119
- }
@@ -1,38 +0,0 @@
1
- import { ServerCallContext } from '@protobuf-ts/runtime-rpc'
2
- import {
3
- PeerDescriptor,
4
- WebsocketConnectionRequest
5
- } from '../../../generated/packages/dht/protos/DhtRpc'
6
- import { IWebsocketClientConnectorRpc } from '../../../generated/packages/dht/protos/DhtRpc.server'
7
- import { DhtCallContext } from '../../rpc-protocol/DhtCallContext'
8
- import { Empty } from '../../../generated/google/protobuf/empty'
9
- import { toNodeId, DhtAddress } from '../../identifiers'
10
- import { PendingConnection } from '../PendingConnection'
11
-
12
- interface WebsocketClientConnectorRpcLocalOptions {
13
- connect: (targetPeerDescriptor: PeerDescriptor) => PendingConnection
14
- hasConnection: (nodeId: DhtAddress) => boolean
15
- onNewConnection: (connection: PendingConnection) => boolean
16
- abortSignal: AbortSignal
17
- }
18
-
19
- export class WebsocketClientConnectorRpcLocal implements IWebsocketClientConnectorRpc {
20
-
21
- private readonly options: WebsocketClientConnectorRpcLocalOptions
22
-
23
- constructor(options: WebsocketClientConnectorRpcLocalOptions) {
24
- this.options = options
25
- }
26
-
27
- public async requestConnection(_request: WebsocketConnectionRequest, context: ServerCallContext): Promise<Empty> {
28
- if (this.options.abortSignal.aborted) {
29
- return {}
30
- }
31
- const senderPeerDescriptor = (context as DhtCallContext).incomingSourceDescriptor!
32
- if (!this.options.hasConnection(toNodeId(senderPeerDescriptor))) {
33
- const connection = this.options.connect(senderPeerDescriptor)
34
- this.options.onNewConnection(connection)
35
- }
36
- return {}
37
- }
38
- }
@@ -1,19 +0,0 @@
1
- import {
2
- WebsocketConnectionRequest
3
- } from '../../../generated/packages/dht/protos/DhtRpc'
4
- import { Logger } from '@streamr/utils'
5
- import { RpcRemote } from '../../dht/contact/RpcRemote'
6
- import { WebsocketClientConnectorRpcClient } from '../../../generated/packages/dht/protos/DhtRpc.client'
7
- import { toNodeId } from '../../identifiers'
8
-
9
- const logger = new Logger(module)
10
-
11
- export class WebsocketClientConnectorRpcRemote extends RpcRemote<WebsocketClientConnectorRpcClient> {
12
-
13
- async requestConnection(): Promise<void> {
14
- logger.trace(`Requesting WebSocket connection from ${toNodeId(this.getLocalPeerDescriptor())}`)
15
- const request: WebsocketConnectionRequest = {}
16
- const options = this.formDhtRpcOptions()
17
- return this.getClient().requestConnection(request, options)
18
- }
19
- }
@@ -1,164 +0,0 @@
1
- import { createServer as createHttpServer, Server as HttpServer, IncomingMessage, ServerResponse } from 'http'
2
- import { createServer as createHttpsServer, Server as HttpsServer } from 'https'
3
- import EventEmitter from 'eventemitter3'
4
- import WebSocket from 'ws'
5
- import { WebsocketServerConnection } from './WebsocketServerConnection'
6
- import { Logger, asAbortable } from '@streamr/utils'
7
- import { createSelfSignedCertificate } from '@streamr/autocertifier-client'
8
- import { WebsocketServerStartError } from '../../helpers/errors'
9
- import { PortRange, TlsCertificate } from '../ConnectionManager'
10
- import { range } from 'lodash'
11
- import fs from 'fs'
12
- import { v4 as uuid } from 'uuid'
13
- import { parse } from 'url'
14
- import { IConnection } from '../IConnection'
15
-
16
- const logger = new Logger(module)
17
-
18
- interface WebsocketServerOptions {
19
- portRange: PortRange
20
- enableTls: boolean
21
- tlsCertificate?: TlsCertificate
22
- maxMessageSize?: number
23
- }
24
-
25
- interface Events {
26
- connected: ((connection: IConnection) => void)
27
- }
28
-
29
- export class WebsocketServer extends EventEmitter<Events> {
30
-
31
- private httpServer?: HttpServer | HttpsServer
32
- private wsServer?: WebSocket.Server
33
- private readonly abortController = new AbortController()
34
- private readonly options: WebsocketServerOptions
35
-
36
- constructor(options: WebsocketServerOptions) {
37
- super()
38
- this.options = options
39
- }
40
-
41
- public async start(): Promise<number> {
42
- const ports = range(this.options.portRange.min, this.options.portRange.max + 1)
43
- for (const port of ports) {
44
- try {
45
- await asAbortable(this.startServer(port, this.options.enableTls), this.abortController.signal)
46
- return port
47
- } catch (err) {
48
- if (err.originalError?.code === 'EADDRINUSE') {
49
- logger.debug(`failed to start WebSocket server on port: ${port} reattempting on next port`)
50
- } else {
51
- throw new WebsocketServerStartError(err)
52
- }
53
- }
54
- }
55
- throw new WebsocketServerStartError(
56
- `Failed to start WebSocket server on any port in range: ${this.options.portRange.min}-${this.options.portRange.min}`
57
- )
58
- }
59
-
60
- // If tlsCertificate has been given the tls boolean is ignored
61
- // TODO: could be simplified?
62
- private startServer(port: number, tls: boolean): Promise<void> {
63
- const requestListener = (request: IncomingMessage, response: ServerResponse<IncomingMessage>) => {
64
- logger.trace('Received request for ' + request.url)
65
- response.writeHead(404)
66
- response.end()
67
- }
68
- return new Promise((resolve, reject) => {
69
- if (this.options.tlsCertificate) {
70
- this.httpServer = createHttpsServer({
71
- key: fs.readFileSync(this.options.tlsCertificate.privateKeyFileName),
72
- cert: fs.readFileSync(this.options.tlsCertificate.certFileName)
73
- }, requestListener)
74
- } else if (!tls) {
75
- this.httpServer = createHttpServer(requestListener)
76
- } else {
77
- // TODO use options option or named constant?
78
- const certificate = createSelfSignedCertificate('streamr-self-signed-' + uuid(), 1000)
79
- this.httpServer = createHttpsServer({
80
- key: certificate.serverKey,
81
- cert: certificate.serverCert
82
- }, requestListener)
83
- }
84
-
85
- function originIsAllowed() {
86
- return true
87
- }
88
-
89
- this.wsServer = this.createWsServer()
90
-
91
- this.wsServer.on('connection', (ws: WebSocket, request: IncomingMessage) => {
92
- logger.trace(`New connection from ${request.socket.remoteAddress}`)
93
- if (!originIsAllowed()) {
94
- // Make sure we only accept requests from an allowed origin
95
- ws.close()
96
- logger.trace('IConnection from origin ' + request.headers.origin + ' rejected.')
97
- return
98
- }
99
- this.emit('connected', new WebsocketServerConnection(ws, parse(request.url!), request.socket.remoteAddress!))
100
- })
101
-
102
- this.httpServer.on('upgrade', (request, socket, head) => {
103
- logger.trace('Received upgrade request for ' + request.url)
104
- this.wsServer!.handleUpgrade(request, socket, head, (ws: WebSocket) => {
105
- this.wsServer!.emit('connection', ws, request)
106
- })
107
- })
108
-
109
- this.httpServer.once('error', (err: Error) => {
110
- reject(new WebsocketServerStartError('Starting Websocket server failed', err))
111
- })
112
-
113
- this.httpServer.once('listening', () => {
114
- logger.debug('Websocket server is listening on port ' + port)
115
- resolve()
116
- })
117
-
118
- try {
119
- // Listen only to IPv4 network interfaces, default value listens to IPv6 as well
120
- this.httpServer.listen(port, '0.0.0.0')
121
- } catch (e) {
122
- reject(new WebsocketServerStartError('Websocket server threw an exception', e))
123
- }
124
- })
125
- }
126
-
127
- public updateCertificate(cert: string, key: string): void {
128
- (this.httpServer! as HttpsServer).setSecureContext({
129
- cert,
130
- key
131
- })
132
- }
133
-
134
- public stop(): Promise<void> {
135
- this.abortController.abort()
136
- this.removeAllListeners()
137
- return new Promise((resolve, _reject) => {
138
- this.wsServer!.close()
139
- for (const ws of this.wsServer!.clients) {
140
- ws.terminate()
141
- }
142
- this.httpServer?.once('close', () => {
143
- // removeAllListeners is maybe not needed?
144
- this.httpServer?.removeAllListeners()
145
- resolve()
146
- })
147
- this.httpServer?.close()
148
- // the close method "Stops the server from accepting new connections and closes all
149
- // connections connected to this server which are not sending a request or waiting for a
150
- // response." (https://nodejs.org/api/http.html#serverclosecallback)
151
- // i.e. we need to call closeAllConnections() to close the rest of the connections
152
- // (in practice this closes the active websocket connections)
153
- this.httpServer?.closeAllConnections()
154
- })
155
- }
156
-
157
- private createWsServer(): WebSocket.Server {
158
- const maxPayload = this.options.maxMessageSize ?? 1048576
159
- return this.wsServer = new WebSocket.Server({
160
- noServer: true,
161
- maxPayload
162
- })
163
- }
164
- }