@streamr/dht 102.0.0-beta.1 → 102.0.0-beta.3

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 (211) 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/eslint.config.mjs +0 -12
  25. package/src/connection/Connection.ts +0 -28
  26. package/src/connection/ConnectionLockRpcLocal.ts +0 -78
  27. package/src/connection/ConnectionLockRpcRemote.ts +0 -64
  28. package/src/connection/ConnectionLockStates.ts +0 -131
  29. package/src/connection/ConnectionManager.ts +0 -661
  30. package/src/connection/ConnectionsView.ts +0 -8
  31. package/src/connection/ConnectorFacade.ts +0 -217
  32. package/src/connection/Handshaker.ts +0 -209
  33. package/src/connection/IConnection.ts +0 -40
  34. package/src/connection/ManagedConnection.ts +0 -113
  35. package/src/connection/OutputBuffer.ts +0 -28
  36. package/src/connection/PendingConnection.ts +0 -68
  37. package/src/connection/connectivityChecker.ts +0 -108
  38. package/src/connection/connectivityRequestHandler.ts +0 -116
  39. package/src/connection/simulator/Simulator.ts +0 -369
  40. package/src/connection/simulator/SimulatorConnection.ts +0 -137
  41. package/src/connection/simulator/SimulatorConnector.ts +0 -98
  42. package/src/connection/simulator/SimulatorTransport.ts +0 -15
  43. package/src/connection/simulator/pings.ts +0 -42
  44. package/src/connection/webrtc/BrowserWebrtcConnection.ts +0 -242
  45. package/src/connection/webrtc/IWebrtcConnection.ts +0 -24
  46. package/src/connection/webrtc/NodeWebrtcConnection.ts +0 -245
  47. package/src/connection/webrtc/WebrtcConnector.ts +0 -234
  48. package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +0 -108
  49. package/src/connection/webrtc/WebrtcConnectorRpcRemote.ts +0 -60
  50. package/src/connection/webrtc/iceServerAsString.ts +0 -15
  51. package/src/connection/websocket/AbstractWebsocketClientConnection.ts +0 -122
  52. package/src/connection/websocket/AutoCertifierClientFacade.ts +0 -89
  53. package/src/connection/websocket/BrowserWebsocketClientConnection.ts +0 -44
  54. package/src/connection/websocket/NodeWebsocketClientConnection.ts +0 -39
  55. package/src/connection/websocket/WebsocketClientConnector.ts +0 -119
  56. package/src/connection/websocket/WebsocketClientConnectorRpcLocal.ts +0 -38
  57. package/src/connection/websocket/WebsocketClientConnectorRpcRemote.ts +0 -19
  58. package/src/connection/websocket/WebsocketServer.ts +0 -164
  59. package/src/connection/websocket/WebsocketServerConnection.ts +0 -109
  60. package/src/connection/websocket/WebsocketServerConnector.ts +0 -290
  61. package/src/dht/DhtNode.ts +0 -683
  62. package/src/dht/DhtNodeRpcLocal.ts +0 -84
  63. package/src/dht/DhtNodeRpcRemote.ts +0 -107
  64. package/src/dht/ExternalApiRpcLocal.ts +0 -58
  65. package/src/dht/ExternalApiRpcRemote.ts +0 -41
  66. package/src/dht/PeerManager.ts +0 -305
  67. package/src/dht/contact/Contact.ts +0 -19
  68. package/src/dht/contact/ContactList.ts +0 -43
  69. package/src/dht/contact/RandomContactList.ts +0 -56
  70. package/src/dht/contact/RingContactList.ts +0 -143
  71. package/src/dht/contact/RpcRemote.ts +0 -72
  72. package/src/dht/contact/SortedContactList.ts +0 -173
  73. package/src/dht/contact/getClosestNodes.ts +0 -24
  74. package/src/dht/contact/ringIdentifiers.ts +0 -62
  75. package/src/dht/discovery/DiscoverySession.ts +0 -129
  76. package/src/dht/discovery/PeerDiscovery.ts +0 -244
  77. package/src/dht/discovery/RingDiscoverySession.ts +0 -148
  78. package/src/dht/recursive-operation/RecursiveOperationManager.ts +0 -251
  79. package/src/dht/recursive-operation/RecursiveOperationRpcLocal.ts +0 -34
  80. package/src/dht/recursive-operation/RecursiveOperationRpcRemote.ts +0 -43
  81. package/src/dht/recursive-operation/RecursiveOperationSession.ts +0 -231
  82. package/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.ts +0 -35
  83. package/src/dht/recursive-operation/RecursiveOperationSessionRpcRemote.ts +0 -30
  84. package/src/dht/routing/DuplicateDetector.ts +0 -34
  85. package/src/dht/routing/Router.ts +0 -246
  86. package/src/dht/routing/RouterRpcLocal.ts +0 -78
  87. package/src/dht/routing/RouterRpcRemote.ts +0 -80
  88. package/src/dht/routing/RoutingSession.ts +0 -243
  89. package/src/dht/routing/RoutingTablesCache.ts +0 -60
  90. package/src/dht/routing/getPreviousPeer.ts +0 -6
  91. package/src/dht/store/LocalDataStore.ts +0 -84
  92. package/src/dht/store/StoreManager.ts +0 -170
  93. package/src/dht/store/StoreRpcLocal.ts +0 -89
  94. package/src/dht/store/StoreRpcRemote.ts +0 -32
  95. package/src/exports.ts +0 -33
  96. package/src/helpers/AddressTools.ts +0 -28
  97. package/src/helpers/Connectivity.ts +0 -19
  98. package/src/helpers/browser/isBrowserEnvironment.ts +0 -1
  99. package/src/helpers/browser/isBrowserEnvironment_override.ts +0 -3
  100. package/src/helpers/createPeerDescriptor.ts +0 -57
  101. package/src/helpers/createPeerDescriptorSignaturePayload.ts +0 -28
  102. package/src/helpers/debugHelpers.ts +0 -9
  103. package/src/helpers/errors.ts +0 -49
  104. package/src/helpers/offering.ts +0 -15
  105. package/src/helpers/protoClasses.ts +0 -57
  106. package/src/helpers/protoToString.ts +0 -21
  107. package/src/helpers/version.ts +0 -32
  108. package/src/identifiers.ts +0 -29
  109. package/src/rpc-protocol/DhtCallContext.ts +0 -14
  110. package/src/rpc-protocol/DhtRpcOptions.ts +0 -10
  111. package/src/transport/ITransport.ts +0 -37
  112. package/src/transport/ListeningRpcCommunicator.ts +0 -32
  113. package/src/transport/RoutingRpcCommunicator.ts +0 -66
  114. package/src/types/ServiceID.ts +0 -1
  115. package/src/types/textencoding.d.ts +0 -6
  116. package/test/benchmark/Find.test.ts +0 -72
  117. package/test/benchmark/KademliaCorrectness.test.ts +0 -114
  118. package/test/benchmark/RingCorrectness.test.ts +0 -157
  119. package/test/benchmark/SortedContactListBenchmark.test.ts +0 -108
  120. package/test/benchmark/WebsocketServerMemoryLeak.test.ts +0 -41
  121. package/test/benchmark/hybrid-network-simulation/RingContactList.test.ts +0 -71
  122. package/test/end-to-end/GeoIpLayer0.test.ts +0 -55
  123. package/test/end-to-end/Layer0-Layer1.test.ts +0 -93
  124. package/test/end-to-end/Layer0.test.ts +0 -76
  125. package/test/end-to-end/Layer0MixedConnectionTypes.test.ts +0 -110
  126. package/test/end-to-end/Layer0Webrtc-Layer1.test.ts +0 -137
  127. package/test/end-to-end/Layer0Webrtc.test.ts +0 -85
  128. package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +0 -82
  129. package/test/end-to-end/Layer1-Scale-Webrtc.test.ts +0 -76
  130. package/test/end-to-end/RecoveryFromFailedAutoCertification.test.ts +0 -52
  131. package/test/end-to-end/WebsocketConnectionRequest.test.ts +0 -69
  132. package/test/end-to-end/memory-leak.test.ts +0 -80
  133. package/test/integration/ConnectionLocking.test.ts +0 -192
  134. package/test/integration/ConnectionManager.test.ts +0 -528
  135. package/test/integration/ConnectivityChecking.test.ts +0 -53
  136. package/test/integration/DhtJoinPeerDiscovery.test.ts +0 -49
  137. package/test/integration/DhtNode.test.ts +0 -66
  138. package/test/integration/DhtNodeExternalAPI.test.ts +0 -48
  139. package/test/integration/DhtNodeRpcRemote.test.ts +0 -66
  140. package/test/integration/DhtRpc.test.ts +0 -121
  141. package/test/integration/Find.test.ts +0 -45
  142. package/test/integration/GeoIpConnectivityChecking.test.ts +0 -72
  143. package/test/integration/Layer1-scale.test.ts +0 -189
  144. package/test/integration/Mock-Layer1-Layer0.test.ts +0 -85
  145. package/test/integration/MultipleEntryPointJoining.test.ts +0 -105
  146. package/test/integration/ReplicateData.test.ts +0 -104
  147. package/test/integration/RouteMessage.test.ts +0 -230
  148. package/test/integration/RouterRpcRemote.test.ts +0 -77
  149. package/test/integration/SimultaneousConnections.test.ts +0 -316
  150. package/test/integration/Store.test.ts +0 -85
  151. package/test/integration/StoreAndDelete.test.ts +0 -77
  152. package/test/integration/StoreOnDhtWithThreeNodes.test.ts +0 -59
  153. package/test/integration/StoreOnDhtWithTwoNodes.test.ts +0 -51
  154. package/test/integration/StoreRpcRemote.test.ts +0 -54
  155. package/test/integration/WebrtcConnectionManagement.test.ts +0 -191
  156. package/test/integration/WebrtcConnectorRpc.test.ts +0 -125
  157. package/test/integration/Websocket.test.ts +0 -65
  158. package/test/integration/WebsocketClientConnectorRpc.test.ts +0 -69
  159. package/test/integration/WebsocketConnectionManagement.test.ts +0 -191
  160. package/test/integration/rpc-connections-over-webrtc.test.ts +0 -123
  161. package/test/kademlia-simulation/data/nodeids.json +0 -13002
  162. package/test/kademlia-simulation/data/orderedneighbors.json +0 -1001
  163. package/test/types/global.d.ts +0 -1
  164. package/test/unit/AddressTools.test.ts +0 -44
  165. package/test/unit/AutoCertifierClientFacade.test.ts +0 -58
  166. package/test/unit/ConnectionManager.test.ts +0 -65
  167. package/test/unit/ConnectivityHelpers.test.ts +0 -61
  168. package/test/unit/DiscoverySession.test.ts +0 -87
  169. package/test/unit/DuplicateDetector.test.ts +0 -31
  170. package/test/unit/Handshaker.test.ts +0 -169
  171. package/test/unit/ListeningRpcCommunicator.test.ts +0 -52
  172. package/test/unit/LocalDataStore.test.ts +0 -108
  173. package/test/unit/ManagedConnection.test.ts +0 -58
  174. package/test/unit/PeerManager.test.ts +0 -93
  175. package/test/unit/PendingConnection.test.ts +0 -57
  176. package/test/unit/ProtobufMessage.test.ts +0 -21
  177. package/test/unit/RandomContactList.test.ts +0 -58
  178. package/test/unit/RecursiveOperationManager.test.ts +0 -161
  179. package/test/unit/RecursiveOperationSession.test.ts +0 -68
  180. package/test/unit/Router.test.ts +0 -137
  181. package/test/unit/RoutingSession.test.ts +0 -86
  182. package/test/unit/SortedContactList.test.ts +0 -115
  183. package/test/unit/StoreManager.test.ts +0 -146
  184. package/test/unit/StoreRpcLocal.test.ts +0 -167
  185. package/test/unit/WebrtcConnection.test.ts +0 -29
  186. package/test/unit/WebrtcConnector.test.ts +0 -56
  187. package/test/unit/WebsocketClientConnector.test.ts +0 -101
  188. package/test/unit/WebsocketServer.test.ts +0 -66
  189. package/test/unit/WebsocketServerConnector.test.ts +0 -102
  190. package/test/unit/connectivityRequestHandler.test.ts +0 -104
  191. package/test/unit/createPeerDescriptor.test.ts +0 -69
  192. package/test/unit/customMatchers.test.ts +0 -34
  193. package/test/unit/getClosestNodes.test.ts +0 -30
  194. package/test/unit/version.test.ts +0 -18
  195. package/test/unit/webrtcReplaceInternalIpWithExternalIp.test.ts +0 -18
  196. package/test/utils/FakeConnectorFacade.ts +0 -41
  197. package/test/utils/FakeRpcCommunicator.ts +0 -23
  198. package/test/utils/FakeTransport.ts +0 -79
  199. package/test/utils/customMatchers.ts +0 -71
  200. package/test/utils/mock/MockConnection.ts +0 -26
  201. package/test/utils/mock/MockConnectionsView.ts +0 -18
  202. package/test/utils/mock/MockRouter.ts +0 -62
  203. package/test/utils/mock/MockRpcCommunicator.ts +0 -7
  204. package/test/utils/mock/MockTransport.ts +0 -26
  205. package/test/utils/mock/mockDataEntry.ts +0 -38
  206. package/test/utils/topology.ts +0 -79
  207. package/test/utils/utils.ts +0 -268
  208. package/tsconfig.browser.json +0 -17
  209. package/tsconfig.jest.json +0 -25
  210. package/tsconfig.json +0 -3
  211. package/tsconfig.node.json +0 -24
@@ -1,245 +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
- import { DataChannel, DescriptionType, PeerConnection, initLogger } from 'node-datachannel'
6
- import { Logger } from '@streamr/utils'
7
- import { IllegalRtcPeerConnectionState } from '../../helpers/errors'
8
- import { iceServerAsString } from './iceServerAsString'
9
- import { IceServer, EARLY_TIMEOUT } from './WebrtcConnector'
10
- import { PortRange } from '../ConnectionManager'
11
- import { toNodeId } from '../../identifiers'
12
- import { createRandomConnectionId } from '../Connection'
13
-
14
- const logger = new Logger(module)
15
-
16
- export interface Params {
17
- remotePeerDescriptor: PeerDescriptor
18
- bufferThresholdHigh?: number
19
- bufferThresholdLow?: number
20
- maxMessageSize?: number
21
- iceServers?: IceServer[] // TODO make this parameter required (empty array is a good fallback which can be set by the caller if needed)
22
- portRange?: PortRange
23
- }
24
-
25
- // Re-defined accoring to https://github.com/microsoft/TypeScript/blob/main/src/lib/dom.generated.d.ts
26
- // because importing single dom definitions in not possible
27
-
28
- enum RtcPeerConnectionStateEnum {
29
- closed = 'closed',
30
- connected = 'connected',
31
- connecting = 'connecting',
32
- disconnected = 'disconnected',
33
- failed = 'failed',
34
- new = 'new'
35
- }
36
-
37
- initLogger('Fatal')
38
-
39
- type RtcPeerConnectionState = keyof typeof RtcPeerConnectionStateEnum
40
-
41
- type Events = WebrtcConnectionEvents & ConnectionEvents
42
-
43
- export class NodeWebrtcConnection extends EventEmitter<Events> implements IConnection, IWebrtcConnection {
44
-
45
- public connectionId: ConnectionID
46
- private connection?: PeerConnection
47
- private dataChannel?: DataChannel
48
- private lastState: RtcPeerConnectionState = 'connecting'
49
- private remoteDescriptionSet = false
50
- public readonly connectionType: ConnectionType = ConnectionType.WEBRTC
51
- private readonly iceServers: IceServer[]
52
- private readonly _bufferThresholdHigh: number // TODO: buffer handling must be implemented before production use (NET-938)
53
- private readonly bufferThresholdLow: number
54
- private readonly remotePeerDescriptor: PeerDescriptor
55
- private readonly portRange?: PortRange
56
- private readonly maxMessageSize?: number
57
- private closed = false
58
- private offering?: boolean
59
- private readonly earlyTimeout: NodeJS.Timeout
60
-
61
- constructor(params: Params) {
62
- super()
63
- this.connectionId = createRandomConnectionId()
64
- this.iceServers = params.iceServers ?? []
65
- // eslint-disable-next-line no-underscore-dangle
66
- this._bufferThresholdHigh = params.bufferThresholdHigh ?? 2 ** 17
67
- this.bufferThresholdLow = params.bufferThresholdLow ?? 2 ** 15
68
- this.remotePeerDescriptor = params.remotePeerDescriptor
69
- this.maxMessageSize = params.maxMessageSize ?? 1048576
70
- this.portRange = params.portRange
71
- this.earlyTimeout = setTimeout(() => {
72
- this.doClose(false, 'timed out due to remote descriptor not being set')
73
- }, EARLY_TIMEOUT)
74
- }
75
-
76
- public start(isOffering: boolean): void {
77
- const nodeId = toNodeId(this.remotePeerDescriptor)
78
- this.offering = isOffering
79
- logger.trace(`Starting new connection for peer ${nodeId}`, { isOffering })
80
- this.connection = new PeerConnection(nodeId, {
81
- iceServers: this.iceServers.map(iceServerAsString),
82
- maxMessageSize: this.maxMessageSize,
83
- portRangeBegin: this.portRange?.min,
84
- portRangeEnd: this.portRange?.max,
85
- })
86
-
87
- this.connection.onStateChange((state: string) => this.onStateChange(state))
88
- this.connection.onGatheringStateChange(() => {})
89
-
90
- this.connection.onLocalDescription((description: string, type: DescriptionType) => {
91
- this.emit('localDescription', description, type.toString())
92
- })
93
- this.connection.onLocalCandidate((candidate: string, mid: string) => {
94
- this.emit('localCandidate', candidate, mid)
95
- })
96
- if (isOffering) {
97
- const dataChannel = this.connection.createDataChannel('streamrDataChannel')
98
- this.setupDataChannel(dataChannel)
99
- } else {
100
- this.connection.onDataChannel((dataChannel) => this.setupDataChannel(dataChannel))
101
- }
102
- }
103
-
104
- public async setRemoteDescription(description: string, type: string): Promise<void> {
105
- if (this.connection) {
106
- clearTimeout(this.earlyTimeout)
107
- const remoteNodeId = toNodeId(this.remotePeerDescriptor)
108
- try {
109
- logger.trace(`Setting remote descriptor for peer: ${remoteNodeId}`)
110
- this.connection.setRemoteDescription(description, type as DescriptionType)
111
- this.remoteDescriptionSet = true
112
- } catch {
113
- logger.debug(`Failed to set remote descriptor for peer ${remoteNodeId}`)
114
- }
115
- } else {
116
- this.doClose(false, `Tried to set description for non-existent connection`)
117
- }
118
- }
119
-
120
- public addRemoteCandidate(candidate: string, mid: string): void {
121
- if (this.connection) {
122
- if (this.remoteDescriptionSet) {
123
- const remoteNodeId = toNodeId(this.remotePeerDescriptor)
124
- try {
125
- logger.trace(`Setting remote candidate for peer: ${remoteNodeId}`)
126
- this.connection.addRemoteCandidate(candidate, mid)
127
- } catch {
128
- logger.debug(`Failed to set remote candidate for peer ${remoteNodeId}`)
129
- }
130
- } else {
131
- // TODO: should queue candidates until remote description is set?
132
- this.doClose(false, `Tried to set candidate before description`)
133
- }
134
- } else {
135
- this.doClose(false, `Tried to set candidate for non-existent connection`)
136
- }
137
- }
138
-
139
- public send(data: Uint8Array): void {
140
- if (this.isOpen()) {
141
- try {
142
- this.dataChannel!.sendMessageBinary(data as Buffer)
143
- } catch (err) {
144
- const remoteNodeId = toNodeId(this.remotePeerDescriptor)
145
- logger.debug('Failed to send binary message to ' + remoteNodeId + err)
146
- }
147
- }
148
- }
149
-
150
- public async close(gracefulLeave: boolean, reason?: string): Promise<void> {
151
- this.doClose(gracefulLeave, reason)
152
- }
153
-
154
- private doClose(gracefulLeave: boolean, reason?: string): void {
155
- if (!this.closed) {
156
- clearTimeout(this.earlyTimeout)
157
- const remoteNodeId = toNodeId(this.remotePeerDescriptor)
158
- logger.trace(`Closing Node WebRTC Connection to ${remoteNodeId}` + `${(reason !== undefined) ? `, reason: ${reason}` : ''}`)
159
-
160
- this.closed = true
161
-
162
- this.emit('disconnected', gracefulLeave, undefined, reason)
163
- this.removeAllListeners()
164
-
165
- if (this.dataChannel) {
166
- try {
167
- logger.trace('closing datachannel')
168
- this.dataChannel.close()
169
- } catch (e) {
170
- logger.trace('dc.close() errored: %s', e)
171
- }
172
- }
173
-
174
- if (this.connection) {
175
- try {
176
- this.connection.close()
177
- } catch (e) {
178
- logger.trace('conn.close() errored: %s', e)
179
- }
180
- }
181
- this.connection = undefined
182
- this.dataChannel = undefined
183
- }
184
- }
185
-
186
- public destroy(): void {
187
- this.removeAllListeners()
188
- this.doClose(false)
189
- }
190
-
191
- private setupDataChannel(dataChannel: DataChannel): void {
192
- this.dataChannel = dataChannel
193
- dataChannel.setBufferedAmountLowThreshold(this.bufferThresholdLow)
194
- dataChannel.onOpen(() => {
195
- logger.trace(`dc.onOpened`)
196
- this.onDataChannelOpen()
197
- })
198
-
199
- dataChannel.onClosed(() => {
200
- logger.trace(`dc.closed`)
201
- this.doClose(false, 'DataChannel closed')
202
- })
203
-
204
- dataChannel.onError((err) => logger.error('error', { err }))
205
-
206
- dataChannel.onBufferedAmountLow(() => {
207
- logger.trace(`dc.onBufferedAmountLow`)
208
- })
209
-
210
- dataChannel.onMessage((msg) => {
211
- logger.trace(`dc.onMessage`)
212
- this.emit('data', msg as Buffer)
213
- })
214
- }
215
-
216
- private onDataChannelOpen(): void {
217
- logger.trace(`DataChannel opened for peer ${toNodeId(this.remotePeerDescriptor)}`)
218
- this.emit('connected')
219
- }
220
-
221
- private onStateChange(state: string): void {
222
- logger.trace('onStateChange ' + state)
223
- if (!Object.keys(RtcPeerConnectionStateEnum).filter((s) => isNaN(+s)).includes(state)) {
224
- throw new IllegalRtcPeerConnectionState('NodeWebrtcConnection used an unknown state: ' + state)
225
- } else {
226
- this.lastState = state as RtcPeerConnectionState
227
- }
228
-
229
- if (state === RtcPeerConnectionStateEnum.closed
230
- || state === RtcPeerConnectionStateEnum.disconnected
231
- || state === RtcPeerConnectionStateEnum.failed
232
- ) {
233
- this.doClose(false)
234
- }
235
-
236
- }
237
-
238
- isOpen(): boolean {
239
- return !this.closed && this.lastState === 'connected' && !!this.dataChannel
240
- }
241
-
242
- public setConnectionId(connectionId: ConnectionID): void {
243
- this.connectionId = connectionId
244
- }
245
- }
@@ -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 { isMaybeSupportedProtocolVersion } 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 (!isMaybeSupportedProtocolVersion(remoteVersion)) {
173
- rejectHandshake(pendingConnection!, connection, handshaker, HandshakeError.UNSUPPORTED_PROTOCOL_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
- }