@streamr/dht 102.0.0-beta.0 → 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 (264) hide show
  1. package/dist/generated/packages/dht/protos/DhtRpc.d.ts +16 -8
  2. package/dist/generated/packages/dht/protos/DhtRpc.js +7 -5
  3. package/dist/generated/packages/dht/protos/DhtRpc.js.map +1 -1
  4. package/dist/package.json +15 -16
  5. package/dist/src/connection/ConnectionManager.js +18 -8
  6. package/dist/src/connection/ConnectionManager.js.map +1 -1
  7. package/dist/src/connection/Handshaker.d.ts +1 -1
  8. package/dist/src/connection/Handshaker.js +9 -5
  9. package/dist/src/connection/Handshaker.js.map +1 -1
  10. package/dist/src/connection/ManagedConnection.js +17 -7
  11. package/dist/src/connection/ManagedConnection.js.map +1 -1
  12. package/dist/src/connection/connectivityChecker.js +20 -10
  13. package/dist/src/connection/connectivityChecker.js.map +1 -1
  14. package/dist/src/connection/connectivityRequestHandler.js +3 -3
  15. package/dist/src/connection/connectivityRequestHandler.js.map +1 -1
  16. package/dist/src/connection/simulator/Simulator.js +3 -2
  17. package/dist/src/connection/simulator/Simulator.js.map +1 -1
  18. package/dist/src/connection/simulator/pings.d.ts +1 -1
  19. package/dist/src/connection/simulator/pings.js +3 -3
  20. package/dist/src/connection/simulator/pings.js.map +1 -1
  21. package/dist/src/connection/webrtc/NodeWebrtcConnection.js +0 -2
  22. package/dist/src/connection/webrtc/NodeWebrtcConnection.js.map +1 -1
  23. package/dist/src/connection/webrtc/WebrtcConnector.js +19 -9
  24. package/dist/src/connection/webrtc/WebrtcConnector.js.map +1 -1
  25. package/dist/src/connection/webrtc/iceServerAsString.js +1 -2
  26. package/dist/src/connection/webrtc/iceServerAsString.js.map +1 -1
  27. package/dist/src/connection/websocket/AbstractWebsocketClientConnection.d.ts +0 -2
  28. package/dist/src/connection/websocket/WebsocketClientConnectorRpcLocal.d.ts +0 -1
  29. package/dist/src/connection/websocket/WebsocketServerConnection.d.ts +0 -1
  30. package/dist/src/connection/websocket/WebsocketServerConnector.js +28 -18
  31. package/dist/src/connection/websocket/WebsocketServerConnector.js.map +1 -1
  32. package/dist/src/dht/DhtNode.d.ts +1 -0
  33. package/dist/src/dht/DhtNode.js +3 -2
  34. package/dist/src/dht/DhtNode.js.map +1 -1
  35. package/dist/src/dht/DhtNodeRpcLocal.d.ts +1 -1
  36. package/dist/src/dht/PeerManager.d.ts +2 -1
  37. package/dist/src/dht/PeerManager.js +2 -1
  38. package/dist/src/dht/PeerManager.js.map +1 -1
  39. package/dist/src/dht/contact/SortedContactList.js +1 -1
  40. package/dist/src/dht/contact/SortedContactList.js.map +1 -1
  41. package/dist/src/dht/discovery/DiscoverySession.d.ts +0 -1
  42. package/dist/src/dht/discovery/PeerDiscovery.d.ts +0 -1
  43. package/dist/src/dht/discovery/RingDiscoverySession.d.ts +0 -1
  44. package/dist/src/dht/recursive-operation/RecursiveOperationManager.d.ts +2 -2
  45. package/dist/src/dht/routing/DuplicateDetector.js.map +1 -1
  46. package/dist/src/dht/routing/RoutingSession.js +2 -2
  47. package/dist/src/dht/routing/RoutingSession.js.map +1 -1
  48. package/dist/src/dht/routing/RoutingTablesCache.d.ts +1 -1
  49. package/dist/src/dht/store/LocalDataStore.js +1 -1
  50. package/dist/src/dht/store/LocalDataStore.js.map +1 -1
  51. package/dist/src/dht/store/StoreManager.d.ts +1 -1
  52. package/dist/src/dht/store/StoreRpcLocal.d.ts +1 -1
  53. package/dist/src/helpers/AddressTools.js +2 -3
  54. package/dist/src/helpers/AddressTools.js.map +1 -1
  55. package/dist/src/helpers/debugHelpers.js +2 -2
  56. package/dist/src/helpers/debugHelpers.js.map +1 -1
  57. package/dist/src/helpers/protoClasses.d.ts +1 -1
  58. package/dist/src/helpers/protoClasses.js.map +1 -1
  59. package/dist/src/helpers/protoToString.js +1 -2
  60. package/dist/src/helpers/protoToString.js.map +1 -1
  61. package/dist/src/helpers/version.d.ts +1 -1
  62. package/dist/src/helpers/version.js +4 -4
  63. package/dist/src/helpers/version.js.map +1 -1
  64. package/eslint.config.mjs +12 -0
  65. package/jest.config.ts +12 -0
  66. package/package.json +15 -16
  67. package/protos/DhtRpc.proto +6 -4
  68. package/.eslintignore +0 -5
  69. package/.eslintrc +0 -3
  70. package/generated/google/protobuf/any.ts +0 -326
  71. package/generated/google/protobuf/empty.ts +0 -81
  72. package/generated/google/protobuf/timestamp.ts +0 -287
  73. package/generated/packages/dht/protos/DhtRpc.client.ts +0 -419
  74. package/generated/packages/dht/protos/DhtRpc.server.ts +0 -165
  75. package/generated/packages/dht/protos/DhtRpc.ts +0 -1266
  76. package/generated/packages/proto-rpc/protos/ProtoRpc.ts +0 -108
  77. package/jest.config.js +0 -5
  78. package/src/connection/Connection.ts +0 -28
  79. package/src/connection/ConnectionLockRpcLocal.ts +0 -78
  80. package/src/connection/ConnectionLockRpcRemote.ts +0 -64
  81. package/src/connection/ConnectionLockStates.ts +0 -131
  82. package/src/connection/ConnectionManager.ts +0 -661
  83. package/src/connection/ConnectionsView.ts +0 -8
  84. package/src/connection/ConnectorFacade.ts +0 -217
  85. package/src/connection/Handshaker.ts +0 -205
  86. package/src/connection/IConnection.ts +0 -40
  87. package/src/connection/ManagedConnection.ts +0 -113
  88. package/src/connection/OutputBuffer.ts +0 -28
  89. package/src/connection/PendingConnection.ts +0 -68
  90. package/src/connection/connectivityChecker.ts +0 -108
  91. package/src/connection/connectivityRequestHandler.ts +0 -116
  92. package/src/connection/simulator/Simulator.ts +0 -368
  93. package/src/connection/simulator/SimulatorConnection.ts +0 -137
  94. package/src/connection/simulator/SimulatorConnector.ts +0 -98
  95. package/src/connection/simulator/SimulatorTransport.ts +0 -15
  96. package/src/connection/simulator/pings.ts +0 -42
  97. package/src/connection/webrtc/BrowserWebrtcConnection.ts +0 -242
  98. package/src/connection/webrtc/IWebrtcConnection.ts +0 -24
  99. package/src/connection/webrtc/NodeWebrtcConnection.ts +0 -247
  100. package/src/connection/webrtc/WebrtcConnector.ts +0 -234
  101. package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +0 -108
  102. package/src/connection/webrtc/WebrtcConnectorRpcRemote.ts +0 -60
  103. package/src/connection/webrtc/iceServerAsString.ts +0 -15
  104. package/src/connection/websocket/AbstractWebsocketClientConnection.ts +0 -122
  105. package/src/connection/websocket/AutoCertifierClientFacade.ts +0 -89
  106. package/src/connection/websocket/BrowserWebsocketClientConnection.ts +0 -44
  107. package/src/connection/websocket/NodeWebsocketClientConnection.ts +0 -39
  108. package/src/connection/websocket/WebsocketClientConnector.ts +0 -119
  109. package/src/connection/websocket/WebsocketClientConnectorRpcLocal.ts +0 -38
  110. package/src/connection/websocket/WebsocketClientConnectorRpcRemote.ts +0 -19
  111. package/src/connection/websocket/WebsocketServer.ts +0 -164
  112. package/src/connection/websocket/WebsocketServerConnection.ts +0 -109
  113. package/src/connection/websocket/WebsocketServerConnector.ts +0 -286
  114. package/src/dht/DhtNode.ts +0 -678
  115. package/src/dht/DhtNodeRpcLocal.ts +0 -84
  116. package/src/dht/DhtNodeRpcRemote.ts +0 -107
  117. package/src/dht/ExternalApiRpcLocal.ts +0 -58
  118. package/src/dht/ExternalApiRpcRemote.ts +0 -41
  119. package/src/dht/PeerManager.ts +0 -303
  120. package/src/dht/contact/Contact.ts +0 -19
  121. package/src/dht/contact/ContactList.ts +0 -43
  122. package/src/dht/contact/RandomContactList.ts +0 -56
  123. package/src/dht/contact/RingContactList.ts +0 -143
  124. package/src/dht/contact/RpcRemote.ts +0 -72
  125. package/src/dht/contact/SortedContactList.ts +0 -173
  126. package/src/dht/contact/getClosestNodes.ts +0 -24
  127. package/src/dht/contact/ringIdentifiers.ts +0 -62
  128. package/src/dht/discovery/DiscoverySession.ts +0 -129
  129. package/src/dht/discovery/PeerDiscovery.ts +0 -244
  130. package/src/dht/discovery/RingDiscoverySession.ts +0 -148
  131. package/src/dht/recursive-operation/RecursiveOperationManager.ts +0 -251
  132. package/src/dht/recursive-operation/RecursiveOperationRpcLocal.ts +0 -34
  133. package/src/dht/recursive-operation/RecursiveOperationRpcRemote.ts +0 -43
  134. package/src/dht/recursive-operation/RecursiveOperationSession.ts +0 -231
  135. package/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.ts +0 -35
  136. package/src/dht/recursive-operation/RecursiveOperationSessionRpcRemote.ts +0 -30
  137. package/src/dht/routing/DuplicateDetector.ts +0 -34
  138. package/src/dht/routing/Router.ts +0 -246
  139. package/src/dht/routing/RouterRpcLocal.ts +0 -78
  140. package/src/dht/routing/RouterRpcRemote.ts +0 -80
  141. package/src/dht/routing/RoutingSession.ts +0 -243
  142. package/src/dht/routing/RoutingTablesCache.ts +0 -60
  143. package/src/dht/routing/getPreviousPeer.ts +0 -6
  144. package/src/dht/store/LocalDataStore.ts +0 -84
  145. package/src/dht/store/StoreManager.ts +0 -170
  146. package/src/dht/store/StoreRpcLocal.ts +0 -89
  147. package/src/dht/store/StoreRpcRemote.ts +0 -32
  148. package/src/exports.ts +0 -33
  149. package/src/helpers/AddressTools.ts +0 -28
  150. package/src/helpers/Connectivity.ts +0 -19
  151. package/src/helpers/browser/isBrowserEnvironment.ts +0 -1
  152. package/src/helpers/browser/isBrowserEnvironment_override.ts +0 -3
  153. package/src/helpers/createPeerDescriptor.ts +0 -57
  154. package/src/helpers/createPeerDescriptorSignaturePayload.ts +0 -28
  155. package/src/helpers/debugHelpers.ts +0 -9
  156. package/src/helpers/errors.ts +0 -49
  157. package/src/helpers/offering.ts +0 -15
  158. package/src/helpers/protoClasses.ts +0 -57
  159. package/src/helpers/protoToString.ts +0 -21
  160. package/src/helpers/version.ts +0 -32
  161. package/src/identifiers.ts +0 -29
  162. package/src/rpc-protocol/DhtCallContext.ts +0 -14
  163. package/src/rpc-protocol/DhtRpcOptions.ts +0 -10
  164. package/src/transport/ITransport.ts +0 -37
  165. package/src/transport/ListeningRpcCommunicator.ts +0 -32
  166. package/src/transport/RoutingRpcCommunicator.ts +0 -66
  167. package/src/types/ServiceID.ts +0 -1
  168. package/src/types/textencoding.d.ts +0 -6
  169. package/test/benchmark/Find.test.ts +0 -72
  170. package/test/benchmark/KademliaCorrectness.test.ts +0 -114
  171. package/test/benchmark/RingCorrectness.test.ts +0 -157
  172. package/test/benchmark/SortedContactListBenchmark.test.ts +0 -108
  173. package/test/benchmark/WebsocketServerMemoryLeak.test.ts +0 -41
  174. package/test/benchmark/hybrid-network-simulation/RingContactList.test.ts +0 -71
  175. package/test/end-to-end/GeoIpLayer0.test.ts +0 -55
  176. package/test/end-to-end/Layer0-Layer1.test.ts +0 -93
  177. package/test/end-to-end/Layer0.test.ts +0 -76
  178. package/test/end-to-end/Layer0MixedConnectionTypes.test.ts +0 -110
  179. package/test/end-to-end/Layer0Webrtc-Layer1.test.ts +0 -137
  180. package/test/end-to-end/Layer0Webrtc.test.ts +0 -85
  181. package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +0 -82
  182. package/test/end-to-end/Layer1-Scale-Webrtc.test.ts +0 -76
  183. package/test/end-to-end/RecoveryFromFailedAutoCertification.test.ts +0 -52
  184. package/test/end-to-end/WebsocketConnectionRequest.test.ts +0 -69
  185. package/test/end-to-end/memory-leak.test.ts +0 -80
  186. package/test/integration/ConnectionLocking.test.ts +0 -182
  187. package/test/integration/ConnectionManager.test.ts +0 -528
  188. package/test/integration/ConnectivityChecking.test.ts +0 -53
  189. package/test/integration/DhtJoinPeerDiscovery.test.ts +0 -49
  190. package/test/integration/DhtNode.test.ts +0 -66
  191. package/test/integration/DhtNodeExternalAPI.test.ts +0 -48
  192. package/test/integration/DhtNodeRpcRemote.test.ts +0 -66
  193. package/test/integration/DhtRpc.test.ts +0 -121
  194. package/test/integration/Find.test.ts +0 -45
  195. package/test/integration/GeoIpConnectivityChecking.test.ts +0 -72
  196. package/test/integration/Layer1-scale.test.ts +0 -189
  197. package/test/integration/Mock-Layer1-Layer0.test.ts +0 -85
  198. package/test/integration/MultipleEntryPointJoining.test.ts +0 -105
  199. package/test/integration/ReplicateData.test.ts +0 -104
  200. package/test/integration/RouteMessage.test.ts +0 -230
  201. package/test/integration/RouterRpcRemote.test.ts +0 -77
  202. package/test/integration/SimultaneousConnections.test.ts +0 -316
  203. package/test/integration/Store.test.ts +0 -85
  204. package/test/integration/StoreAndDelete.test.ts +0 -77
  205. package/test/integration/StoreOnDhtWithThreeNodes.test.ts +0 -59
  206. package/test/integration/StoreOnDhtWithTwoNodes.test.ts +0 -51
  207. package/test/integration/StoreRpcRemote.test.ts +0 -54
  208. package/test/integration/WebrtcConnectionManagement.test.ts +0 -219
  209. package/test/integration/WebrtcConnectorRpc.test.ts +0 -125
  210. package/test/integration/Websocket.test.ts +0 -65
  211. package/test/integration/WebsocketClientConnectorRpc.test.ts +0 -69
  212. package/test/integration/WebsocketConnectionManagement.test.ts +0 -191
  213. package/test/integration/rpc-connections-over-webrtc.test.ts +0 -158
  214. package/test/kademlia-simulation/data/nodeids.json +0 -13002
  215. package/test/kademlia-simulation/data/orderedneighbors.json +0 -1001
  216. package/test/types/global.d.ts +0 -1
  217. package/test/unit/AddressTools.test.ts +0 -44
  218. package/test/unit/AutoCertifierClientFacade.test.ts +0 -58
  219. package/test/unit/ConnectionManager.test.ts +0 -65
  220. package/test/unit/ConnectivityHelpers.test.ts +0 -61
  221. package/test/unit/DiscoverySession.test.ts +0 -87
  222. package/test/unit/DuplicateDetector.test.ts +0 -31
  223. package/test/unit/Handshaker.test.ts +0 -169
  224. package/test/unit/ListeningRpcCommunicator.test.ts +0 -52
  225. package/test/unit/LocalDataStore.test.ts +0 -108
  226. package/test/unit/ManagedConnection.test.ts +0 -58
  227. package/test/unit/PeerManager.test.ts +0 -93
  228. package/test/unit/PendingConnection.test.ts +0 -57
  229. package/test/unit/ProtobufMessage.test.ts +0 -21
  230. package/test/unit/RandomContactList.test.ts +0 -58
  231. package/test/unit/RecursiveOperationManager.test.ts +0 -161
  232. package/test/unit/RecursiveOperationSession.test.ts +0 -68
  233. package/test/unit/Router.test.ts +0 -137
  234. package/test/unit/RoutingSession.test.ts +0 -79
  235. package/test/unit/SortedContactList.test.ts +0 -115
  236. package/test/unit/StoreManager.test.ts +0 -146
  237. package/test/unit/StoreRpcLocal.test.ts +0 -167
  238. package/test/unit/WebrtcConnection.test.ts +0 -29
  239. package/test/unit/WebrtcConnector.test.ts +0 -56
  240. package/test/unit/WebsocketClientConnector.test.ts +0 -101
  241. package/test/unit/WebsocketServer.test.ts +0 -66
  242. package/test/unit/WebsocketServerConnector.test.ts +0 -102
  243. package/test/unit/connectivityRequestHandler.test.ts +0 -104
  244. package/test/unit/createPeerDescriptor.test.ts +0 -69
  245. package/test/unit/customMatchers.test.ts +0 -16
  246. package/test/unit/getClosestNodes.test.ts +0 -30
  247. package/test/unit/version.test.ts +0 -18
  248. package/test/unit/webrtcReplaceInternalIpWithExternalIp.test.ts +0 -18
  249. package/test/utils/FakeConnectorFacade.ts +0 -41
  250. package/test/utils/FakeRpcCommunicator.ts +0 -23
  251. package/test/utils/FakeTransport.ts +0 -79
  252. package/test/utils/customMatchers.ts +0 -71
  253. package/test/utils/mock/MockConnection.ts +0 -26
  254. package/test/utils/mock/MockConnectionsView.ts +0 -18
  255. package/test/utils/mock/MockRouter.ts +0 -62
  256. package/test/utils/mock/MockRpcCommunicator.ts +0 -7
  257. package/test/utils/mock/MockTransport.ts +0 -26
  258. package/test/utils/mock/mockDataEntry.ts +0 -38
  259. package/test/utils/topology.ts +0 -80
  260. package/test/utils/utils.ts +0 -268
  261. package/tsconfig.browser.json +0 -17
  262. package/tsconfig.jest.json +0 -25
  263. package/tsconfig.json +0 -3
  264. package/tsconfig.node.json +0 -24
@@ -1,247 +0,0 @@
1
- import { IWebrtcConnection, WebrtcConnectionEvents } from './IWebrtcConnection'
2
- import { ConnectionType, IConnection, ConnectionID, ConnectionEvents } from '../IConnection'
3
- import { PeerDescriptor } from '../../../generated/packages/dht/protos/DhtRpc'
4
- import EventEmitter from 'eventemitter3'
5
- // TODO: why does eslint import rule plugin not work?
6
- // eslint-disable-next-line import/no-unresolved
7
- import { DataChannel, DescriptionType, PeerConnection, initLogger } from 'node-datachannel'
8
- import { Logger } from '@streamr/utils'
9
- import { IllegalRtcPeerConnectionState } from '../../helpers/errors'
10
- import { iceServerAsString } from './iceServerAsString'
11
- import { IceServer, EARLY_TIMEOUT } from './WebrtcConnector'
12
- import { PortRange } from '../ConnectionManager'
13
- import { toNodeId } from '../../identifiers'
14
- import { createRandomConnectionId } from '../Connection'
15
-
16
- const logger = new Logger(module)
17
-
18
- export interface Params {
19
- remotePeerDescriptor: PeerDescriptor
20
- bufferThresholdHigh?: number
21
- bufferThresholdLow?: number
22
- maxMessageSize?: number
23
- iceServers?: IceServer[] // TODO make this parameter required (empty array is a good fallback which can be set by the caller if needed)
24
- portRange?: PortRange
25
- }
26
-
27
- // Re-defined accoring to https://github.com/microsoft/TypeScript/blob/main/src/lib/dom.generated.d.ts
28
- // because importing single dom definitions in not possible
29
-
30
- enum RtcPeerConnectionStateEnum {
31
- closed = 'closed',
32
- connected = 'connected',
33
- connecting = 'connecting',
34
- disconnected = 'disconnected',
35
- failed = 'failed',
36
- new = 'new'
37
- }
38
-
39
- initLogger('Fatal')
40
-
41
- type RtcPeerConnectionState = keyof typeof RtcPeerConnectionStateEnum
42
-
43
- type Events = WebrtcConnectionEvents & ConnectionEvents
44
-
45
- export class NodeWebrtcConnection extends EventEmitter<Events> implements IConnection, IWebrtcConnection {
46
-
47
- public connectionId: ConnectionID
48
- private connection?: PeerConnection
49
- private dataChannel?: DataChannel
50
- private lastState: RtcPeerConnectionState = 'connecting'
51
- private remoteDescriptionSet = false
52
- public readonly connectionType: ConnectionType = ConnectionType.WEBRTC
53
- private readonly iceServers: IceServer[]
54
- private readonly _bufferThresholdHigh: number // TODO: buffer handling must be implemented before production use (NET-938)
55
- private readonly bufferThresholdLow: number
56
- private readonly remotePeerDescriptor: PeerDescriptor
57
- private readonly portRange?: PortRange
58
- private readonly maxMessageSize?: number
59
- private closed = false
60
- private offering?: boolean
61
- private readonly earlyTimeout: NodeJS.Timeout
62
-
63
- constructor(params: Params) {
64
- super()
65
- this.connectionId = createRandomConnectionId()
66
- this.iceServers = params.iceServers ?? []
67
- // eslint-disable-next-line no-underscore-dangle
68
- this._bufferThresholdHigh = params.bufferThresholdHigh ?? 2 ** 17
69
- this.bufferThresholdLow = params.bufferThresholdLow ?? 2 ** 15
70
- this.remotePeerDescriptor = params.remotePeerDescriptor
71
- this.maxMessageSize = params.maxMessageSize ?? 1048576
72
- this.portRange = params.portRange
73
- this.earlyTimeout = setTimeout(() => {
74
- this.doClose(false, 'timed out due to remote descriptor not being set')
75
- }, EARLY_TIMEOUT)
76
- }
77
-
78
- public start(isOffering: boolean): void {
79
- const nodeId = toNodeId(this.remotePeerDescriptor)
80
- this.offering = isOffering
81
- logger.trace(`Starting new connection for peer ${nodeId}`, { isOffering })
82
- this.connection = new PeerConnection(nodeId, {
83
- iceServers: this.iceServers.map(iceServerAsString),
84
- maxMessageSize: this.maxMessageSize,
85
- portRangeBegin: this.portRange?.min,
86
- portRangeEnd: this.portRange?.max,
87
- })
88
-
89
- this.connection.onStateChange((state: string) => this.onStateChange(state))
90
- this.connection.onGatheringStateChange(() => {})
91
-
92
- this.connection.onLocalDescription((description: string, type: DescriptionType) => {
93
- this.emit('localDescription', description, type.toString())
94
- })
95
- this.connection.onLocalCandidate((candidate: string, mid: string) => {
96
- this.emit('localCandidate', candidate, mid)
97
- })
98
- if (isOffering) {
99
- const dataChannel = this.connection.createDataChannel('streamrDataChannel')
100
- this.setupDataChannel(dataChannel)
101
- } else {
102
- this.connection.onDataChannel((dataChannel) => this.setupDataChannel(dataChannel))
103
- }
104
- }
105
-
106
- public async setRemoteDescription(description: string, type: string): Promise<void> {
107
- if (this.connection) {
108
- clearTimeout(this.earlyTimeout)
109
- const remoteNodeId = toNodeId(this.remotePeerDescriptor)
110
- try {
111
- logger.trace(`Setting remote descriptor for peer: ${remoteNodeId}`)
112
- this.connection.setRemoteDescription(description, type as DescriptionType)
113
- this.remoteDescriptionSet = true
114
- } catch {
115
- logger.debug(`Failed to set remote descriptor for peer ${remoteNodeId}`)
116
- }
117
- } else {
118
- this.doClose(false, `Tried to set description for non-existent connection`)
119
- }
120
- }
121
-
122
- public addRemoteCandidate(candidate: string, mid: string): void {
123
- if (this.connection) {
124
- if (this.remoteDescriptionSet) {
125
- const remoteNodeId = toNodeId(this.remotePeerDescriptor)
126
- try {
127
- logger.trace(`Setting remote candidate for peer: ${remoteNodeId}`)
128
- this.connection.addRemoteCandidate(candidate, mid)
129
- } catch {
130
- logger.debug(`Failed to set remote candidate for peer ${remoteNodeId}`)
131
- }
132
- } else {
133
- // TODO: should queue candidates until remote description is set?
134
- this.doClose(false, `Tried to set candidate before description`)
135
- }
136
- } else {
137
- this.doClose(false, `Tried to set candidate for non-existent connection`)
138
- }
139
- }
140
-
141
- public send(data: Uint8Array): void {
142
- if (this.isOpen()) {
143
- try {
144
- this.dataChannel!.sendMessageBinary(data as Buffer)
145
- } catch (err) {
146
- const remoteNodeId = toNodeId(this.remotePeerDescriptor)
147
- logger.debug('Failed to send binary message to ' + remoteNodeId + err)
148
- }
149
- }
150
- }
151
-
152
- public async close(gracefulLeave: boolean, reason?: string): Promise<void> {
153
- this.doClose(gracefulLeave, reason)
154
- }
155
-
156
- private doClose(gracefulLeave: boolean, reason?: string): void {
157
- if (!this.closed) {
158
- clearTimeout(this.earlyTimeout)
159
- const remoteNodeId = toNodeId(this.remotePeerDescriptor)
160
- logger.trace(`Closing Node WebRTC Connection to ${remoteNodeId}` + `${(reason !== undefined) ? `, reason: ${reason}` : ''}`)
161
-
162
- this.closed = true
163
-
164
- this.emit('disconnected', gracefulLeave, undefined, reason)
165
- this.removeAllListeners()
166
-
167
- if (this.dataChannel) {
168
- try {
169
- logger.trace('closing datachannel')
170
- this.dataChannel.close()
171
- } catch (e) {
172
- logger.trace('dc.close() errored: %s', e)
173
- }
174
- }
175
-
176
- if (this.connection) {
177
- try {
178
- this.connection.close()
179
- } catch (e) {
180
- logger.trace('conn.close() errored: %s', e)
181
- }
182
- }
183
- this.connection = undefined
184
- this.dataChannel = undefined
185
- }
186
- }
187
-
188
- public destroy(): void {
189
- this.removeAllListeners()
190
- this.doClose(false)
191
- }
192
-
193
- private setupDataChannel(dataChannel: DataChannel): void {
194
- this.dataChannel = dataChannel
195
- dataChannel.setBufferedAmountLowThreshold(this.bufferThresholdLow)
196
- dataChannel.onOpen(() => {
197
- logger.trace(`dc.onOpened`)
198
- this.onDataChannelOpen()
199
- })
200
-
201
- dataChannel.onClosed(() => {
202
- logger.trace(`dc.closed`)
203
- this.doClose(false, 'DataChannel closed')
204
- })
205
-
206
- dataChannel.onError((err) => logger.error('error', { err }))
207
-
208
- dataChannel.onBufferedAmountLow(() => {
209
- logger.trace(`dc.onBufferedAmountLow`)
210
- })
211
-
212
- dataChannel.onMessage((msg) => {
213
- logger.trace(`dc.onMessage`)
214
- this.emit('data', msg as Buffer)
215
- })
216
- }
217
-
218
- private onDataChannelOpen(): void {
219
- logger.trace(`DataChannel opened for peer ${toNodeId(this.remotePeerDescriptor)}`)
220
- this.emit('connected')
221
- }
222
-
223
- private onStateChange(state: string): void {
224
- logger.trace('onStateChange ' + state)
225
- if (!Object.keys(RtcPeerConnectionStateEnum).filter((s) => isNaN(+s)).includes(state)) {
226
- throw new IllegalRtcPeerConnectionState('NodeWebrtcConnection used an unknown state: ' + state)
227
- } else {
228
- this.lastState = state as RtcPeerConnectionState
229
- }
230
-
231
- if (state === RtcPeerConnectionStateEnum.closed
232
- || state === RtcPeerConnectionStateEnum.disconnected
233
- || state === RtcPeerConnectionStateEnum.failed
234
- ) {
235
- this.doClose(false)
236
- }
237
-
238
- }
239
-
240
- isOpen(): boolean {
241
- return !this.closed && this.lastState === 'connected' && !!this.dataChannel
242
- }
243
-
244
- public setConnectionId(connectionId: ConnectionID): void {
245
- this.connectionId = connectionId
246
- }
247
- }
@@ -1,234 +0,0 @@
1
- import {
2
- HandshakeError,
3
- IceCandidate,
4
- PeerDescriptor,
5
- RtcAnswer,
6
- RtcOffer, WebrtcConnectionRequest
7
- } from '../../../generated/packages/dht/protos/DhtRpc'
8
- import { ITransport } from '../../transport/ITransport'
9
- import { ListeningRpcCommunicator } from '../../transport/ListeningRpcCommunicator'
10
- import { NodeWebrtcConnection } from './NodeWebrtcConnection'
11
- import { WebrtcConnectorRpcRemote } from './WebrtcConnectorRpcRemote'
12
- import { WebrtcConnectorRpcClient } from '../../../generated/packages/dht/protos/DhtRpc.client'
13
- import { Logger } from '@streamr/utils'
14
- import * as Err from '../../helpers/errors'
15
- import { PortRange } from '../ConnectionManager'
16
- import { ServerCallContext } from '@protobuf-ts/runtime-rpc'
17
- import { WebrtcConnectorRpcLocal } from './WebrtcConnectorRpcLocal'
18
- import { DhtAddress, areEqualPeerDescriptors, toNodeId } from '../../identifiers'
19
- import { getOfferer } from '../../helpers/offering'
20
- import { acceptHandshake, createIncomingHandshaker, createOutgoingHandshaker, rejectHandshake } from '../Handshaker'
21
- import { isMaybeSupportedVersion } from '../../helpers/version'
22
- import { PendingConnection } from '../PendingConnection'
23
-
24
- const logger = new Logger(module)
25
-
26
- export const replaceInternalIpWithExternalIp = (candidate: string, ip: string): string => {
27
- const parsed = candidate.split(' ')
28
- const type = parsed[7]
29
- if (type === 'host') {
30
- parsed[4] = ip
31
- }
32
- return parsed.join(' ')
33
- }
34
-
35
- export const EARLY_TIMEOUT = 5000
36
-
37
- export interface WebrtcConnectorOptions {
38
- onNewConnection: (connection: PendingConnection) => boolean
39
- transport: ITransport
40
- iceServers?: IceServer[]
41
- allowPrivateAddresses?: boolean
42
- bufferThresholdLow?: number
43
- bufferThresholdHigh?: number
44
- maxMessageSize?: number
45
- externalIp?: string
46
- portRange?: PortRange
47
- }
48
-
49
- export interface IceServer {
50
- url: string
51
- port: number
52
- username?: string
53
- password?: string
54
- tcp?: boolean
55
- }
56
-
57
- export interface ConnectingConnection {
58
- managedConnection: PendingConnection
59
- connection: NodeWebrtcConnection
60
- }
61
-
62
- export class WebrtcConnector {
63
-
64
- private static readonly WEBRTC_CONNECTOR_SERVICE_ID = 'system/webrtc-connector'
65
- private readonly rpcCommunicator: ListeningRpcCommunicator
66
- private readonly ongoingConnectAttempts: Map<DhtAddress, ConnectingConnection> = new Map()
67
- private localPeerDescriptor?: PeerDescriptor
68
- private stopped = false
69
- private options: WebrtcConnectorOptions
70
-
71
- constructor(options: WebrtcConnectorOptions) {
72
- this.options = options
73
- this.rpcCommunicator = new ListeningRpcCommunicator(WebrtcConnector.WEBRTC_CONNECTOR_SERVICE_ID, options.transport, {
74
- rpcRequestTimeout: 15000 // TODO use options option or named constant?
75
- })
76
- this.registerLocalRpcMethods(options)
77
- }
78
-
79
- private registerLocalRpcMethods(options: WebrtcConnectorOptions) {
80
- const localRpc = new WebrtcConnectorRpcLocal({
81
- connect: (targetPeerDescriptor: PeerDescriptor, doNotRequestConnection: boolean) =>
82
- this.connect(targetPeerDescriptor, doNotRequestConnection),
83
- onNewConnection: (connection: PendingConnection) => this.options.onNewConnection(connection),
84
- ongoingConnectAttempts: this.ongoingConnectAttempts,
85
- rpcCommunicator: this.rpcCommunicator,
86
- getLocalPeerDescriptor: () => this.localPeerDescriptor!,
87
- allowPrivateAddresses: options.allowPrivateAddresses ?? true
88
- })
89
- this.rpcCommunicator.registerRpcNotification(WebrtcConnectionRequest, 'requestConnection',
90
- async (_req: WebrtcConnectionRequest, context: ServerCallContext) => {
91
- if (!this.stopped) {
92
- return localRpc.requestConnection(context)
93
- } else {
94
- return {}
95
- }
96
- }
97
- )
98
- this.rpcCommunicator.registerRpcNotification(RtcOffer, 'rtcOffer',
99
- async (req: RtcOffer, context: ServerCallContext) => {
100
- if (!this.stopped) {
101
- return localRpc.rtcOffer(req, context)
102
- } else {
103
- return {}
104
- }
105
- }
106
- )
107
- this.rpcCommunicator.registerRpcNotification(RtcAnswer, 'rtcAnswer',
108
- async (req: RtcAnswer, context: ServerCallContext) => {
109
- if (!this.stopped) {
110
- return localRpc.rtcAnswer(req, context)
111
- } else {
112
- return {}
113
- }
114
- }
115
- )
116
- this.rpcCommunicator.registerRpcNotification(IceCandidate, 'iceCandidate',
117
- async (req: IceCandidate, context: ServerCallContext) => {
118
- if (!this.stopped) {
119
- return localRpc.iceCandidate(req, context)
120
- } else {
121
- return {}
122
- }
123
- }
124
- )
125
- }
126
-
127
- connect(targetPeerDescriptor: PeerDescriptor, doNotRequestConnection: boolean): PendingConnection {
128
- if (areEqualPeerDescriptors(targetPeerDescriptor, this.localPeerDescriptor!)) {
129
- throw new Err.CannotConnectToSelf('Cannot open WebRTC Connection to self')
130
- }
131
-
132
- logger.trace(`Opening WebRTC connection to ${toNodeId(targetPeerDescriptor)}`)
133
-
134
- const nodeId = toNodeId(targetPeerDescriptor)
135
- const existingConnection = this.ongoingConnectAttempts.get(nodeId)
136
- if (existingConnection) {
137
- return existingConnection.managedConnection
138
- }
139
-
140
- const connection = this.createConnection(targetPeerDescriptor)
141
-
142
- const localNodeId = toNodeId(this.localPeerDescriptor!)
143
- const targetNodeId = toNodeId(targetPeerDescriptor)
144
- const offering = (getOfferer(localNodeId, targetNodeId) === 'local')
145
- let pendingConnection: PendingConnection
146
- const remoteConnector = new WebrtcConnectorRpcRemote(
147
- this.localPeerDescriptor!,
148
- targetPeerDescriptor,
149
- this.rpcCommunicator,
150
- WebrtcConnectorRpcClient
151
- )
152
- const delFunc = () => {
153
- this.ongoingConnectAttempts.delete(nodeId)
154
- connection.off('disconnected', delFunc)
155
- pendingConnection.off('disconnected', delFunc)
156
- pendingConnection.off('connected', delFunc)
157
- }
158
- if (offering) {
159
- pendingConnection = new PendingConnection(targetPeerDescriptor)
160
- createOutgoingHandshaker(this.localPeerDescriptor!, pendingConnection, connection, targetPeerDescriptor)
161
- connection.once('localDescription', (description: string) => {
162
- logger.trace('Sending offer to remote peer')
163
- remoteConnector.sendRtcOffer(description, connection.connectionId)
164
- })
165
- } else {
166
- pendingConnection = new PendingConnection(targetPeerDescriptor)
167
- const handshaker = createIncomingHandshaker(this.localPeerDescriptor!, pendingConnection, connection)
168
- connection.once('localDescription', (description: string) => {
169
- remoteConnector.sendRtcAnswer(description, connection.connectionId)
170
- })
171
- handshaker.on('handshakeRequest', (_sourceDescriptor: PeerDescriptor, remoteVersion: string) => {
172
- if (!isMaybeSupportedVersion(remoteVersion)) {
173
- rejectHandshake(pendingConnection!, connection, handshaker, HandshakeError.UNSUPPORTED_VERSION)
174
- } else {
175
- acceptHandshake(handshaker, pendingConnection, connection)
176
- }
177
- delFunc()
178
- })
179
- }
180
-
181
- this.ongoingConnectAttempts.set(targetNodeId, {
182
- managedConnection: pendingConnection,
183
- connection
184
- })
185
-
186
- connection.on('disconnected', delFunc)
187
- pendingConnection.on('disconnected', delFunc)
188
- pendingConnection.on('connected', delFunc)
189
-
190
- connection.on('localCandidate', (candidate: string, mid: string) => {
191
- if (this.options.externalIp !== undefined) {
192
- candidate = replaceInternalIpWithExternalIp(candidate, this.options.externalIp)
193
- logger.debug(`onLocalCandidate injected external ip ${candidate} ${mid}`)
194
- }
195
- remoteConnector.sendIceCandidate(candidate, mid, connection.connectionId)
196
- })
197
-
198
- connection.start(offering)
199
-
200
- if (!doNotRequestConnection && !offering) {
201
- remoteConnector.requestConnection()
202
- }
203
-
204
- return pendingConnection
205
- }
206
-
207
- private createConnection(targetPeerDescriptor: PeerDescriptor): NodeWebrtcConnection {
208
- return new NodeWebrtcConnection({
209
- remotePeerDescriptor: targetPeerDescriptor,
210
- iceServers: this.options.iceServers,
211
- bufferThresholdLow: this.options.bufferThresholdLow,
212
- bufferThresholdHigh: this.options.bufferThresholdHigh,
213
- portRange: this.options.portRange
214
- // TODO should we pass maxMessageSize?
215
- })
216
- }
217
-
218
- setLocalPeerDescriptor(peerDescriptor: PeerDescriptor): void {
219
- this.localPeerDescriptor = peerDescriptor
220
- }
221
-
222
- public async stop(): Promise<void> {
223
- logger.trace('stop()')
224
- this.stopped = true
225
-
226
- const attempts = Array.from(this.ongoingConnectAttempts.values())
227
- await Promise.allSettled(attempts.map(async (conn) => {
228
- conn.connection.destroy()
229
- conn.managedConnection.close(false)
230
- }))
231
-
232
- this.rpcCommunicator.destroy()
233
- }
234
- }
@@ -1,108 +0,0 @@
1
- import { ServerCallContext } from '@protobuf-ts/runtime-rpc'
2
- import { Logger } from '@streamr/utils'
3
- import { getAddressFromIceCandidate, isPrivateIPv4 } from '../../helpers/AddressTools'
4
- import { Empty } from '../../../generated/google/protobuf/empty'
5
- import {
6
- IceCandidate,
7
- PeerDescriptor,
8
- RtcAnswer,
9
- RtcOffer
10
- } from '../../../generated/packages/dht/protos/DhtRpc'
11
- import { IWebrtcConnectorRpc } from '../../../generated/packages/dht/protos/DhtRpc.server'
12
- import { DhtCallContext } from '../../rpc-protocol/DhtCallContext'
13
- import { ListeningRpcCommunicator } from '../../transport/ListeningRpcCommunicator'
14
- import { NodeWebrtcConnection } from './NodeWebrtcConnection'
15
- import { DhtAddress, toNodeId } from '../../identifiers'
16
- import { ConnectionID } from '../IConnection'
17
- import { ConnectingConnection } from './WebrtcConnector'
18
- import { PendingConnection } from '../PendingConnection'
19
-
20
- const logger = new Logger(module)
21
-
22
- interface WebrtcConnectorRpcLocalOptions {
23
- connect: (targetPeerDescriptor: PeerDescriptor, doNotRequestConnection: boolean) => PendingConnection
24
- onNewConnection: (connection: PendingConnection) => boolean
25
- // TODO pass accessor methods instead of passing a mutable entity
26
- ongoingConnectAttempts: Map<DhtAddress, ConnectingConnection>
27
- rpcCommunicator: ListeningRpcCommunicator
28
- getLocalPeerDescriptor: () => PeerDescriptor
29
- allowPrivateAddresses: boolean
30
- }
31
-
32
- export class WebrtcConnectorRpcLocal implements IWebrtcConnectorRpc {
33
-
34
- private readonly options: WebrtcConnectorRpcLocalOptions
35
-
36
- constructor(options: WebrtcConnectorRpcLocalOptions) {
37
- this.options = options
38
- }
39
-
40
- async requestConnection(context: ServerCallContext): Promise<Empty> {
41
- const targetPeerDescriptor = (context as DhtCallContext).incomingSourceDescriptor!
42
- if (this.options.ongoingConnectAttempts.has(toNodeId(targetPeerDescriptor))) {
43
- return {}
44
- }
45
- const pendingConnection = this.options.connect(targetPeerDescriptor, false)
46
- this.options.onNewConnection(pendingConnection)
47
- return {}
48
- }
49
-
50
- async rtcOffer(request: RtcOffer, context: ServerCallContext): Promise<Empty> {
51
- const remotePeerDescriptor = (context as DhtCallContext).incomingSourceDescriptor!
52
- const nodeId = toNodeId(remotePeerDescriptor)
53
- let connection: NodeWebrtcConnection
54
- let pendingConnection: PendingConnection
55
-
56
- if (!this.options.ongoingConnectAttempts.has(nodeId)) {
57
- pendingConnection = this.options.connect(remotePeerDescriptor, true)
58
- connection = this.options.ongoingConnectAttempts.get(nodeId)!.connection
59
- this.options.onNewConnection(pendingConnection)
60
- } else {
61
- pendingConnection = this.options.ongoingConnectAttempts.get(nodeId)!.managedConnection
62
- connection = this.options.ongoingConnectAttempts.get(nodeId)!.connection
63
- }
64
- // Always use offerers connectionId
65
- connection!.setConnectionId(request.connectionId as ConnectionID)
66
- connection!.setRemoteDescription(request.description, 'offer')
67
- return {}
68
- }
69
-
70
- async rtcAnswer(request: RtcAnswer, context: ServerCallContext): Promise<Empty> {
71
- const remotePeerDescriptor = (context as DhtCallContext).incomingSourceDescriptor!
72
- const nodeId = toNodeId(remotePeerDescriptor)
73
- const connection = this.options.ongoingConnectAttempts.get(nodeId)?.connection
74
- if (!connection) {
75
- return {}
76
- } else if (connection.connectionId !== request.connectionId) {
77
- logger.trace(`Ignoring RTC answer due to connectionId mismatch`)
78
- return {}
79
- }
80
- connection.setRemoteDescription(request.description, 'answer')
81
- return {}
82
- }
83
-
84
- async iceCandidate(request: IceCandidate, context: ServerCallContext): Promise<Empty> {
85
- const remotePeerDescriptor = (context as DhtCallContext).incomingSourceDescriptor!
86
- const nodeId = toNodeId(remotePeerDescriptor)
87
- const connection = this.options.ongoingConnectAttempts.get(nodeId)?.connection
88
- if (!connection) {
89
- return {}
90
- } else if (connection.connectionId !== request.connectionId) {
91
- logger.trace(`Ignoring remote candidate due to connectionId mismatch`)
92
- return {}
93
- } else if (this.isIceCandidateAllowed(request.candidate)) {
94
- connection.addRemoteCandidate(request.candidate, request.mid)
95
- }
96
- return {}
97
- }
98
-
99
- private isIceCandidateAllowed(candidate: string): boolean {
100
- if (!this.options.allowPrivateAddresses) {
101
- const address = getAddressFromIceCandidate(candidate)
102
- if ((address !== undefined) && isPrivateIPv4(address)) {
103
- return false
104
- }
105
- }
106
- return true
107
- }
108
- }
@@ -1,60 +0,0 @@
1
- import { Logger } from '@streamr/utils'
2
- import { RpcRemote } from '../../dht/contact/RpcRemote'
3
- import {
4
- IceCandidate,
5
- RtcAnswer,
6
- RtcOffer,
7
- WebrtcConnectionRequest
8
- } from '../../../generated/packages/dht/protos/DhtRpc'
9
- import { WebrtcConnectorRpcClient } from '../../../generated/packages/dht/protos/DhtRpc.client'
10
-
11
- const logger = new Logger(module)
12
-
13
- export class WebrtcConnectorRpcRemote extends RpcRemote<WebrtcConnectorRpcClient> {
14
-
15
- requestConnection(): void {
16
- const request: WebrtcConnectionRequest = {
17
- }
18
- const options = this.formDhtRpcOptions({
19
- notification: true
20
- })
21
- this.getClient().requestConnection(request, options).catch((_e) => {
22
- logger.trace('Failed to send requestConnection')
23
- })
24
- }
25
-
26
- sendRtcOffer(description: string, connectionId: string): void {
27
- const request: RtcOffer = {
28
- connectionId,
29
- description
30
- }
31
- const options = this.formDhtRpcOptions()
32
- this.getClient().rtcOffer(request, options).catch((_e) => {
33
- logger.trace('Failed to send rtcOffer')
34
- })
35
- }
36
-
37
- sendRtcAnswer(description: string, connectionId: string): void {
38
- const request: RtcAnswer = {
39
- connectionId,
40
- description
41
- }
42
- const options = this.formDhtRpcOptions()
43
- this.getClient().rtcAnswer(request, options).catch((_e) => {
44
- logger.trace('Failed to send rtcAnswer')
45
- })
46
- }
47
-
48
- sendIceCandidate(candidate: string, mid: string, connectionId: string): void {
49
- const request: IceCandidate = {
50
- connectionId,
51
- mid,
52
- candidate
53
- }
54
- const options = this.formDhtRpcOptions()
55
- this.getClient().iceCandidate(request, options).catch((_e) => {
56
- logger.trace('Failed to send iceCandidate')
57
- })
58
- }
59
- }
60
-
@@ -1,15 +0,0 @@
1
- import { IceServer } from './WebrtcConnector'
2
-
3
- export function iceServerAsString({ url, port, username, password, tcp }: IceServer): string {
4
- const [protocol, hostname] = url.split(':')
5
- if (hostname === undefined) {
6
- throw new Error(`invalid stun/turn format: ${url}`)
7
- }
8
- if (username === undefined && password === undefined) {
9
- return `${protocol}:${hostname}:${port}`
10
- }
11
- if (username !== undefined && password !== undefined) {
12
- return `${protocol}:${username}:${password}@${hostname}:${port}${(tcp !== undefined) ? '?transport=tcp' : ''}`
13
- }
14
- throw new Error(`username (${username}) and password (${password}) must be supplied together`)
15
- }