@streamr/dht 100.0.0-pretestnet.6 → 100.0.0-testnet-one.1

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 (260) hide show
  1. package/dist/src/connection/ConnectionLockHandler.js +2 -2
  2. package/dist/src/connection/ConnectionLockHandler.js.map +1 -1
  3. package/dist/src/connection/ConnectionLockRpcRemote.d.ts +2 -2
  4. package/dist/src/connection/ConnectionLockRpcRemote.js +3 -27
  5. package/dist/src/connection/ConnectionLockRpcRemote.js.map +1 -1
  6. package/dist/src/connection/ConnectionManager.d.ts +0 -1
  7. package/dist/src/connection/ConnectionManager.js +11 -7
  8. package/dist/src/connection/ConnectionManager.js.map +1 -1
  9. package/dist/src/connection/ConnectorFacade.d.ts +2 -2
  10. package/dist/src/connection/ConnectorFacade.js +1 -2
  11. package/dist/src/connection/ConnectorFacade.js.map +1 -1
  12. package/dist/src/connection/ManagedConnection.js +1 -0
  13. package/dist/src/connection/ManagedConnection.js.map +1 -1
  14. package/dist/src/connection/connectivityChecker.d.ts +9 -0
  15. package/dist/src/connection/connectivityChecker.js +122 -0
  16. package/dist/src/connection/connectivityChecker.js.map +1 -0
  17. package/dist/src/connection/connectivityRequestHandler.d.ts +2 -0
  18. package/dist/src/connection/connectivityRequestHandler.js +79 -0
  19. package/dist/src/connection/connectivityRequestHandler.js.map +1 -0
  20. package/dist/src/connection/simulator/Simulator.js +3 -2
  21. package/dist/src/connection/simulator/Simulator.js.map +1 -1
  22. package/dist/src/connection/simulator/SimulatorConnection.js +1 -1
  23. package/dist/src/connection/simulator/SimulatorConnection.js.map +1 -1
  24. package/dist/src/connection/webrtc/NodeWebrtcConnection.js +1 -1
  25. package/dist/src/connection/webrtc/NodeWebrtcConnection.js.map +1 -1
  26. package/dist/src/connection/webrtc/WebrtcConnector.js +1 -1
  27. package/dist/src/connection/webrtc/WebrtcConnector.js.map +1 -1
  28. package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js +1 -1
  29. package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js.map +1 -1
  30. package/dist/src/connection/webrtc/WebrtcConnectorRpcRemote.d.ts +2 -2
  31. package/dist/src/connection/webrtc/WebrtcConnectorRpcRemote.js +2 -2
  32. package/dist/src/connection/webrtc/WebrtcConnectorRpcRemote.js.map +1 -1
  33. package/dist/src/connection/webrtc/iceServerAsString.js +1 -1
  34. package/dist/src/connection/webrtc/iceServerAsString.js.map +1 -1
  35. package/dist/src/connection/websocket/ClientWebsocket.d.ts +1 -0
  36. package/dist/src/connection/websocket/ClientWebsocket.js +7 -3
  37. package/dist/src/connection/websocket/ClientWebsocket.js.map +1 -1
  38. package/dist/src/connection/websocket/ServerWebsocket.d.ts +4 -0
  39. package/dist/src/connection/websocket/ServerWebsocket.js +32 -21
  40. package/dist/src/connection/websocket/ServerWebsocket.js.map +1 -1
  41. package/dist/src/connection/websocket/WebsocketConnector.d.ts +0 -2
  42. package/dist/src/connection/websocket/WebsocketConnector.js +61 -16
  43. package/dist/src/connection/websocket/WebsocketConnector.js.map +1 -1
  44. package/dist/src/connection/websocket/WebsocketConnectorRpcLocal.d.ts +1 -1
  45. package/dist/src/connection/websocket/WebsocketConnectorRpcLocal.js +8 -11
  46. package/dist/src/connection/websocket/WebsocketConnectorRpcLocal.js.map +1 -1
  47. package/dist/src/connection/websocket/WebsocketConnectorRpcRemote.d.ts +4 -4
  48. package/dist/src/connection/websocket/WebsocketConnectorRpcRemote.js +5 -39
  49. package/dist/src/connection/websocket/WebsocketConnectorRpcRemote.js.map +1 -1
  50. package/dist/src/connection/websocket/WebsocketServer.js +21 -4
  51. package/dist/src/connection/websocket/WebsocketServer.js.map +1 -1
  52. package/dist/src/dht/DhtNode.d.ts +13 -23
  53. package/dist/src/dht/DhtNode.js +97 -226
  54. package/dist/src/dht/DhtNode.js.map +1 -1
  55. package/dist/src/dht/DhtNodeRpcLocal.d.ts +1 -4
  56. package/dist/src/dht/DhtNodeRpcLocal.js +1 -5
  57. package/dist/src/dht/DhtNodeRpcLocal.js.map +1 -1
  58. package/dist/src/dht/DhtNodeRpcRemote.d.ts +3 -3
  59. package/dist/src/dht/DhtNodeRpcRemote.js +4 -4
  60. package/dist/src/dht/DhtNodeRpcRemote.js.map +1 -1
  61. package/dist/src/dht/ExternalApiRpcLocal.d.ts +4 -4
  62. package/dist/src/dht/ExternalApiRpcLocal.js +5 -12
  63. package/dist/src/dht/ExternalApiRpcLocal.js.map +1 -1
  64. package/dist/src/dht/ExternalApiRpcRemote.d.ts +3 -3
  65. package/dist/src/dht/ExternalApiRpcRemote.js +5 -5
  66. package/dist/src/dht/ExternalApiRpcRemote.js.map +1 -1
  67. package/dist/src/dht/PeerManager.d.ts +52 -0
  68. package/dist/src/dht/PeerManager.js +273 -0
  69. package/dist/src/dht/PeerManager.js.map +1 -0
  70. package/dist/src/dht/contact/ContactList.d.ts +1 -1
  71. package/dist/src/dht/contact/ContactList.js +1 -0
  72. package/dist/src/dht/contact/ContactList.js.map +1 -1
  73. package/dist/src/dht/contact/{Remote.d.ts → RpcRemote.d.ts} +3 -3
  74. package/dist/src/dht/contact/{Remote.js → RpcRemote.js} +8 -8
  75. package/dist/src/dht/contact/RpcRemote.js.map +1 -0
  76. package/dist/src/dht/contact/SortedContactList.d.ts +20 -6
  77. package/dist/src/dht/contact/SortedContactList.js +55 -24
  78. package/dist/src/dht/contact/SortedContactList.js.map +1 -1
  79. package/dist/src/dht/discovery/DiscoverySession.d.ts +4 -14
  80. package/dist/src/dht/discovery/DiscoverySession.js +15 -26
  81. package/dist/src/dht/discovery/DiscoverySession.js.map +1 -1
  82. package/dist/src/dht/discovery/PeerDiscovery.d.ts +2 -9
  83. package/dist/src/dht/discovery/PeerDiscovery.js +11 -19
  84. package/dist/src/dht/discovery/PeerDiscovery.js.map +1 -1
  85. package/dist/src/dht/find/FindRpcLocal.js +2 -1
  86. package/dist/src/dht/find/FindRpcLocal.js.map +1 -1
  87. package/dist/src/dht/find/FindSession.d.ts +6 -6
  88. package/dist/src/dht/find/FindSession.js +18 -13
  89. package/dist/src/dht/find/FindSession.js.map +1 -1
  90. package/dist/src/dht/find/FindSessionRpcLocal.d.ts +1 -1
  91. package/dist/src/dht/find/FindSessionRpcRemote.d.ts +2 -2
  92. package/dist/src/dht/find/FindSessionRpcRemote.js +2 -2
  93. package/dist/src/dht/find/FindSessionRpcRemote.js.map +1 -1
  94. package/dist/src/dht/find/Finder.d.ts +4 -4
  95. package/dist/src/dht/find/Finder.js +55 -42
  96. package/dist/src/dht/find/Finder.js.map +1 -1
  97. package/dist/src/dht/routing/FindRpcRemote.d.ts +2 -2
  98. package/dist/src/dht/routing/FindRpcRemote.js +7 -5
  99. package/dist/src/dht/routing/FindRpcRemote.js.map +1 -1
  100. package/dist/src/dht/routing/Router.d.ts +3 -7
  101. package/dist/src/dht/routing/Router.js +29 -22
  102. package/dist/src/dht/routing/Router.js.map +1 -1
  103. package/dist/src/dht/routing/RouterRpcLocal.d.ts +2 -2
  104. package/dist/src/dht/routing/RouterRpcLocal.js +4 -3
  105. package/dist/src/dht/routing/RouterRpcLocal.js.map +1 -1
  106. package/dist/src/dht/routing/RouterRpcRemote.d.ts +2 -2
  107. package/dist/src/dht/routing/RouterRpcRemote.js +13 -8
  108. package/dist/src/dht/routing/RouterRpcRemote.js.map +1 -1
  109. package/dist/src/dht/routing/RoutingSession.d.ts +1 -1
  110. package/dist/src/dht/routing/RoutingSession.js +23 -11
  111. package/dist/src/dht/routing/RoutingSession.js.map +1 -1
  112. package/dist/src/dht/routing/getPreviousPeer.js.map +1 -1
  113. package/dist/src/dht/store/LocalDataStore.d.ts +3 -3
  114. package/dist/src/dht/store/LocalDataStore.js +18 -17
  115. package/dist/src/dht/store/LocalDataStore.js.map +1 -1
  116. package/dist/src/dht/store/StoreRpcLocal.d.ts +10 -9
  117. package/dist/src/dht/store/StoreRpcLocal.js +108 -102
  118. package/dist/src/dht/store/StoreRpcLocal.js.map +1 -1
  119. package/dist/src/dht/store/StoreRpcRemote.d.ts +4 -5
  120. package/dist/src/dht/store/StoreRpcRemote.js +6 -15
  121. package/dist/src/dht/store/StoreRpcRemote.js.map +1 -1
  122. package/dist/src/exports.d.ts +1 -1
  123. package/dist/src/exports.js +4 -4
  124. package/dist/src/exports.js.map +1 -1
  125. package/dist/src/helpers/PeerID.d.ts +1 -0
  126. package/dist/src/helpers/PeerID.js +9 -4
  127. package/dist/src/helpers/PeerID.js.map +1 -1
  128. package/dist/src/helpers/UUID.js +1 -1
  129. package/dist/src/helpers/UUID.js.map +1 -1
  130. package/dist/src/helpers/nodeId.d.ts +1 -0
  131. package/dist/src/helpers/{kademliaId.js → nodeId.js} +4 -4
  132. package/dist/src/helpers/nodeId.js.map +1 -0
  133. package/dist/src/helpers/peerIdFromPeerDescriptor.js +4 -4
  134. package/dist/src/helpers/peerIdFromPeerDescriptor.js.map +1 -1
  135. package/dist/src/proto/packages/dht/protos/DhtRpc.client.d.ts +5 -16
  136. package/dist/src/proto/packages/dht/protos/DhtRpc.client.js +2 -9
  137. package/dist/src/proto/packages/dht/protos/DhtRpc.client.js.map +1 -1
  138. package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +80 -95
  139. package/dist/src/proto/packages/dht/protos/DhtRpc.js +67 -66
  140. package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
  141. package/dist/src/proto/packages/dht/protos/DhtRpc.server.d.ts +3 -10
  142. package/dist/src/transport/RoutingRpcCommunicator.js +2 -0
  143. package/dist/src/transport/RoutingRpcCommunicator.js.map +1 -1
  144. package/karma.config.js +2 -2
  145. package/package.json +5 -5
  146. package/protos/DhtRpc.proto +36 -36
  147. package/src/connection/ConnectionLockHandler.ts +2 -2
  148. package/src/connection/ConnectionLockRpcRemote.ts +3 -4
  149. package/src/connection/ConnectionManager.ts +19 -17
  150. package/src/connection/ConnectorFacade.ts +5 -7
  151. package/src/connection/ManagedConnection.ts +1 -0
  152. package/src/connection/connectivityChecker.ts +102 -0
  153. package/src/connection/connectivityRequestHandler.ts +79 -0
  154. package/src/connection/simulator/Simulator.ts +3 -2
  155. package/src/connection/simulator/SimulatorConnection.ts +1 -1
  156. package/src/connection/webrtc/BrowserWebrtcConnection.ts +10 -10
  157. package/src/connection/webrtc/NodeWebrtcConnection.ts +1 -1
  158. package/src/connection/webrtc/WebrtcConnector.ts +1 -1
  159. package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +1 -1
  160. package/src/connection/webrtc/WebrtcConnectorRpcRemote.ts +2 -2
  161. package/src/connection/webrtc/iceServerAsString.ts +1 -1
  162. package/src/connection/websocket/ClientWebsocket.ts +6 -2
  163. package/src/connection/websocket/ServerWebsocket.ts +40 -25
  164. package/src/connection/websocket/WebsocketConnector.ts +43 -22
  165. package/src/connection/websocket/WebsocketConnectorRpcLocal.ts +9 -11
  166. package/src/connection/websocket/WebsocketConnectorRpcRemote.ts +7 -16
  167. package/src/connection/websocket/WebsocketServer.ts +20 -5
  168. package/src/dht/DhtNode.ts +123 -280
  169. package/src/dht/DhtNodeRpcLocal.ts +2 -9
  170. package/src/dht/DhtNodeRpcRemote.ts +4 -4
  171. package/src/dht/ExternalApiRpcLocal.ts +8 -13
  172. package/src/dht/ExternalApiRpcRemote.ts +5 -5
  173. package/src/dht/PeerManager.ts +330 -0
  174. package/src/dht/contact/ContactList.ts +3 -2
  175. package/src/dht/contact/{Remote.ts → RpcRemote.ts} +7 -6
  176. package/src/dht/contact/SortedContactList.ts +87 -44
  177. package/src/dht/discovery/DiscoverySession.ts +19 -44
  178. package/src/dht/discovery/PeerDiscovery.ts +16 -28
  179. package/src/dht/find/FindRpcLocal.ts +2 -2
  180. package/src/dht/find/FindSession.ts +25 -20
  181. package/src/dht/find/FindSessionRpcLocal.ts +1 -1
  182. package/src/dht/find/FindSessionRpcRemote.ts +2 -2
  183. package/src/dht/find/Finder.ts +84 -64
  184. package/src/dht/routing/FindRpcRemote.ts +7 -5
  185. package/src/dht/routing/Router.ts +30 -25
  186. package/src/dht/routing/RouterRpcLocal.ts +5 -5
  187. package/src/dht/routing/RouterRpcRemote.ts +13 -10
  188. package/src/dht/routing/RoutingSession.ts +22 -17
  189. package/src/dht/routing/getPreviousPeer.ts +1 -1
  190. package/src/dht/store/LocalDataStore.ts +18 -17
  191. package/src/dht/store/StoreRpcLocal.ts +118 -113
  192. package/src/dht/store/StoreRpcRemote.ts +7 -23
  193. package/src/exports.ts +1 -1
  194. package/src/helpers/PeerID.ts +8 -4
  195. package/src/helpers/UUID.ts +1 -1
  196. package/src/helpers/{kademliaId.ts → nodeId.ts} +1 -1
  197. package/src/helpers/peerIdFromPeerDescriptor.ts +6 -6
  198. package/src/proto/packages/dht/protos/DhtRpc.client.ts +6 -20
  199. package/src/proto/packages/dht/protos/DhtRpc.server.ts +3 -10
  200. package/src/proto/packages/dht/protos/DhtRpc.ts +103 -135
  201. package/src/transport/RoutingRpcCommunicator.ts +2 -0
  202. package/test/benchmark/Find.test.ts +5 -5
  203. package/test/benchmark/KademliaCorrectness.test.ts +3 -3
  204. package/test/benchmark/SortedContactListBenchmark.test.ts +150 -0
  205. package/test/benchmark/WebsocketServerMemoryLeak.test.ts +41 -0
  206. package/test/benchmark/kademlia-simulation/Contact.ts +1 -1
  207. package/test/benchmark/kademlia-simulation/KademliaSimulation.ts +1 -1
  208. package/test/benchmark/kademlia-simulation/SimulationNode.ts +6 -1
  209. package/test/end-to-end/Layer0-Layer1.test.ts +1 -1
  210. package/test/end-to-end/Layer0.test.ts +4 -4
  211. package/test/end-to-end/Layer0MixedConnectionTypes.test.ts +11 -11
  212. package/test/end-to-end/Layer0Webrtc-Layer1.test.ts +6 -6
  213. package/test/end-to-end/Layer0Webrtc.test.ts +2 -2
  214. package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +3 -3
  215. package/test/end-to-end/Layer1-Scale-Webrtc.test.ts +3 -3
  216. package/test/end-to-end/RecoveryFromFailedAutoCertification.test.ts +1 -1
  217. package/test/end-to-end/WebsocketConnectionRequest.test.ts +1 -1
  218. package/test/end-to-end/memory-leak.test.ts +9 -12
  219. package/test/integration/ConnectionLocking.test.ts +2 -2
  220. package/test/integration/ConnectionManager.test.ts +14 -14
  221. package/test/integration/DhtJoinPeerDiscovery.test.ts +3 -3
  222. package/test/integration/DhtNodeExternalAPI.test.ts +10 -7
  223. package/test/integration/DhtNodeRpcRemote.test.ts +4 -4
  224. package/test/integration/DhtRpc.test.ts +6 -6
  225. package/test/integration/Find.test.ts +3 -3
  226. package/test/integration/Layer1-scale.test.ts +3 -3
  227. package/test/integration/Mock-Layer1-Layer0.test.ts +16 -16
  228. package/test/integration/MultipleEntryPointJoining.test.ts +7 -7
  229. package/test/integration/{MigrateData.test.ts → ReplicateData.test.ts} +15 -10
  230. package/test/integration/RouteMessage.test.ts +2 -2
  231. package/test/integration/RouterRpcRemote.test.ts +2 -2
  232. package/test/integration/RpcErrors.test.ts +2 -2
  233. package/test/integration/ScaleDownDht.test.ts +4 -2
  234. package/test/integration/SimultaneousConnections.test.ts +89 -57
  235. package/test/integration/Store.test.ts +33 -13
  236. package/test/integration/StoreAndDelete.test.ts +19 -17
  237. package/test/integration/StoreOnDhtWithTwoNodes.test.ts +21 -21
  238. package/test/integration/StoreRpcRemote.test.ts +3 -3
  239. package/test/integration/WebrtcConnectionManagement.test.ts +2 -2
  240. package/test/integration/WebrtcConnectorRpc.test.ts +1 -1
  241. package/test/integration/WebsocketConnectionManagement.test.ts +41 -3
  242. package/test/integration/WebsocketConnectorRpc.test.ts +5 -7
  243. package/test/unit/ConnectivityHelpers.test.ts +4 -4
  244. package/test/unit/Finder.test.ts +69 -23
  245. package/test/unit/LocalDataStore.test.ts +60 -43
  246. package/test/unit/RandomContactList.test.ts +2 -2
  247. package/test/unit/Router.test.ts +19 -11
  248. package/test/unit/RoutingSession.test.ts +76 -0
  249. package/test/unit/SortedContactList.test.ts +17 -12
  250. package/test/unit/WebsocketConnector.test.ts +1 -1
  251. package/test/unit/connectivityRequestHandler.test.ts +71 -0
  252. package/test/utils/mock/Router.ts +1 -1
  253. package/test/utils/utils.ts +24 -22
  254. package/dist/src/connection/ConnectivityChecker.d.ts +0 -17
  255. package/dist/src/connection/ConnectivityChecker.js +0 -208
  256. package/dist/src/connection/ConnectivityChecker.js.map +0 -1
  257. package/dist/src/dht/contact/Remote.js.map +0 -1
  258. package/dist/src/helpers/kademliaId.d.ts +0 -1
  259. package/dist/src/helpers/kademliaId.js.map +0 -1
  260. package/src/connection/ConnectivityChecker.ts +0 -199
@@ -0,0 +1,102 @@
1
+ import { Logger, RunAndRaceEventsReturnType, runAndRaceEvents3 } from '@streamr/utils'
2
+ import { v4 } from 'uuid'
3
+ import * as Err from '../helpers/errors'
4
+ import {
5
+ ConnectivityRequest, ConnectivityResponse,
6
+ Message, MessageType, PeerDescriptor
7
+ } from '../proto/packages/dht/protos/DhtRpc'
8
+ import { ConnectionEvents, IConnection } from './IConnection'
9
+ import { ClientWebsocket } from './websocket/ClientWebsocket'
10
+ import { connectivityMethodToWebsocketUrl } from './websocket/WebsocketConnector'
11
+
12
+ const logger = new Logger(module)
13
+
14
+ export const connectAsync = async ({ url, selfSigned, timeoutMs = 1000 }:
15
+ { url: string, selfSigned: boolean, timeoutMs?: number }
16
+ ): Promise<IConnection> => {
17
+ const socket = new ClientWebsocket()
18
+ let result: RunAndRaceEventsReturnType<ConnectionEvents>
19
+ try {
20
+ result = await runAndRaceEvents3<ConnectionEvents>([
21
+ () => { socket.connect(url, selfSigned) }],
22
+ socket, ['connected', 'error'],
23
+ timeoutMs)
24
+ } catch (e) {
25
+ throw new Err.ConnectionFailed('WebSocket connection timed out')
26
+ }
27
+ if (result.winnerName === 'error') {
28
+ throw new Err.ConnectionFailed('Could not open WebSocket connection')
29
+ }
30
+ return socket
31
+ }
32
+
33
+ export const CONNECTIVITY_CHECKER_SERVICE_ID = 'system/connectivity-checker'
34
+ const CONNECTIVITY_CHECKER_TIMEOUT = 5000
35
+
36
+ export const sendConnectivityRequest = async (
37
+ request: ConnectivityRequest,
38
+ entryPoint: PeerDescriptor
39
+ ): Promise<ConnectivityResponse> => {
40
+ let outgoingConnection: IConnection
41
+ const wsServerInfo = {
42
+ host: entryPoint.websocket!.host,
43
+ port: entryPoint.websocket!.port,
44
+ tls: entryPoint.websocket!.tls,
45
+ }
46
+ const url = connectivityMethodToWebsocketUrl(wsServerInfo, 'connectivityRequest')
47
+ logger.debug(`Attempting connectivity check with entrypoint ${url}`)
48
+ try {
49
+ outgoingConnection = await connectAsync({
50
+ url,
51
+ selfSigned: request.selfSigned
52
+ })
53
+ } catch (e) {
54
+ throw new Err.ConnectionFailed(`Failed to connect to entrypoint for connectivity check: ${url}`, e)
55
+ }
56
+ // send connectivity request
57
+ const msg: Message = {
58
+ serviceId: CONNECTIVITY_CHECKER_SERVICE_ID,
59
+ messageType: MessageType.CONNECTIVITY_REQUEST, messageId: v4(),
60
+ body: {
61
+ oneofKind: 'connectivityRequest',
62
+ connectivityRequest: request
63
+ }
64
+ }
65
+ const responseAwaiter = () => {
66
+ return new Promise((resolve: (res: ConnectivityResponse) => void, reject) => {
67
+ const timeoutId = setTimeout(() => {
68
+ // TODO should we have some handling for this floating promise?
69
+ outgoingConnection.close(false)
70
+ reject(new Err.ConnectivityResponseTimeout('timeout'))
71
+ }, CONNECTIVITY_CHECKER_TIMEOUT)
72
+ const listener = (bytes: Uint8Array) => {
73
+ // TODO should we have some handling for this floating promise?
74
+ outgoingConnection.close(false)
75
+ try {
76
+ const message: Message = Message.fromBinary(bytes)
77
+ if (message.body.oneofKind === 'connectivityResponse') {
78
+ logger.debug('ConnectivityResponse received: ' + JSON.stringify(Message.toJson(message)))
79
+ const connectivityResponseMessage = message.body.connectivityResponse
80
+ outgoingConnection!.off('data', listener)
81
+ clearTimeout(timeoutId)
82
+ resolve(connectivityResponseMessage)
83
+ } else {
84
+ return
85
+ }
86
+ } catch (err) {
87
+ logger.trace(`Could not parse message: ${err}`)
88
+ }
89
+ }
90
+ outgoingConnection!.on('data', listener)
91
+ })
92
+ }
93
+ try {
94
+ const retPromise = responseAwaiter()
95
+ outgoingConnection.send(Message.toBinary(msg))
96
+ logger.trace('ConnectivityRequest sent: ' + JSON.stringify(Message.toJson(msg)))
97
+ return await retPromise
98
+ } catch (e) {
99
+ logger.error('error getting connectivityresponse')
100
+ throw e
101
+ }
102
+ }
@@ -0,0 +1,79 @@
1
+ import { Logger } from '@streamr/utils'
2
+ import { v4 } from 'uuid'
3
+ import {
4
+ ConnectivityRequest, ConnectivityResponse,
5
+ Message, MessageType
6
+ } from '../proto/packages/dht/protos/DhtRpc'
7
+ import { NatType } from './ConnectionManager'
8
+ import { CONNECTIVITY_CHECKER_SERVICE_ID, connectAsync } from './connectivityChecker'
9
+ import { IConnection } from './IConnection'
10
+ import { ServerWebsocket } from './websocket/ServerWebsocket'
11
+ import { connectivityMethodToWebsocketUrl } from './websocket/WebsocketConnector'
12
+
13
+ const logger = new Logger(module)
14
+
15
+ export const attachConnectivityRequestHandler = (connectionToListenTo: ServerWebsocket): void => {
16
+ connectionToListenTo.on('data', async (data: Uint8Array) => {
17
+ logger.trace('server received data')
18
+ try {
19
+ const message = Message.fromBinary(data)
20
+ if (message.body.oneofKind === 'connectivityRequest') {
21
+ logger.trace('ConnectivityRequest received: ' + JSON.stringify(Message.toJson(message)))
22
+ try {
23
+ await handleIncomingConnectivityRequest(connectionToListenTo, message.body.connectivityRequest)
24
+ logger.trace('handleIncomingConnectivityRequest ok')
25
+ } catch (e) {
26
+ logger.error('handleIncomingConnectivityRequest', { error: e })
27
+ }
28
+ }
29
+ } catch (err) {
30
+ logger.trace(`Could not parse message: ${err}`)
31
+ }
32
+ })
33
+ }
34
+
35
+ const handleIncomingConnectivityRequest = async (connection: ServerWebsocket, connectivityRequest: ConnectivityRequest): Promise<void> => {
36
+ let outgoingConnection: IConnection | undefined
37
+ let connectivityResponseMessage: ConnectivityResponse | undefined
38
+ const host = connectivityRequest.host ?? connection.getRemoteAddress()
39
+ try {
40
+ const wsServerInfo = {
41
+ host,
42
+ port: connectivityRequest.port,
43
+ tls: connectivityRequest.tls
44
+ }
45
+ const url = connectivityMethodToWebsocketUrl(wsServerInfo, 'connectivityProbe')
46
+ logger.trace(`Attempting Connectivity Check to ${url}`)
47
+ outgoingConnection = await connectAsync({
48
+ url,
49
+ selfSigned: connectivityRequest.selfSigned
50
+ })
51
+ } catch (err) {
52
+ logger.debug('error', { err })
53
+ connectivityResponseMessage = {
54
+ host,
55
+ natType: NatType.UNKNOWN
56
+ }
57
+ }
58
+ if (outgoingConnection) {
59
+ // TODO should we have some handling for this floating promise?
60
+ outgoingConnection.close(false)
61
+ logger.trace('Connectivity test produced positive result, communicating reply to the requester ' + host + ':' + connectivityRequest.port)
62
+ connectivityResponseMessage = {
63
+ host,
64
+ natType: NatType.OPEN_INTERNET,
65
+ websocket: { host, port: connectivityRequest.port, tls: connectivityRequest.tls }
66
+ }
67
+ }
68
+ const msg: Message = {
69
+ serviceId: CONNECTIVITY_CHECKER_SERVICE_ID,
70
+ messageType: MessageType.CONNECTIVITY_RESPONSE,
71
+ messageId: v4(),
72
+ body: {
73
+ oneofKind: 'connectivityResponse',
74
+ connectivityResponse: connectivityResponseMessage!
75
+ }
76
+ }
77
+ connection.send(Message.toBinary(msg))
78
+ logger.trace('ConnectivityResponse sent: ' + JSON.stringify(Message.toJson(msg)))
79
+ }
@@ -148,7 +148,7 @@ export class Simulator extends EventEmitter<ConnectionSourceEvents> {
148
148
  this.latencyTable = getRegionDelayMatrix()
149
149
  }
150
150
 
151
- if (this.latencyType === LatencyType.FIXED && !this.fixedLatency) {
151
+ if ((this.latencyType === LatencyType.FIXED) && (this.fixedLatency === undefined)) {
152
152
  throw new Error('LatencyType.FIXED requires the desired latency to be given as second parameter')
153
153
  }
154
154
 
@@ -185,7 +185,7 @@ export class Simulator extends EventEmitter<ConnectionSourceEvents> {
185
185
 
186
186
  if (sourceRegion === undefined || targetRegion === undefined || sourceRegion > 15 || targetRegion > 15) {
187
187
  logger.error('invalid region index given to Simulator')
188
- throw ('invalid region index given to Simulator')
188
+ throw new Error('invalid region index given to Simulator')
189
189
  }
190
190
 
191
191
  latency = this.latencyTable![sourceRegion][targetRegion]
@@ -313,6 +313,7 @@ export class Simulator extends EventEmitter<ConnectionSourceEvents> {
313
313
  this.simulatorTimeout = setTimeout(this.executeQueuedOperations, timeDifference)
314
314
 
315
315
  if (Simulator.clock) {
316
+ // TODO should we have some handling for this floating promise?
316
317
  Simulator.clock.runAllAsync()
317
318
  }
318
319
  }
@@ -85,7 +85,7 @@ export class SimulatorConnection extends Connection implements IConnection {
85
85
  logger.trace('connect() called')
86
86
 
87
87
  this.simulator.connect(this, this.targetPeerDescriptor, (error?: string) => {
88
- if (error) {
88
+ if (error !== undefined) {
89
89
  logger.trace(error)
90
90
  this.doDisconnect(false)
91
91
  } else {
@@ -51,7 +51,7 @@ export class NodeWebrtcConnection extends EventEmitter<Events> implements IWebrt
51
51
  this.peerConnection = new RTCPeerConnection({ iceServers: urls })
52
52
 
53
53
  this.peerConnection.onicecandidate = (event) => {
54
- if (event.candidate && event.candidate.sdpMid) {
54
+ if ((event.candidate !== null) && (event.candidate.sdpMid !== null)) {
55
55
  this.emit('localCandidate', event.candidate.candidate, event.candidate.sdpMid)
56
56
  }
57
57
  }
@@ -63,14 +63,14 @@ export class NodeWebrtcConnection extends EventEmitter<Events> implements IWebrt
63
63
  if (isOffering) {
64
64
  this.peerConnection.onnegotiationneeded = async () => {
65
65
  try {
66
- if (this.peerConnection) {
66
+ if (this.peerConnection !== undefined) {
67
67
  this.makingOffer = true
68
68
  try {
69
69
  await this.peerConnection.setLocalDescription()
70
70
  } catch (err) {
71
71
  logger.warn('error', { err })
72
72
  }
73
- if (this.peerConnection.localDescription) {
73
+ if (this.peerConnection.localDescription !== null) {
74
74
  this.emit('localDescription', this.peerConnection.localDescription?.sdp, this.peerConnection.localDescription?.type)
75
75
  }
76
76
  }
@@ -93,7 +93,7 @@ export class NodeWebrtcConnection extends EventEmitter<Events> implements IWebrt
93
93
  }
94
94
 
95
95
  public async setRemoteDescription(description: string, type: string): Promise<void> {
96
- const offerCollision = (type.toLowerCase() === RtcDescription.OFFER) && (this.makingOffer || !this.peerConnection ||
96
+ const offerCollision = (type.toLowerCase() === RtcDescription.OFFER) && (this.makingOffer || (this.peerConnection === undefined) ||
97
97
  this.peerConnection.signalingState != 'stable')
98
98
 
99
99
  const ignoreOffer = this.isOffering && offerCollision
@@ -106,13 +106,13 @@ export class NodeWebrtcConnection extends EventEmitter<Events> implements IWebrt
106
106
  logger.warn('error', { err })
107
107
  }
108
108
 
109
- if (type.toLowerCase() === RtcDescription.OFFER && this.peerConnection) {
109
+ if ((type.toLowerCase() === RtcDescription.OFFER) && (this.peerConnection !== undefined)) {
110
110
  try {
111
111
  await this.peerConnection.setLocalDescription()
112
112
  } catch (err) {
113
113
  logger.warn('error', { err })
114
114
  }
115
- if (this.peerConnection.localDescription) {
115
+ if (this.peerConnection.localDescription !== null) {
116
116
  this.emit('localDescription', this.peerConnection.localDescription.sdp, this.peerConnection.localDescription.type)
117
117
  }
118
118
  }
@@ -148,7 +148,7 @@ export class NodeWebrtcConnection extends EventEmitter<Events> implements IWebrt
148
148
 
149
149
  this.removeAllListeners()
150
150
 
151
- if (this.dataChannel) {
151
+ if (this.dataChannel !== undefined) {
152
152
  try {
153
153
  this.dataChannel.close()
154
154
  } catch (e) {
@@ -158,7 +158,7 @@ export class NodeWebrtcConnection extends EventEmitter<Events> implements IWebrt
158
158
 
159
159
  this.dataChannel = undefined
160
160
 
161
- if (this.peerConnection) {
161
+ if (this.peerConnection !== undefined) {
162
162
  try {
163
163
  this.peerConnection.close()
164
164
  } catch (e) {
@@ -209,7 +209,7 @@ export class NodeWebrtcConnection extends EventEmitter<Events> implements IWebrt
209
209
  }
210
210
 
211
211
  private stopListening() {
212
- if (this.dataChannel) {
212
+ if (this.dataChannel !== undefined) {
213
213
  this.dataChannel.onopen = null
214
214
  this.dataChannel.onclose = null
215
215
  this.dataChannel.onerror = null
@@ -217,7 +217,7 @@ export class NodeWebrtcConnection extends EventEmitter<Events> implements IWebrt
217
217
  this.dataChannel.onmessage = null
218
218
  }
219
219
 
220
- if (this.peerConnection) {
220
+ if (this.peerConnection !== undefined) {
221
221
  this.peerConnection.onicecandidate = null
222
222
  this.peerConnection.onicegatheringstatechange = null
223
223
  this.peerConnection.onnegotiationneeded = null
@@ -161,7 +161,7 @@ export class NodeWebrtcConnection extends EventEmitter<Events> implements IConne
161
161
  if (!this.closed) {
162
162
  logger.trace(
163
163
  `Closing Node WebRTC Connection to ${getNodeIdFromPeerDescriptor(this.remotePeerDescriptor)}`
164
- + `${reason ? `, reason: ${reason}` : ''}`
164
+ + `${(reason !== undefined) ? `, reason: ${reason}` : ''}`
165
165
  )
166
166
 
167
167
  this.closed = true
@@ -178,7 +178,7 @@ export class WebrtcConnector {
178
178
  )
179
179
 
180
180
  connection.on('localCandidate', (candidate: string, mid: string) => {
181
- if (this.config.externalIp) {
181
+ if (this.config.externalIp !== undefined) {
182
182
  candidate = replaceInternalIpWithExternalIp(candidate, this.config.externalIp)
183
183
  logger.debug(`onLocalCandidate injected external ip ${candidate} ${mid}`)
184
184
  }
@@ -123,7 +123,7 @@ export class WebrtcConnectorRpcLocal implements IWebrtcConnectorRpc {
123
123
  private isIceCandidateAllowed(candidate: string): boolean {
124
124
  if (!this.config.allowPrivateAddresses) {
125
125
  const address = getAddressFromIceCandidate(candidate)
126
- if (address && isPrivateIPv4(address)) {
126
+ if ((address !== undefined) && isPrivateIPv4(address)) {
127
127
  return false
128
128
  }
129
129
  }
@@ -1,4 +1,4 @@
1
- import { Remote } from '../../dht/contact/Remote'
1
+ import { RpcRemote } from '../../dht/contact/RpcRemote'
2
2
  import {
3
3
  IceCandidate,
4
4
  PeerDescriptor,
@@ -12,7 +12,7 @@ import { Logger } from '@streamr/utils'
12
12
 
13
13
  const logger = new Logger(module)
14
14
 
15
- export class WebrtcConnectorRpcRemote extends Remote<IWebrtcConnectorRpcClient> {
15
+ export class WebrtcConnectorRpcRemote extends RpcRemote<IWebrtcConnectorRpcClient> {
16
16
 
17
17
  constructor(
18
18
  localPeerDescriptor: PeerDescriptor,
@@ -9,7 +9,7 @@ export function iceServerAsString({ url, port, username, password, tcp }: IceSer
9
9
  return `${protocol}:${hostname}:${port}`
10
10
  }
11
11
  if (username !== undefined && password !== undefined) {
12
- return `${protocol}:${username}:${password}@${hostname}:${port}${tcp ? '?transport=tcp' : ''}`
12
+ return `${protocol}:${username}:${password}@${hostname}:${port}${(tcp !== undefined) ? '?transport=tcp' : ''}`
13
13
  }
14
14
  throw new Error(`username (${username}) and password (${password}) must be supplied together`)
15
15
  }
@@ -8,6 +8,9 @@ const logger = new Logger(module)
8
8
  // https://kapeli.com/cheat_sheets/WebSocket_Status_Codes.docset/Contents/Resources/Documents/index
9
9
  // Browsers send this automatically when closing a tab
10
10
  export const GOING_AWAY = 1001
11
+ // The GOING_AWAY is a reserved code and we shouldn't send that from the application. Therefore
12
+ // we have a custom counterpart
13
+ export const CUSTOM_GOING_AWAY = 3001
11
14
 
12
15
  const BINARY_TYPE = 'arraybuffer'
13
16
 
@@ -23,6 +26,7 @@ export class ClientWebsocket extends EventEmitter<ConnectionEvents> implements I
23
26
  this.connectionId = new ConnectionID()
24
27
  }
25
28
 
29
+ // TODO explicit default value for "selfSigned" or make it required
26
30
  public connect(address: string, selfSigned?: boolean): void {
27
31
  if (!this.destroyed) {
28
32
  this.socket = new Websocket(address, undefined, undefined, undefined, { rejectUnauthorized: !selfSigned })
@@ -68,7 +72,7 @@ export class ClientWebsocket extends EventEmitter<ConnectionEvents> implements I
68
72
  this.destroyed = true
69
73
  this.stopListening()
70
74
  this.socket = undefined
71
- const gracefulLeave = code === GOING_AWAY
75
+ const gracefulLeave = (code === GOING_AWAY) || (code === CUSTOM_GOING_AWAY)
72
76
  this.emit('disconnected', gracefulLeave, code, reason)
73
77
  this.removeAllListeners()
74
78
  }
@@ -91,7 +95,7 @@ export class ClientWebsocket extends EventEmitter<ConnectionEvents> implements I
91
95
  this.removeAllListeners()
92
96
  if (!this.destroyed) {
93
97
  logger.trace(`Closing socket for connection ${this.connectionId.toString()}`)
94
- this.socket?.close(gracefulLeave === true ? GOING_AWAY : undefined)
98
+ this.socket?.close(gracefulLeave ? CUSTOM_GOING_AWAY : undefined)
95
99
  } else {
96
100
  logger.debug('Tried to close() a stopped connection')
97
101
  }
@@ -1,9 +1,9 @@
1
1
  import EventEmitter from 'eventemitter3'
2
2
  import { IConnection, ConnectionID, ConnectionEvents, ConnectionType } from '../IConnection'
3
- import { connection as WsConnection } from 'websocket'
3
+ import { Message, connection as WsConnection } from 'websocket'
4
4
  import { Logger } from '@streamr/utils'
5
5
  import { Url } from 'url'
6
- import { GOING_AWAY } from './ClientWebsocket'
6
+ import { CUSTOM_GOING_AWAY, GOING_AWAY } from './ClientWebsocket'
7
7
 
8
8
  const logger = new Logger(module)
9
9
 
@@ -29,37 +29,52 @@ export class ServerWebsocket extends EventEmitter<ConnectionEvents> implements I
29
29
  constructor(socket: WsConnection, resourceURL: Url) {
30
30
  super()
31
31
 
32
+ this.onMessage = this.onMessage.bind(this)
33
+ this.onClose = this.onClose.bind(this)
34
+ this.onError = this.onError.bind(this)
35
+
32
36
  this.resourceURL = resourceURL
33
37
  this.connectionId = new ConnectionID()
34
38
 
35
- socket.on('message', (message) => {
36
- logger.trace('ServerWebsocket::onMessage')
37
- if (message.type === MessageType.UTF8) {
38
- logger.debug('Received string Message: ' + message.utf8Data)
39
- } else if (message.type === MessageType.BINARY) {
40
- logger.trace('Received Binary Message of ' + message.binaryData.length + ' bytes')
41
- this.emit('data',
42
- new Uint8Array(message.binaryData.buffer, message.binaryData.byteOffset,
43
- message.binaryData.byteLength / Uint8Array.BYTES_PER_ELEMENT))
44
- }
45
- })
46
- socket.on('close', (reasonCode, description) => {
47
- logger.trace('Peer ' + socket.remoteAddress + ' disconnected.')
48
- this.doDisconnect(reasonCode, description)
49
- })
50
-
51
- socket.on('error', (error) => {
52
- this.emit('error', error.name)
53
- })
39
+ socket.on('message', this.onMessage)
40
+ socket.on('close', this.onClose)
41
+ socket.on('error', this.onError)
54
42
 
55
43
  this.socket = socket
56
44
  }
57
45
 
46
+ private onMessage(message: Message): void {
47
+ logger.trace('ServerWebsocket::onMessage')
48
+ if (message.type === MessageType.UTF8) {
49
+ logger.debug('Received string Message: ' + message.utf8Data)
50
+ } else if (message.type === MessageType.BINARY) {
51
+ logger.trace('Received Binary Message of ' + message.binaryData.length + ' bytes')
52
+ this.emit('data',
53
+ new Uint8Array(message.binaryData.buffer, message.binaryData.byteOffset,
54
+ message.binaryData.byteLength / Uint8Array.BYTES_PER_ELEMENT))
55
+ }
56
+ }
57
+
58
+ private onClose(reasonCode: number, description: string): void {
59
+ logger.trace('Peer ' + this.socket?.remoteAddress + ' disconnected.')
60
+ this.doDisconnect(reasonCode, description)
61
+ }
62
+
63
+ private onError(error: Error): void {
64
+ this.emit('error', error.name)
65
+ }
66
+
67
+ private stopListening(): void {
68
+ this.socket?.off('message', this.onMessage)
69
+ this.socket?.off('close', this.onClose)
70
+ this.socket?.off('error', this.onError)
71
+ }
72
+
58
73
  private doDisconnect(reasonCode: number, description: string): void {
59
74
  this.stopped = true
60
- this.socket?.removeAllListeners()
75
+ this.stopListening()
61
76
  this.socket = undefined
62
- const gracefulLeave = reasonCode === GOING_AWAY
77
+ const gracefulLeave = (reasonCode === GOING_AWAY) || (reasonCode === CUSTOM_GOING_AWAY)
63
78
  this.emit('disconnected', gracefulLeave, reasonCode, description)
64
79
  }
65
80
 
@@ -83,7 +98,7 @@ export class ServerWebsocket extends EventEmitter<ConnectionEvents> implements I
83
98
  this.emit('disconnected', gracefulLeave, undefined, 'close() called')
84
99
  this.removeAllListeners()
85
100
  if (!this.stopped) {
86
- this.socket?.close(gracefulLeave === true ? GOING_AWAY : undefined)
101
+ this.socket?.close(gracefulLeave ? GOING_AWAY : undefined)
87
102
  } else {
88
103
  logger.debug('Tried to close a stopped connection')
89
104
  }
@@ -93,7 +108,7 @@ export class ServerWebsocket extends EventEmitter<ConnectionEvents> implements I
93
108
  if (!this.stopped) {
94
109
  this.removeAllListeners()
95
110
  if (this.socket) {
96
- this.socket.removeAllListeners()
111
+ this.stopListening()
97
112
  this.socket.close()
98
113
  this.socket = undefined
99
114
  }