@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.
- package/dist/generated/google/protobuf/any.d.ts +180 -0
- package/dist/generated/google/protobuf/any.js +155 -0
- package/dist/generated/google/protobuf/any.js.map +1 -0
- package/dist/generated/google/protobuf/empty.d.ts +31 -0
- package/dist/generated/google/protobuf/empty.js +32 -0
- package/dist/generated/google/protobuf/empty.js.map +1 -0
- package/dist/generated/google/protobuf/timestamp.d.ts +155 -0
- package/dist/generated/google/protobuf/timestamp.js +136 -0
- package/dist/generated/google/protobuf/timestamp.js.map +1 -0
- package/dist/generated/packages/dht/protos/DhtRpc.client.d.ts +361 -0
- package/dist/generated/packages/dht/protos/DhtRpc.client.js +285 -0
- package/dist/generated/packages/dht/protos/DhtRpc.client.js.map +1 -0
- package/dist/generated/packages/dht/protos/DhtRpc.d.ts +999 -0
- package/dist/generated/packages/dht/protos/DhtRpc.js +677 -0
- package/dist/generated/packages/dht/protos/DhtRpc.js.map +1 -0
- package/dist/generated/packages/dht/protos/DhtRpc.server.d.ts +162 -0
- package/dist/generated/packages/dht/protos/DhtRpc.server.js +3 -0
- package/dist/generated/packages/dht/protos/DhtRpc.server.js.map +1 -0
- package/dist/generated/packages/proto-rpc/protos/ProtoRpc.d.ts +87 -0
- package/dist/generated/packages/proto-rpc/protos/ProtoRpc.js +66 -0
- package/dist/generated/packages/proto-rpc/protos/ProtoRpc.js.map +1 -0
- package/dist/package.json +7 -7
- package/package.json +7 -7
- package/eslint.config.mjs +0 -12
- package/src/connection/Connection.ts +0 -28
- package/src/connection/ConnectionLockRpcLocal.ts +0 -78
- package/src/connection/ConnectionLockRpcRemote.ts +0 -64
- package/src/connection/ConnectionLockStates.ts +0 -131
- package/src/connection/ConnectionManager.ts +0 -661
- package/src/connection/ConnectionsView.ts +0 -8
- package/src/connection/ConnectorFacade.ts +0 -217
- package/src/connection/Handshaker.ts +0 -209
- package/src/connection/IConnection.ts +0 -40
- package/src/connection/ManagedConnection.ts +0 -113
- package/src/connection/OutputBuffer.ts +0 -28
- package/src/connection/PendingConnection.ts +0 -68
- package/src/connection/connectivityChecker.ts +0 -108
- package/src/connection/connectivityRequestHandler.ts +0 -116
- package/src/connection/simulator/Simulator.ts +0 -369
- package/src/connection/simulator/SimulatorConnection.ts +0 -137
- package/src/connection/simulator/SimulatorConnector.ts +0 -98
- package/src/connection/simulator/SimulatorTransport.ts +0 -15
- package/src/connection/simulator/pings.ts +0 -42
- package/src/connection/webrtc/BrowserWebrtcConnection.ts +0 -242
- package/src/connection/webrtc/IWebrtcConnection.ts +0 -24
- package/src/connection/webrtc/NodeWebrtcConnection.ts +0 -245
- package/src/connection/webrtc/WebrtcConnector.ts +0 -234
- package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +0 -108
- package/src/connection/webrtc/WebrtcConnectorRpcRemote.ts +0 -60
- package/src/connection/webrtc/iceServerAsString.ts +0 -15
- package/src/connection/websocket/AbstractWebsocketClientConnection.ts +0 -122
- package/src/connection/websocket/AutoCertifierClientFacade.ts +0 -89
- package/src/connection/websocket/BrowserWebsocketClientConnection.ts +0 -44
- package/src/connection/websocket/NodeWebsocketClientConnection.ts +0 -39
- package/src/connection/websocket/WebsocketClientConnector.ts +0 -119
- package/src/connection/websocket/WebsocketClientConnectorRpcLocal.ts +0 -38
- package/src/connection/websocket/WebsocketClientConnectorRpcRemote.ts +0 -19
- package/src/connection/websocket/WebsocketServer.ts +0 -164
- package/src/connection/websocket/WebsocketServerConnection.ts +0 -109
- package/src/connection/websocket/WebsocketServerConnector.ts +0 -290
- package/src/dht/DhtNode.ts +0 -683
- package/src/dht/DhtNodeRpcLocal.ts +0 -84
- package/src/dht/DhtNodeRpcRemote.ts +0 -107
- package/src/dht/ExternalApiRpcLocal.ts +0 -58
- package/src/dht/ExternalApiRpcRemote.ts +0 -41
- package/src/dht/PeerManager.ts +0 -305
- package/src/dht/contact/Contact.ts +0 -19
- package/src/dht/contact/ContactList.ts +0 -43
- package/src/dht/contact/RandomContactList.ts +0 -56
- package/src/dht/contact/RingContactList.ts +0 -143
- package/src/dht/contact/RpcRemote.ts +0 -72
- package/src/dht/contact/SortedContactList.ts +0 -173
- package/src/dht/contact/getClosestNodes.ts +0 -24
- package/src/dht/contact/ringIdentifiers.ts +0 -62
- package/src/dht/discovery/DiscoverySession.ts +0 -129
- package/src/dht/discovery/PeerDiscovery.ts +0 -244
- package/src/dht/discovery/RingDiscoverySession.ts +0 -148
- package/src/dht/recursive-operation/RecursiveOperationManager.ts +0 -251
- package/src/dht/recursive-operation/RecursiveOperationRpcLocal.ts +0 -34
- package/src/dht/recursive-operation/RecursiveOperationRpcRemote.ts +0 -43
- package/src/dht/recursive-operation/RecursiveOperationSession.ts +0 -231
- package/src/dht/recursive-operation/RecursiveOperationSessionRpcLocal.ts +0 -35
- package/src/dht/recursive-operation/RecursiveOperationSessionRpcRemote.ts +0 -30
- package/src/dht/routing/DuplicateDetector.ts +0 -34
- package/src/dht/routing/Router.ts +0 -246
- package/src/dht/routing/RouterRpcLocal.ts +0 -78
- package/src/dht/routing/RouterRpcRemote.ts +0 -80
- package/src/dht/routing/RoutingSession.ts +0 -243
- package/src/dht/routing/RoutingTablesCache.ts +0 -60
- package/src/dht/routing/getPreviousPeer.ts +0 -6
- package/src/dht/store/LocalDataStore.ts +0 -84
- package/src/dht/store/StoreManager.ts +0 -170
- package/src/dht/store/StoreRpcLocal.ts +0 -89
- package/src/dht/store/StoreRpcRemote.ts +0 -32
- package/src/exports.ts +0 -33
- package/src/helpers/AddressTools.ts +0 -28
- package/src/helpers/Connectivity.ts +0 -19
- package/src/helpers/browser/isBrowserEnvironment.ts +0 -1
- package/src/helpers/browser/isBrowserEnvironment_override.ts +0 -3
- package/src/helpers/createPeerDescriptor.ts +0 -57
- package/src/helpers/createPeerDescriptorSignaturePayload.ts +0 -28
- package/src/helpers/debugHelpers.ts +0 -9
- package/src/helpers/errors.ts +0 -49
- package/src/helpers/offering.ts +0 -15
- package/src/helpers/protoClasses.ts +0 -57
- package/src/helpers/protoToString.ts +0 -21
- package/src/helpers/version.ts +0 -32
- package/src/identifiers.ts +0 -29
- package/src/rpc-protocol/DhtCallContext.ts +0 -14
- package/src/rpc-protocol/DhtRpcOptions.ts +0 -10
- package/src/transport/ITransport.ts +0 -37
- package/src/transport/ListeningRpcCommunicator.ts +0 -32
- package/src/transport/RoutingRpcCommunicator.ts +0 -66
- package/src/types/ServiceID.ts +0 -1
- package/src/types/textencoding.d.ts +0 -6
- package/test/benchmark/Find.test.ts +0 -72
- package/test/benchmark/KademliaCorrectness.test.ts +0 -114
- package/test/benchmark/RingCorrectness.test.ts +0 -157
- package/test/benchmark/SortedContactListBenchmark.test.ts +0 -108
- package/test/benchmark/WebsocketServerMemoryLeak.test.ts +0 -41
- package/test/benchmark/hybrid-network-simulation/RingContactList.test.ts +0 -71
- package/test/end-to-end/GeoIpLayer0.test.ts +0 -55
- package/test/end-to-end/Layer0-Layer1.test.ts +0 -93
- package/test/end-to-end/Layer0.test.ts +0 -76
- package/test/end-to-end/Layer0MixedConnectionTypes.test.ts +0 -110
- package/test/end-to-end/Layer0Webrtc-Layer1.test.ts +0 -137
- package/test/end-to-end/Layer0Webrtc.test.ts +0 -85
- package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +0 -82
- package/test/end-to-end/Layer1-Scale-Webrtc.test.ts +0 -76
- package/test/end-to-end/RecoveryFromFailedAutoCertification.test.ts +0 -52
- package/test/end-to-end/WebsocketConnectionRequest.test.ts +0 -69
- package/test/end-to-end/memory-leak.test.ts +0 -80
- package/test/integration/ConnectionLocking.test.ts +0 -192
- package/test/integration/ConnectionManager.test.ts +0 -528
- package/test/integration/ConnectivityChecking.test.ts +0 -53
- package/test/integration/DhtJoinPeerDiscovery.test.ts +0 -49
- package/test/integration/DhtNode.test.ts +0 -66
- package/test/integration/DhtNodeExternalAPI.test.ts +0 -48
- package/test/integration/DhtNodeRpcRemote.test.ts +0 -66
- package/test/integration/DhtRpc.test.ts +0 -121
- package/test/integration/Find.test.ts +0 -45
- package/test/integration/GeoIpConnectivityChecking.test.ts +0 -72
- package/test/integration/Layer1-scale.test.ts +0 -189
- package/test/integration/Mock-Layer1-Layer0.test.ts +0 -85
- package/test/integration/MultipleEntryPointJoining.test.ts +0 -105
- package/test/integration/ReplicateData.test.ts +0 -104
- package/test/integration/RouteMessage.test.ts +0 -230
- package/test/integration/RouterRpcRemote.test.ts +0 -77
- package/test/integration/SimultaneousConnections.test.ts +0 -316
- package/test/integration/Store.test.ts +0 -85
- package/test/integration/StoreAndDelete.test.ts +0 -77
- package/test/integration/StoreOnDhtWithThreeNodes.test.ts +0 -59
- package/test/integration/StoreOnDhtWithTwoNodes.test.ts +0 -51
- package/test/integration/StoreRpcRemote.test.ts +0 -54
- package/test/integration/WebrtcConnectionManagement.test.ts +0 -191
- package/test/integration/WebrtcConnectorRpc.test.ts +0 -125
- package/test/integration/Websocket.test.ts +0 -65
- package/test/integration/WebsocketClientConnectorRpc.test.ts +0 -69
- package/test/integration/WebsocketConnectionManagement.test.ts +0 -191
- package/test/integration/rpc-connections-over-webrtc.test.ts +0 -123
- package/test/kademlia-simulation/data/nodeids.json +0 -13002
- package/test/kademlia-simulation/data/orderedneighbors.json +0 -1001
- package/test/types/global.d.ts +0 -1
- package/test/unit/AddressTools.test.ts +0 -44
- package/test/unit/AutoCertifierClientFacade.test.ts +0 -58
- package/test/unit/ConnectionManager.test.ts +0 -65
- package/test/unit/ConnectivityHelpers.test.ts +0 -61
- package/test/unit/DiscoverySession.test.ts +0 -87
- package/test/unit/DuplicateDetector.test.ts +0 -31
- package/test/unit/Handshaker.test.ts +0 -169
- package/test/unit/ListeningRpcCommunicator.test.ts +0 -52
- package/test/unit/LocalDataStore.test.ts +0 -108
- package/test/unit/ManagedConnection.test.ts +0 -58
- package/test/unit/PeerManager.test.ts +0 -93
- package/test/unit/PendingConnection.test.ts +0 -57
- package/test/unit/ProtobufMessage.test.ts +0 -21
- package/test/unit/RandomContactList.test.ts +0 -58
- package/test/unit/RecursiveOperationManager.test.ts +0 -161
- package/test/unit/RecursiveOperationSession.test.ts +0 -68
- package/test/unit/Router.test.ts +0 -137
- package/test/unit/RoutingSession.test.ts +0 -86
- package/test/unit/SortedContactList.test.ts +0 -115
- package/test/unit/StoreManager.test.ts +0 -146
- package/test/unit/StoreRpcLocal.test.ts +0 -167
- package/test/unit/WebrtcConnection.test.ts +0 -29
- package/test/unit/WebrtcConnector.test.ts +0 -56
- package/test/unit/WebsocketClientConnector.test.ts +0 -101
- package/test/unit/WebsocketServer.test.ts +0 -66
- package/test/unit/WebsocketServerConnector.test.ts +0 -102
- package/test/unit/connectivityRequestHandler.test.ts +0 -104
- package/test/unit/createPeerDescriptor.test.ts +0 -69
- package/test/unit/customMatchers.test.ts +0 -34
- package/test/unit/getClosestNodes.test.ts +0 -30
- package/test/unit/version.test.ts +0 -18
- package/test/unit/webrtcReplaceInternalIpWithExternalIp.test.ts +0 -18
- package/test/utils/FakeConnectorFacade.ts +0 -41
- package/test/utils/FakeRpcCommunicator.ts +0 -23
- package/test/utils/FakeTransport.ts +0 -79
- package/test/utils/customMatchers.ts +0 -71
- package/test/utils/mock/MockConnection.ts +0 -26
- package/test/utils/mock/MockConnectionsView.ts +0 -18
- package/test/utils/mock/MockRouter.ts +0 -62
- package/test/utils/mock/MockRpcCommunicator.ts +0 -7
- package/test/utils/mock/MockTransport.ts +0 -26
- package/test/utils/mock/mockDataEntry.ts +0 -38
- package/test/utils/topology.ts +0 -79
- package/test/utils/utils.ts +0 -268
- package/tsconfig.browser.json +0 -17
- package/tsconfig.jest.json +0 -25
- package/tsconfig.json +0 -3
- package/tsconfig.node.json +0 -24
|
@@ -1,108 +0,0 @@
|
|
|
1
|
-
import { Logger, RunAndRaceEventsReturnType, runAndRaceEvents3 } from '@streamr/utils'
|
|
2
|
-
import { v4 } from 'uuid'
|
|
3
|
-
import * as Err from '../helpers/errors'
|
|
4
|
-
import {
|
|
5
|
-
ConnectivityRequest, ConnectivityResponse,
|
|
6
|
-
Message, PeerDescriptor
|
|
7
|
-
} from '../../generated/packages/dht/protos/DhtRpc'
|
|
8
|
-
import { ConnectionEvents, IConnection } from './IConnection'
|
|
9
|
-
import { WebsocketClientConnection } from './websocket/NodeWebsocketClientConnection'
|
|
10
|
-
import { connectivityMethodToWebsocketUrl } from './websocket/WebsocketClientConnector'
|
|
11
|
-
import { isMaybeSupportedProtocolVersion } from '../helpers/version'
|
|
12
|
-
|
|
13
|
-
const logger = new Logger(module)
|
|
14
|
-
|
|
15
|
-
// TODO use options option or named constant?
|
|
16
|
-
export const connectAsync = async ({ url, allowSelfSignedCertificate, timeoutMs = 1000 }:
|
|
17
|
-
{ url: string, allowSelfSignedCertificate: boolean, timeoutMs?: number }
|
|
18
|
-
): Promise<IConnection> => {
|
|
19
|
-
const socket = new WebsocketClientConnection()
|
|
20
|
-
let result: RunAndRaceEventsReturnType<ConnectionEvents>
|
|
21
|
-
try {
|
|
22
|
-
result = await runAndRaceEvents3<ConnectionEvents>([
|
|
23
|
-
() => { socket.connect(url, allowSelfSignedCertificate) }],
|
|
24
|
-
socket, ['connected', 'error'],
|
|
25
|
-
timeoutMs)
|
|
26
|
-
} catch {
|
|
27
|
-
throw new Err.ConnectionFailed('WebSocket connection timed out')
|
|
28
|
-
}
|
|
29
|
-
if (result.winnerName === 'error') {
|
|
30
|
-
throw new Err.ConnectionFailed('Could not open WebSocket connection')
|
|
31
|
-
}
|
|
32
|
-
return socket
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export const CONNECTIVITY_CHECKER_SERVICE_ID = 'system/connectivity-checker'
|
|
36
|
-
const CONNECTIVITY_CHECKER_TIMEOUT = 5000
|
|
37
|
-
|
|
38
|
-
export const sendConnectivityRequest = async (
|
|
39
|
-
request: ConnectivityRequest,
|
|
40
|
-
entryPoint: PeerDescriptor
|
|
41
|
-
): Promise<ConnectivityResponse> => {
|
|
42
|
-
let outgoingConnection: IConnection
|
|
43
|
-
const wsServerInfo = {
|
|
44
|
-
host: entryPoint.websocket!.host,
|
|
45
|
-
port: entryPoint.websocket!.port,
|
|
46
|
-
tls: entryPoint.websocket!.tls,
|
|
47
|
-
}
|
|
48
|
-
const url = connectivityMethodToWebsocketUrl(wsServerInfo, 'connectivityRequest')
|
|
49
|
-
logger.debug(`Attempting connectivity check with entrypoint ${url}`)
|
|
50
|
-
try {
|
|
51
|
-
outgoingConnection = await connectAsync({
|
|
52
|
-
url,
|
|
53
|
-
allowSelfSignedCertificate: request.allowSelfSignedCertificate
|
|
54
|
-
})
|
|
55
|
-
} catch (e) {
|
|
56
|
-
throw new Err.ConnectionFailed(`Failed to connect to entrypoint for connectivity check: ${url}`, e)
|
|
57
|
-
}
|
|
58
|
-
// send connectivity request
|
|
59
|
-
const msg: Message = {
|
|
60
|
-
serviceId: CONNECTIVITY_CHECKER_SERVICE_ID,
|
|
61
|
-
messageId: v4(),
|
|
62
|
-
body: {
|
|
63
|
-
oneofKind: 'connectivityRequest',
|
|
64
|
-
connectivityRequest: request
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
const responseAwaiter = () => {
|
|
68
|
-
return new Promise((resolve: (res: ConnectivityResponse) => void, reject) => {
|
|
69
|
-
const timeoutId = setTimeout(() => {
|
|
70
|
-
// TODO should we have some handling for this floating promise?
|
|
71
|
-
outgoingConnection.close(false)
|
|
72
|
-
reject(new Err.ConnectivityResponseTimeout('timeout'))
|
|
73
|
-
}, CONNECTIVITY_CHECKER_TIMEOUT)
|
|
74
|
-
const listener = (bytes: Uint8Array) => {
|
|
75
|
-
// TODO should we have some handling for this floating promise?
|
|
76
|
-
outgoingConnection.close(false)
|
|
77
|
-
try {
|
|
78
|
-
const message: Message = Message.fromBinary(bytes)
|
|
79
|
-
if (message.body.oneofKind === 'connectivityResponse') {
|
|
80
|
-
logger.debug('ConnectivityResponse received: ' + JSON.stringify(Message.toJson(message)))
|
|
81
|
-
const connectivityResponseMessage = message.body.connectivityResponse
|
|
82
|
-
const remoteProtocolVersion = connectivityResponseMessage.protocolVersion
|
|
83
|
-
outgoingConnection!.off('data', listener)
|
|
84
|
-
clearTimeout(timeoutId)
|
|
85
|
-
if (isMaybeSupportedProtocolVersion(remoteProtocolVersion)) {
|
|
86
|
-
resolve(connectivityResponseMessage)
|
|
87
|
-
} else {
|
|
88
|
-
// eslint-disable-next-line @typescript-eslint/prefer-promise-reject-errors
|
|
89
|
-
reject(`Unsupported version: ${remoteProtocolVersion}`)
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
} catch (err) {
|
|
93
|
-
logger.trace('Could not parse message', { err })
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
outgoingConnection!.on('data', listener)
|
|
97
|
-
})
|
|
98
|
-
}
|
|
99
|
-
try {
|
|
100
|
-
const retPromise = responseAwaiter()
|
|
101
|
-
outgoingConnection.send(Message.toBinary(msg))
|
|
102
|
-
logger.trace('ConnectivityRequest sent: ' + JSON.stringify(Message.toJson(msg)))
|
|
103
|
-
return await retPromise
|
|
104
|
-
} catch (e) {
|
|
105
|
-
logger.error('error getting connectivityresponse')
|
|
106
|
-
throw e
|
|
107
|
-
}
|
|
108
|
-
}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import { ipv4ToNumber, Logger } from '@streamr/utils'
|
|
2
|
-
import { v4 } from 'uuid'
|
|
3
|
-
import {
|
|
4
|
-
ConnectivityRequest,
|
|
5
|
-
ConnectivityResponse,
|
|
6
|
-
Message
|
|
7
|
-
} from '../../generated/packages/dht/protos/DhtRpc'
|
|
8
|
-
import { NatType } from './ConnectionManager'
|
|
9
|
-
import { CONNECTIVITY_CHECKER_SERVICE_ID, connectAsync } from './connectivityChecker'
|
|
10
|
-
import { IConnection } from './IConnection'
|
|
11
|
-
import { WebsocketServerConnection } from './websocket/WebsocketServerConnection'
|
|
12
|
-
import { connectivityMethodToWebsocketUrl } from './websocket/WebsocketClientConnector'
|
|
13
|
-
import { LOCAL_PROTOCOL_VERSION } from '../helpers/version'
|
|
14
|
-
import { GeoIpLocator } from '@streamr/geoip-location'
|
|
15
|
-
|
|
16
|
-
export const DISABLE_CONNECTIVITY_PROBE = 0
|
|
17
|
-
|
|
18
|
-
const logger = new Logger(module)
|
|
19
|
-
|
|
20
|
-
export const attachConnectivityRequestHandler = (connectionToListenTo: WebsocketServerConnection, geoIpLocator?: GeoIpLocator): void => {
|
|
21
|
-
connectionToListenTo.on('data', async (data: Uint8Array) => {
|
|
22
|
-
logger.trace('server received data')
|
|
23
|
-
try {
|
|
24
|
-
const message = Message.fromBinary(data)
|
|
25
|
-
if (message.body.oneofKind === 'connectivityRequest') {
|
|
26
|
-
logger.trace('ConnectivityRequest received: ' + JSON.stringify(Message.toJson(message)))
|
|
27
|
-
try {
|
|
28
|
-
await handleIncomingConnectivityRequest(connectionToListenTo,
|
|
29
|
-
message.body.connectivityRequest, geoIpLocator)
|
|
30
|
-
logger.trace('handleIncomingConnectivityRequest ok')
|
|
31
|
-
} catch (err1) {
|
|
32
|
-
logger.error('handleIncomingConnectivityRequest', { err: err1 })
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
} catch (err2) {
|
|
36
|
-
logger.trace('Could not parse message', { err: err2 })
|
|
37
|
-
}
|
|
38
|
-
})
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const handleIncomingConnectivityRequest = async (
|
|
42
|
-
connection: WebsocketServerConnection,
|
|
43
|
-
connectivityRequest: ConnectivityRequest,
|
|
44
|
-
geoIpLocator?: GeoIpLocator
|
|
45
|
-
): Promise<void> => {
|
|
46
|
-
const host = connectivityRequest.host ?? connection.getRemoteIpAddress()
|
|
47
|
-
const ipAddress = connection.getRemoteIpAddress()
|
|
48
|
-
let connectivityResponse: ConnectivityResponse
|
|
49
|
-
if (connectivityRequest.port !== DISABLE_CONNECTIVITY_PROBE) {
|
|
50
|
-
connectivityResponse = await connectivityProbe(connectivityRequest, ipAddress, host)
|
|
51
|
-
} else {
|
|
52
|
-
logger.trace('ConnectivityRequest port is 0, replying without connectivityProbe')
|
|
53
|
-
connectivityResponse = {
|
|
54
|
-
host,
|
|
55
|
-
natType: NatType.UNKNOWN,
|
|
56
|
-
ipAddress: ipv4ToNumber(ipAddress),
|
|
57
|
-
protocolVersion: LOCAL_PROTOCOL_VERSION
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
if (geoIpLocator !== undefined) {
|
|
61
|
-
const location = geoIpLocator.lookup(ipAddress)
|
|
62
|
-
if (location !== undefined) {
|
|
63
|
-
connectivityResponse.latitude = location.latitude
|
|
64
|
-
connectivityResponse.longitude = location.longitude
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
const msg: Message = {
|
|
68
|
-
serviceId: CONNECTIVITY_CHECKER_SERVICE_ID,
|
|
69
|
-
messageId: v4(),
|
|
70
|
-
body: {
|
|
71
|
-
oneofKind: 'connectivityResponse',
|
|
72
|
-
connectivityResponse
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
connection.send(Message.toBinary(msg))
|
|
76
|
-
logger.trace('ConnectivityResponse sent: ' + JSON.stringify(Message.toJson(msg)))
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const connectivityProbe = async (connectivityRequest: ConnectivityRequest, ipAddress: string, host: string): Promise<ConnectivityResponse> => {
|
|
80
|
-
let outgoingConnection: IConnection | undefined
|
|
81
|
-
let connectivityResponseMessage: ConnectivityResponse
|
|
82
|
-
try {
|
|
83
|
-
const wsServerInfo = {
|
|
84
|
-
host,
|
|
85
|
-
port: connectivityRequest.port,
|
|
86
|
-
tls: connectivityRequest.tls
|
|
87
|
-
}
|
|
88
|
-
const url = connectivityMethodToWebsocketUrl(wsServerInfo, 'connectivityProbe')
|
|
89
|
-
logger.trace(`Attempting Connectivity Check to ${url}`)
|
|
90
|
-
outgoingConnection = await connectAsync({
|
|
91
|
-
url,
|
|
92
|
-
allowSelfSignedCertificate: connectivityRequest.allowSelfSignedCertificate
|
|
93
|
-
})
|
|
94
|
-
logger.trace('Connectivity test produced positive result, communicating reply to the requester ' + host + ':' + connectivityRequest.port)
|
|
95
|
-
connectivityResponseMessage = {
|
|
96
|
-
host,
|
|
97
|
-
natType: NatType.OPEN_INTERNET,
|
|
98
|
-
websocket: { host, port: connectivityRequest.port, tls: connectivityRequest.tls },
|
|
99
|
-
ipAddress: ipv4ToNumber(ipAddress),
|
|
100
|
-
protocolVersion: LOCAL_PROTOCOL_VERSION
|
|
101
|
-
}
|
|
102
|
-
} catch (err) {
|
|
103
|
-
logger.debug('error', { err })
|
|
104
|
-
connectivityResponseMessage = {
|
|
105
|
-
host,
|
|
106
|
-
natType: NatType.UNKNOWN,
|
|
107
|
-
ipAddress: ipv4ToNumber(ipAddress),
|
|
108
|
-
protocolVersion: LOCAL_PROTOCOL_VERSION
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
if (outgoingConnection) {
|
|
112
|
-
// TODO should we have some handling for this floating promise?
|
|
113
|
-
outgoingConnection.close(false)
|
|
114
|
-
}
|
|
115
|
-
return connectivityResponseMessage
|
|
116
|
-
}
|
|
@@ -1,369 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/parameter-properties */
|
|
2
|
-
import { PeerDescriptor } from '../../../generated/packages/dht/protos/DhtRpc'
|
|
3
|
-
import { SimulatorConnector } from './SimulatorConnector'
|
|
4
|
-
import { SimulatorConnection } from './SimulatorConnection'
|
|
5
|
-
import { ConnectionID } from '../IConnection'
|
|
6
|
-
import { Logger } from '@streamr/utils'
|
|
7
|
-
import { getRegionDelayMatrix } from './pings'
|
|
8
|
-
import Heap from 'heap'
|
|
9
|
-
import { debugVars } from '../../helpers/debugHelpers'
|
|
10
|
-
import { DhtAddress, toNodeId } from '../../identifiers'
|
|
11
|
-
|
|
12
|
-
const logger = new Logger(module)
|
|
13
|
-
|
|
14
|
-
export enum LatencyType { NONE = 'NONE', RANDOM = 'RANDOM', REAL = 'REAL', FIXED = 'FIXED' }
|
|
15
|
-
|
|
16
|
-
// One-way 'pipe' of messages
|
|
17
|
-
|
|
18
|
-
class Association {
|
|
19
|
-
public sourceConnection: SimulatorConnection
|
|
20
|
-
public destinationConnection?: SimulatorConnection
|
|
21
|
-
private lastOperationAt: number = 0
|
|
22
|
-
private closing = false
|
|
23
|
-
|
|
24
|
-
constructor(sourceConnection: SimulatorConnection,
|
|
25
|
-
destinationConnection?: SimulatorConnection,
|
|
26
|
-
public connectedCallback?: (error?: string) => void
|
|
27
|
-
) {
|
|
28
|
-
this.sourceConnection = sourceConnection
|
|
29
|
-
this.destinationConnection = destinationConnection
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
public setDestinationConnection(connection: SimulatorConnection) {
|
|
33
|
-
this.destinationConnection = connection
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
public getLastOperationAt(): number {
|
|
37
|
-
return this.lastOperationAt
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
public setLastOperationAt(executionTime: number): void {
|
|
41
|
-
this.lastOperationAt = executionTime
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
public setClosing(): void {
|
|
45
|
-
this.closing = true
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
public isClosing(): boolean {
|
|
49
|
-
return this.closing
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
class SimulatorOperation {
|
|
54
|
-
private static objectCounter = 0
|
|
55
|
-
public objectId = 0
|
|
56
|
-
|
|
57
|
-
constructor(
|
|
58
|
-
public executionTime: number,
|
|
59
|
-
public association: Association
|
|
60
|
-
) {
|
|
61
|
-
this.objectId = SimulatorOperation.objectCounter
|
|
62
|
-
SimulatorOperation.objectCounter++
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
class ConnectOperation extends SimulatorOperation {
|
|
67
|
-
constructor(
|
|
68
|
-
executionTime: number,
|
|
69
|
-
association: Association,
|
|
70
|
-
public sourceConnection: SimulatorConnection,
|
|
71
|
-
public targetDescriptor: PeerDescriptor) {
|
|
72
|
-
|
|
73
|
-
super(executionTime, association)
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
class SendOperation extends SimulatorOperation {
|
|
78
|
-
constructor(
|
|
79
|
-
executionTime: number,
|
|
80
|
-
association: Association,
|
|
81
|
-
public data: Uint8Array
|
|
82
|
-
) {
|
|
83
|
-
super(executionTime, association)
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
class CloseOperation extends SimulatorOperation {
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export class Simulator {
|
|
91
|
-
private stopped = false
|
|
92
|
-
private connectors: Map<DhtAddress, SimulatorConnector> = new Map()
|
|
93
|
-
private latencyTable?: number[][]
|
|
94
|
-
private associations: Map<ConnectionID, Association> = new Map()
|
|
95
|
-
|
|
96
|
-
private latencyType: LatencyType
|
|
97
|
-
private fixedLatency?: number
|
|
98
|
-
|
|
99
|
-
private loopCounter = 0
|
|
100
|
-
private MAX_LOOPS = 1000
|
|
101
|
-
|
|
102
|
-
private operationQueue: Heap<SimulatorOperation> = new Heap<SimulatorOperation>((a: SimulatorOperation, b: SimulatorOperation) => {
|
|
103
|
-
if ((a.executionTime - b.executionTime) === 0) {
|
|
104
|
-
return (a.objectId - b.objectId)
|
|
105
|
-
} else {
|
|
106
|
-
return (a.executionTime - b.executionTime)
|
|
107
|
-
}
|
|
108
|
-
})
|
|
109
|
-
|
|
110
|
-
private simulatorTimeout?: NodeJS.Timeout
|
|
111
|
-
|
|
112
|
-
constructor(latencyType: LatencyType = LatencyType.NONE, fixedLatency?: number) {
|
|
113
|
-
this.latencyType = latencyType
|
|
114
|
-
this.fixedLatency = fixedLatency
|
|
115
|
-
|
|
116
|
-
if (this.latencyType === LatencyType.REAL) {
|
|
117
|
-
this.latencyTable = getRegionDelayMatrix()
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
if ((this.latencyType === LatencyType.FIXED) && (this.fixedLatency === undefined)) {
|
|
121
|
-
throw new Error('LatencyType.FIXED requires the desired latency to be given as second parameter')
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
this.generateExecutionTime = this.generateExecutionTime.bind(this)
|
|
125
|
-
this.getLatency = this.getLatency.bind(this)
|
|
126
|
-
this.executeCloseOperation = this.executeCloseOperation.bind(this)
|
|
127
|
-
this.executeConnectOperation = this.executeConnectOperation.bind(this)
|
|
128
|
-
this.executeSendOperation = this.executeSendOperation.bind(this)
|
|
129
|
-
this.executeQueuedOperations = this.executeQueuedOperations.bind(this)
|
|
130
|
-
this.accept = this.accept.bind(this)
|
|
131
|
-
this.send = this.send.bind(this)
|
|
132
|
-
this.close = this.close.bind(this)
|
|
133
|
-
this.scheduleNextTimeout = this.scheduleNextTimeout.bind(this)
|
|
134
|
-
this.scheduleOperation = this.scheduleOperation.bind(this)
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
private generateExecutionTime(association: Association, sourceRegion: number | undefined, targetRegion: number | undefined): number {
|
|
138
|
-
let executionTime = Date.now() + this.getLatency(sourceRegion, targetRegion)
|
|
139
|
-
if (association.getLastOperationAt() > executionTime) {
|
|
140
|
-
executionTime = association.getLastOperationAt()
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
return executionTime
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
private getLatency(sourceRegion: number | undefined, targetRegion: number | undefined): number {
|
|
147
|
-
let latency: number = 0
|
|
148
|
-
|
|
149
|
-
if (this.latencyType === LatencyType.FIXED) {
|
|
150
|
-
latency = this.fixedLatency!
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (this.latencyType === LatencyType.REAL) {
|
|
154
|
-
|
|
155
|
-
if (sourceRegion === undefined || targetRegion === undefined || sourceRegion > 15 || targetRegion > 15) {
|
|
156
|
-
logger.error('invalid region index given to Simulator')
|
|
157
|
-
throw new Error('invalid region index given to Simulator')
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
latency = this.latencyTable![sourceRegion][targetRegion]
|
|
161
|
-
}
|
|
162
|
-
if (this.latencyType === LatencyType.RANDOM) {
|
|
163
|
-
latency = Math.random() * (250 - 5) + 5
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
return latency
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
public accept(sourceConnection: SimulatorConnection, targetConnection: SimulatorConnection): void {
|
|
170
|
-
|
|
171
|
-
const sourceAssociation = this.associations.get(sourceConnection.connectionId)
|
|
172
|
-
|
|
173
|
-
if (!sourceAssociation) {
|
|
174
|
-
logger.error('source association not found in accept()')
|
|
175
|
-
return
|
|
176
|
-
}
|
|
177
|
-
sourceAssociation.setDestinationConnection(targetConnection)
|
|
178
|
-
|
|
179
|
-
const targetAssociation = new Association(targetConnection, sourceConnection)
|
|
180
|
-
this.associations.set(targetConnection.connectionId, targetAssociation)
|
|
181
|
-
|
|
182
|
-
sourceAssociation.connectedCallback!()
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
public addConnector(connector: SimulatorConnector): void {
|
|
186
|
-
this.connectors.set(toNodeId(connector.getPeerDescriptor()), connector)
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
private executeConnectOperation(operation: ConnectOperation): void {
|
|
190
|
-
const target = this.connectors.get(toNodeId(operation.targetDescriptor))
|
|
191
|
-
|
|
192
|
-
if (!target) {
|
|
193
|
-
logger.error('Target connector not found when executing connect operation')
|
|
194
|
-
operation.association.connectedCallback!('Target connector not found')
|
|
195
|
-
return
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
target.handleIncomingConnection(operation.sourceConnection)
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
private executeCloseOperation(operation: CloseOperation): void {
|
|
202
|
-
|
|
203
|
-
if (this.stopped) {
|
|
204
|
-
return
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
const target = operation.association.destinationConnection
|
|
208
|
-
|
|
209
|
-
let counterAssociation: Association | undefined
|
|
210
|
-
|
|
211
|
-
if (target) {
|
|
212
|
-
counterAssociation = this.associations.get(target.connectionId)
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
if (!target || !counterAssociation) {
|
|
216
|
-
this.associations.delete(operation.association.sourceConnection.connectionId)
|
|
217
|
-
|
|
218
|
-
} else if (!counterAssociation.isClosing()) {
|
|
219
|
-
target.handleIncomingDisconnection()
|
|
220
|
-
this.close(target)
|
|
221
|
-
} else {
|
|
222
|
-
// this is the 'ack' of the CloseOperation to the original closer
|
|
223
|
-
this.associations.delete(target.connectionId)
|
|
224
|
-
this.associations.delete(operation.association.sourceConnection.connectionId)
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
private executeSendOperation(operation: SendOperation): void {
|
|
229
|
-
|
|
230
|
-
if (this.stopped) {
|
|
231
|
-
return
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
const target = operation.association.destinationConnection
|
|
235
|
-
target!.handleIncomingData(operation.data)
|
|
236
|
-
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
private executeQueuedOperations(): void {
|
|
240
|
-
const currentTime = Date.now()
|
|
241
|
-
while (this.operationQueue.size() > 0
|
|
242
|
-
&& this.operationQueue.peek()!.executionTime <= currentTime) {
|
|
243
|
-
const operation = this.operationQueue.pop()
|
|
244
|
-
|
|
245
|
-
if (operation instanceof ConnectOperation) {
|
|
246
|
-
this.executeConnectOperation(operation)
|
|
247
|
-
} else if (operation instanceof CloseOperation) {
|
|
248
|
-
this.executeCloseOperation(operation)
|
|
249
|
-
} else if (operation instanceof SendOperation) {
|
|
250
|
-
this.executeSendOperation(operation)
|
|
251
|
-
} else {
|
|
252
|
-
logger.error('Unknown SimulatorOperation')
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
this.loopCounter++
|
|
256
|
-
if (this.loopCounter >= this.MAX_LOOPS) {
|
|
257
|
-
this.loopCounter = 0
|
|
258
|
-
setTimeout(() => this.executeQueuedOperations(), 0)
|
|
259
|
-
return
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
this.scheduleNextTimeout()
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
private scheduleNextTimeout(): void {
|
|
267
|
-
if (this.simulatorTimeout) {
|
|
268
|
-
clearTimeout(this.simulatorTimeout)
|
|
269
|
-
this.simulatorTimeout = undefined
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
const currentTime = Date.now()
|
|
273
|
-
|
|
274
|
-
const firstOperation = this.operationQueue.peek()
|
|
275
|
-
|
|
276
|
-
if (!firstOperation) {
|
|
277
|
-
return
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
const firstOperationTime = firstOperation.executionTime
|
|
281
|
-
const timeDifference = firstOperationTime - currentTime
|
|
282
|
-
|
|
283
|
-
this.simulatorTimeout = setTimeout(this.executeQueuedOperations, timeDifference)
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
private scheduleOperation(operation: SimulatorOperation) {
|
|
287
|
-
this.operationQueue.push(operation)
|
|
288
|
-
this.scheduleNextTimeout()
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
public connect(sourceConnection: SimulatorConnection, targetDescriptor: PeerDescriptor, connectedCallback: (error?: string) => void): void {
|
|
292
|
-
|
|
293
|
-
if (this.stopped) {
|
|
294
|
-
logger.error('connect() called on a stopped simulator ' + (new Error().stack))
|
|
295
|
-
return
|
|
296
|
-
}
|
|
297
|
-
debugVars.simulatorHeapSize = this.operationQueue.size()
|
|
298
|
-
|
|
299
|
-
const association = new Association(sourceConnection, undefined, connectedCallback)
|
|
300
|
-
this.associations.set(sourceConnection.connectionId, association)
|
|
301
|
-
|
|
302
|
-
const executionTime = this.generateExecutionTime(association, sourceConnection.localPeerDescriptor.region, targetDescriptor.region)
|
|
303
|
-
association.setLastOperationAt(executionTime)
|
|
304
|
-
|
|
305
|
-
const operation = new ConnectOperation(executionTime, association,
|
|
306
|
-
sourceConnection, targetDescriptor)
|
|
307
|
-
|
|
308
|
-
this.scheduleOperation(operation)
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
public close(sourceConnection: SimulatorConnection): void {
|
|
312
|
-
|
|
313
|
-
if (this.stopped) {
|
|
314
|
-
return
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
const association = this.associations.get(sourceConnection.connectionId)
|
|
318
|
-
if (!association) {
|
|
319
|
-
return
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
association.setClosing()
|
|
323
|
-
|
|
324
|
-
const executionTime = this.generateExecutionTime(association,
|
|
325
|
-
sourceConnection.localPeerDescriptor.region,
|
|
326
|
-
sourceConnection.getPeerDescriptor()?.region)
|
|
327
|
-
association.setLastOperationAt(executionTime)
|
|
328
|
-
|
|
329
|
-
const operation = new CloseOperation(executionTime, association)
|
|
330
|
-
|
|
331
|
-
this.scheduleOperation(operation)
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
public send(sourceConnection: SimulatorConnection, data: Uint8Array): void {
|
|
335
|
-
|
|
336
|
-
if (this.stopped) {
|
|
337
|
-
return
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
const association = this.associations.get(sourceConnection.connectionId)
|
|
341
|
-
if (!association) {
|
|
342
|
-
return
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
if (association.isClosing()) {
|
|
346
|
-
logger.trace('Tried to call send() on a closing association')
|
|
347
|
-
return
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
const executionTime = this.generateExecutionTime(association,
|
|
351
|
-
sourceConnection.localPeerDescriptor.region,
|
|
352
|
-
association.destinationConnection!.localPeerDescriptor.region)
|
|
353
|
-
|
|
354
|
-
association.setLastOperationAt(executionTime)
|
|
355
|
-
|
|
356
|
-
const operation = new SendOperation(executionTime, association, data)
|
|
357
|
-
|
|
358
|
-
this.scheduleOperation(operation)
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
public stop(): void {
|
|
362
|
-
this.stopped = true
|
|
363
|
-
logger.info(this.associations.size + ' associations in the beginning of stop()')
|
|
364
|
-
|
|
365
|
-
if (this.simulatorTimeout) {
|
|
366
|
-
clearTimeout(this.simulatorTimeout)
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
}
|