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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (210) hide show
  1. package/dist/generated/google/protobuf/any.d.ts +180 -0
  2. package/dist/generated/google/protobuf/any.js +155 -0
  3. package/dist/generated/google/protobuf/any.js.map +1 -0
  4. package/dist/generated/google/protobuf/empty.d.ts +31 -0
  5. package/dist/generated/google/protobuf/empty.js +32 -0
  6. package/dist/generated/google/protobuf/empty.js.map +1 -0
  7. package/dist/generated/google/protobuf/timestamp.d.ts +155 -0
  8. package/dist/generated/google/protobuf/timestamp.js +136 -0
  9. package/dist/generated/google/protobuf/timestamp.js.map +1 -0
  10. package/dist/generated/packages/dht/protos/DhtRpc.client.d.ts +361 -0
  11. package/dist/generated/packages/dht/protos/DhtRpc.client.js +285 -0
  12. package/dist/generated/packages/dht/protos/DhtRpc.client.js.map +1 -0
  13. package/dist/generated/packages/dht/protos/DhtRpc.d.ts +999 -0
  14. package/dist/generated/packages/dht/protos/DhtRpc.js +677 -0
  15. package/dist/generated/packages/dht/protos/DhtRpc.js.map +1 -0
  16. package/dist/generated/packages/dht/protos/DhtRpc.server.d.ts +162 -0
  17. package/dist/generated/packages/dht/protos/DhtRpc.server.js +3 -0
  18. package/dist/generated/packages/dht/protos/DhtRpc.server.js.map +1 -0
  19. package/dist/generated/packages/proto-rpc/protos/ProtoRpc.d.ts +87 -0
  20. package/dist/generated/packages/proto-rpc/protos/ProtoRpc.js +66 -0
  21. package/dist/generated/packages/proto-rpc/protos/ProtoRpc.js.map +1 -0
  22. package/dist/package.json +7 -7
  23. package/package.json +7 -7
  24. package/src/connection/Connection.ts +0 -28
  25. package/src/connection/ConnectionLockRpcLocal.ts +0 -78
  26. package/src/connection/ConnectionLockRpcRemote.ts +0 -64
  27. package/src/connection/ConnectionLockStates.ts +0 -131
  28. package/src/connection/ConnectionManager.ts +0 -661
  29. package/src/connection/ConnectionsView.ts +0 -8
  30. package/src/connection/ConnectorFacade.ts +0 -217
  31. package/src/connection/Handshaker.ts +0 -209
  32. package/src/connection/IConnection.ts +0 -40
  33. package/src/connection/ManagedConnection.ts +0 -113
  34. package/src/connection/OutputBuffer.ts +0 -28
  35. package/src/connection/PendingConnection.ts +0 -68
  36. package/src/connection/connectivityChecker.ts +0 -108
  37. package/src/connection/connectivityRequestHandler.ts +0 -116
  38. package/src/connection/simulator/Simulator.ts +0 -369
  39. package/src/connection/simulator/SimulatorConnection.ts +0 -137
  40. package/src/connection/simulator/SimulatorConnector.ts +0 -98
  41. package/src/connection/simulator/SimulatorTransport.ts +0 -15
  42. package/src/connection/simulator/pings.ts +0 -42
  43. package/src/connection/webrtc/BrowserWebrtcConnection.ts +0 -242
  44. package/src/connection/webrtc/IWebrtcConnection.ts +0 -24
  45. package/src/connection/webrtc/NodeWebrtcConnection.ts +0 -245
  46. package/src/connection/webrtc/WebrtcConnector.ts +0 -234
  47. package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +0 -108
  48. package/src/connection/webrtc/WebrtcConnectorRpcRemote.ts +0 -60
  49. package/src/connection/webrtc/iceServerAsString.ts +0 -15
  50. package/src/connection/websocket/AbstractWebsocketClientConnection.ts +0 -122
  51. package/src/connection/websocket/AutoCertifierClientFacade.ts +0 -89
  52. package/src/connection/websocket/BrowserWebsocketClientConnection.ts +0 -44
  53. package/src/connection/websocket/NodeWebsocketClientConnection.ts +0 -39
  54. package/src/connection/websocket/WebsocketClientConnector.ts +0 -119
  55. package/src/connection/websocket/WebsocketClientConnectorRpcLocal.ts +0 -38
  56. package/src/connection/websocket/WebsocketClientConnectorRpcRemote.ts +0 -19
  57. package/src/connection/websocket/WebsocketServer.ts +0 -164
  58. package/src/connection/websocket/WebsocketServerConnection.ts +0 -109
  59. package/src/connection/websocket/WebsocketServerConnector.ts +0 -290
  60. package/src/dht/DhtNode.ts +0 -683
  61. package/src/dht/DhtNodeRpcLocal.ts +0 -84
  62. package/src/dht/DhtNodeRpcRemote.ts +0 -107
  63. package/src/dht/ExternalApiRpcLocal.ts +0 -58
  64. package/src/dht/ExternalApiRpcRemote.ts +0 -41
  65. package/src/dht/PeerManager.ts +0 -305
  66. package/src/dht/contact/Contact.ts +0 -19
  67. package/src/dht/contact/ContactList.ts +0 -43
  68. package/src/dht/contact/RandomContactList.ts +0 -56
  69. package/src/dht/contact/RingContactList.ts +0 -143
  70. package/src/dht/contact/RpcRemote.ts +0 -72
  71. package/src/dht/contact/SortedContactList.ts +0 -173
  72. package/src/dht/contact/getClosestNodes.ts +0 -24
  73. package/src/dht/contact/ringIdentifiers.ts +0 -62
  74. package/src/dht/discovery/DiscoverySession.ts +0 -129
  75. package/src/dht/discovery/PeerDiscovery.ts +0 -244
  76. package/src/dht/discovery/RingDiscoverySession.ts +0 -148
  77. package/src/dht/recursive-operation/RecursiveOperationManager.ts +0 -251
  78. package/src/dht/recursive-operation/RecursiveOperationRpcLocal.ts +0 -34
  79. package/src/dht/recursive-operation/RecursiveOperationRpcRemote.ts +0 -43
  80. package/src/dht/recursive-operation/RecursiveOperationSession.ts +0 -231
  81. package/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.ts +0 -35
  82. package/src/dht/recursive-operation/RecursiveOperationSessionRpcRemote.ts +0 -30
  83. package/src/dht/routing/DuplicateDetector.ts +0 -34
  84. package/src/dht/routing/Router.ts +0 -246
  85. package/src/dht/routing/RouterRpcLocal.ts +0 -78
  86. package/src/dht/routing/RouterRpcRemote.ts +0 -80
  87. package/src/dht/routing/RoutingSession.ts +0 -243
  88. package/src/dht/routing/RoutingTablesCache.ts +0 -60
  89. package/src/dht/routing/getPreviousPeer.ts +0 -6
  90. package/src/dht/store/LocalDataStore.ts +0 -84
  91. package/src/dht/store/StoreManager.ts +0 -170
  92. package/src/dht/store/StoreRpcLocal.ts +0 -89
  93. package/src/dht/store/StoreRpcRemote.ts +0 -32
  94. package/src/exports.ts +0 -33
  95. package/src/helpers/AddressTools.ts +0 -28
  96. package/src/helpers/Connectivity.ts +0 -19
  97. package/src/helpers/browser/isBrowserEnvironment.ts +0 -1
  98. package/src/helpers/browser/isBrowserEnvironment_override.ts +0 -3
  99. package/src/helpers/createPeerDescriptor.ts +0 -57
  100. package/src/helpers/createPeerDescriptorSignaturePayload.ts +0 -28
  101. package/src/helpers/debugHelpers.ts +0 -9
  102. package/src/helpers/errors.ts +0 -49
  103. package/src/helpers/offering.ts +0 -15
  104. package/src/helpers/protoClasses.ts +0 -57
  105. package/src/helpers/protoToString.ts +0 -21
  106. package/src/helpers/version.ts +0 -32
  107. package/src/identifiers.ts +0 -29
  108. package/src/rpc-protocol/DhtCallContext.ts +0 -14
  109. package/src/rpc-protocol/DhtRpcOptions.ts +0 -10
  110. package/src/transport/ITransport.ts +0 -37
  111. package/src/transport/ListeningRpcCommunicator.ts +0 -32
  112. package/src/transport/RoutingRpcCommunicator.ts +0 -66
  113. package/src/types/ServiceID.ts +0 -1
  114. package/src/types/textencoding.d.ts +0 -6
  115. package/test/benchmark/Find.test.ts +0 -72
  116. package/test/benchmark/KademliaCorrectness.test.ts +0 -114
  117. package/test/benchmark/RingCorrectness.test.ts +0 -157
  118. package/test/benchmark/SortedContactListBenchmark.test.ts +0 -108
  119. package/test/benchmark/WebsocketServerMemoryLeak.test.ts +0 -41
  120. package/test/benchmark/hybrid-network-simulation/RingContactList.test.ts +0 -71
  121. package/test/end-to-end/GeoIpLayer0.test.ts +0 -55
  122. package/test/end-to-end/Layer0-Layer1.test.ts +0 -93
  123. package/test/end-to-end/Layer0.test.ts +0 -76
  124. package/test/end-to-end/Layer0MixedConnectionTypes.test.ts +0 -110
  125. package/test/end-to-end/Layer0Webrtc-Layer1.test.ts +0 -137
  126. package/test/end-to-end/Layer0Webrtc.test.ts +0 -85
  127. package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +0 -82
  128. package/test/end-to-end/Layer1-Scale-Webrtc.test.ts +0 -76
  129. package/test/end-to-end/RecoveryFromFailedAutoCertification.test.ts +0 -52
  130. package/test/end-to-end/WebsocketConnectionRequest.test.ts +0 -69
  131. package/test/end-to-end/memory-leak.test.ts +0 -80
  132. package/test/integration/ConnectionLocking.test.ts +0 -192
  133. package/test/integration/ConnectionManager.test.ts +0 -528
  134. package/test/integration/ConnectivityChecking.test.ts +0 -53
  135. package/test/integration/DhtJoinPeerDiscovery.test.ts +0 -49
  136. package/test/integration/DhtNode.test.ts +0 -66
  137. package/test/integration/DhtNodeExternalAPI.test.ts +0 -48
  138. package/test/integration/DhtNodeRpcRemote.test.ts +0 -66
  139. package/test/integration/DhtRpc.test.ts +0 -121
  140. package/test/integration/Find.test.ts +0 -45
  141. package/test/integration/GeoIpConnectivityChecking.test.ts +0 -72
  142. package/test/integration/Layer1-scale.test.ts +0 -189
  143. package/test/integration/Mock-Layer1-Layer0.test.ts +0 -85
  144. package/test/integration/MultipleEntryPointJoining.test.ts +0 -105
  145. package/test/integration/ReplicateData.test.ts +0 -104
  146. package/test/integration/RouteMessage.test.ts +0 -230
  147. package/test/integration/RouterRpcRemote.test.ts +0 -77
  148. package/test/integration/SimultaneousConnections.test.ts +0 -316
  149. package/test/integration/Store.test.ts +0 -85
  150. package/test/integration/StoreAndDelete.test.ts +0 -77
  151. package/test/integration/StoreOnDhtWithThreeNodes.test.ts +0 -59
  152. package/test/integration/StoreOnDhtWithTwoNodes.test.ts +0 -51
  153. package/test/integration/StoreRpcRemote.test.ts +0 -54
  154. package/test/integration/WebrtcConnectionManagement.test.ts +0 -191
  155. package/test/integration/WebrtcConnectorRpc.test.ts +0 -125
  156. package/test/integration/Websocket.test.ts +0 -65
  157. package/test/integration/WebsocketClientConnectorRpc.test.ts +0 -69
  158. package/test/integration/WebsocketConnectionManagement.test.ts +0 -191
  159. package/test/integration/rpc-connections-over-webrtc.test.ts +0 -123
  160. package/test/kademlia-simulation/data/nodeids.json +0 -13002
  161. package/test/kademlia-simulation/data/orderedneighbors.json +0 -1001
  162. package/test/types/global.d.ts +0 -1
  163. package/test/unit/AddressTools.test.ts +0 -44
  164. package/test/unit/AutoCertifierClientFacade.test.ts +0 -58
  165. package/test/unit/ConnectionManager.test.ts +0 -65
  166. package/test/unit/ConnectivityHelpers.test.ts +0 -61
  167. package/test/unit/DiscoverySession.test.ts +0 -87
  168. package/test/unit/DuplicateDetector.test.ts +0 -31
  169. package/test/unit/Handshaker.test.ts +0 -169
  170. package/test/unit/ListeningRpcCommunicator.test.ts +0 -52
  171. package/test/unit/LocalDataStore.test.ts +0 -108
  172. package/test/unit/ManagedConnection.test.ts +0 -58
  173. package/test/unit/PeerManager.test.ts +0 -93
  174. package/test/unit/PendingConnection.test.ts +0 -57
  175. package/test/unit/ProtobufMessage.test.ts +0 -21
  176. package/test/unit/RandomContactList.test.ts +0 -58
  177. package/test/unit/RecursiveOperationManager.test.ts +0 -161
  178. package/test/unit/RecursiveOperationSession.test.ts +0 -68
  179. package/test/unit/Router.test.ts +0 -137
  180. package/test/unit/RoutingSession.test.ts +0 -86
  181. package/test/unit/SortedContactList.test.ts +0 -115
  182. package/test/unit/StoreManager.test.ts +0 -146
  183. package/test/unit/StoreRpcLocal.test.ts +0 -167
  184. package/test/unit/WebrtcConnection.test.ts +0 -29
  185. package/test/unit/WebrtcConnector.test.ts +0 -56
  186. package/test/unit/WebsocketClientConnector.test.ts +0 -101
  187. package/test/unit/WebsocketServer.test.ts +0 -66
  188. package/test/unit/WebsocketServerConnector.test.ts +0 -102
  189. package/test/unit/connectivityRequestHandler.test.ts +0 -104
  190. package/test/unit/createPeerDescriptor.test.ts +0 -69
  191. package/test/unit/customMatchers.test.ts +0 -34
  192. package/test/unit/getClosestNodes.test.ts +0 -30
  193. package/test/unit/version.test.ts +0 -18
  194. package/test/unit/webrtcReplaceInternalIpWithExternalIp.test.ts +0 -18
  195. package/test/utils/FakeConnectorFacade.ts +0 -41
  196. package/test/utils/FakeRpcCommunicator.ts +0 -23
  197. package/test/utils/FakeTransport.ts +0 -79
  198. package/test/utils/customMatchers.ts +0 -71
  199. package/test/utils/mock/MockConnection.ts +0 -26
  200. package/test/utils/mock/MockConnectionsView.ts +0 -18
  201. package/test/utils/mock/MockRouter.ts +0 -62
  202. package/test/utils/mock/MockRpcCommunicator.ts +0 -7
  203. package/test/utils/mock/MockTransport.ts +0 -26
  204. package/test/utils/mock/mockDataEntry.ts +0 -38
  205. package/test/utils/topology.ts +0 -79
  206. package/test/utils/utils.ts +0 -268
  207. package/tsconfig.browser.json +0 -17
  208. package/tsconfig.jest.json +0 -25
  209. package/tsconfig.json +0 -3
  210. package/tsconfig.node.json +0 -24
@@ -1,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
- }