@streamr/dht 100.2.3 → 100.2.4
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/README.md +1 -1
- package/dist/package.json +8 -9
- package/dist/src/connection/ConnectionManager.d.ts +2 -1
- package/dist/src/connection/ConnectionManager.js +2 -10
- package/dist/src/connection/ConnectionManager.js.map +1 -1
- package/dist/src/connection/ConnectionsView.d.ts +7 -0
- package/dist/src/connection/ConnectionsView.js +3 -0
- package/dist/src/connection/ConnectionsView.js.map +1 -0
- package/dist/src/connection/ConnectorFacade.d.ts +2 -1
- package/dist/src/connection/ConnectorFacade.js +5 -4
- package/dist/src/connection/ConnectorFacade.js.map +1 -1
- package/dist/src/connection/connectivityRequestHandler.d.ts +2 -1
- package/dist/src/connection/connectivityRequestHandler.js +12 -5
- package/dist/src/connection/connectivityRequestHandler.js.map +1 -1
- package/dist/src/connection/{ManagedWebrtcConnection.d.ts → webrtc/ManagedWebrtcConnection.d.ts} +3 -3
- package/dist/src/connection/{ManagedWebrtcConnection.js → webrtc/ManagedWebrtcConnection.js} +2 -2
- package/dist/src/connection/webrtc/ManagedWebrtcConnection.js.map +1 -0
- package/dist/src/connection/webrtc/NodeWebrtcConnection.js +3 -26
- package/dist/src/connection/webrtc/NodeWebrtcConnection.js.map +1 -1
- package/dist/src/connection/webrtc/WebrtcConnector.js +1 -1
- package/dist/src/connection/webrtc/WebrtcConnector.js.map +1 -1
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.d.ts +1 -1
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js +1 -1
- package/dist/src/connection/webrtc/WebrtcConnectorRpcLocal.js.map +1 -1
- package/dist/src/connection/websocket/WebsocketConnector.d.ts +2 -0
- package/dist/src/connection/websocket/WebsocketConnector.js +21 -13
- package/dist/src/connection/websocket/WebsocketConnector.js.map +1 -1
- package/dist/src/connection/websocket/WebsocketServerConnection.d.ts +2 -1
- package/dist/src/connection/websocket/WebsocketServerConnection.js +4 -0
- package/dist/src/connection/websocket/WebsocketServerConnection.js.map +1 -1
- package/dist/src/dht/DhtNode.d.ts +14 -11
- package/dist/src/dht/DhtNode.js +74 -61
- package/dist/src/dht/DhtNode.js.map +1 -1
- package/dist/src/dht/DhtNodeRpcLocal.d.ts +3 -3
- package/dist/src/dht/DhtNodeRpcLocal.js +5 -2
- package/dist/src/dht/DhtNodeRpcLocal.js.map +1 -1
- package/dist/src/dht/PeerManager.d.ts +14 -14
- package/dist/src/dht/PeerManager.js +51 -42
- package/dist/src/dht/PeerManager.js.map +1 -1
- package/dist/src/dht/contact/ContactList.d.ts +1 -2
- package/dist/src/dht/contact/ContactList.js +1 -3
- package/dist/src/dht/contact/ContactList.js.map +1 -1
- package/dist/src/dht/contact/RandomContactList.d.ts +1 -1
- package/dist/src/dht/contact/RandomContactList.js +7 -4
- package/dist/src/dht/contact/RandomContactList.js.map +1 -1
- package/dist/src/dht/contact/getClosestNodes.d.ts +6 -0
- package/dist/src/dht/contact/{getClosestContacts.js → getClosestNodes.js} +7 -6
- package/dist/src/dht/contact/getClosestNodes.js.map +1 -0
- package/dist/src/dht/discovery/DiscoverySession.d.ts +4 -0
- package/dist/src/dht/discovery/DiscoverySession.js +27 -21
- package/dist/src/dht/discovery/DiscoverySession.js.map +1 -1
- package/dist/src/dht/discovery/PeerDiscovery.d.ts +8 -5
- package/dist/src/dht/discovery/PeerDiscovery.js +34 -24
- package/dist/src/dht/discovery/PeerDiscovery.js.map +1 -1
- package/dist/src/dht/discovery/RingDiscoverySession.d.ts +4 -4
- package/dist/src/dht/discovery/RingDiscoverySession.js +10 -19
- package/dist/src/dht/discovery/RingDiscoverySession.js.map +1 -1
- package/dist/src/dht/recursive-operation/RecursiveOperationManager.d.ts +2 -0
- package/dist/src/dht/recursive-operation/RecursiveOperationManager.js +3 -3
- package/dist/src/dht/recursive-operation/RecursiveOperationManager.js.map +1 -1
- package/dist/src/dht/store/StoreManager.d.ts +5 -6
- package/dist/src/dht/store/StoreManager.js +21 -76
- package/dist/src/dht/store/StoreManager.js.map +1 -1
- package/dist/src/dht/store/StoreRpcLocal.d.ts +5 -2
- package/dist/src/dht/store/StoreRpcLocal.js +22 -5
- package/dist/src/dht/store/StoreRpcLocal.js.map +1 -1
- package/dist/src/exports.d.ts +2 -1
- package/dist/src/exports.js.map +1 -1
- package/dist/src/helpers/version.d.ts +1 -1
- package/dist/src/helpers/version.js +1 -1
- package/dist/src/proto/google/protobuf/any.d.ts +8 -5
- package/dist/src/proto/google/protobuf/any.js.map +1 -1
- package/dist/src/proto/google/protobuf/empty.d.ts +0 -1
- package/dist/src/proto/google/protobuf/empty.js.map +1 -1
- package/dist/src/proto/google/protobuf/timestamp.d.ts +10 -1
- package/dist/src/proto/google/protobuf/timestamp.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +8 -0
- package/dist/src/proto/packages/dht/protos/DhtRpc.js +3 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
- package/dist/src/transport/ITransport.d.ts +0 -4
- package/dist/src/transport/ITransport.js.map +1 -1
- package/karma.config.js +2 -2
- package/package.json +8 -9
- package/protos/DhtRpc.proto +2 -0
- package/src/connection/ConnectionManager.ts +4 -10
- package/src/connection/ConnectionsView.ts +8 -0
- package/src/connection/ConnectorFacade.ts +7 -5
- package/src/connection/connectivityRequestHandler.ts +18 -5
- package/src/connection/{ManagedWebrtcConnection.ts → webrtc/ManagedWebrtcConnection.ts} +4 -4
- package/src/connection/webrtc/NodeWebrtcConnection.ts +3 -3
- package/src/connection/webrtc/WebrtcConnector.ts +1 -1
- package/src/connection/webrtc/WebrtcConnectorRpcLocal.ts +1 -1
- package/src/connection/websocket/WebsocketConnector.ts +26 -16
- package/src/connection/websocket/WebsocketServerConnection.ts +6 -1
- package/src/dht/DhtNode.ts +102 -74
- package/src/dht/DhtNodeRpcLocal.ts +12 -5
- package/src/dht/PeerManager.ts +58 -49
- package/src/dht/contact/ContactList.ts +1 -4
- package/src/dht/contact/RandomContactList.ts +7 -5
- package/src/dht/contact/{getClosestContacts.ts → getClosestNodes.ts} +8 -6
- package/src/dht/discovery/DiscoverySession.ts +34 -22
- package/src/dht/discovery/PeerDiscovery.ts +44 -30
- package/src/dht/discovery/RingDiscoverySession.ts +15 -29
- package/src/dht/recursive-operation/RecursiveOperationManager.ts +5 -3
- package/src/dht/store/StoreManager.ts +46 -84
- package/src/dht/store/StoreRpcLocal.ts +32 -9
- package/src/exports.ts +2 -1
- package/src/helpers/version.ts +1 -1
- package/src/proto/google/protobuf/any.ts +8 -5
- package/src/proto/google/protobuf/empty.ts +0 -1
- package/src/proto/google/protobuf/timestamp.ts +10 -1
- package/src/proto/packages/dht/protos/DhtRpc.ts +11 -1
- package/src/transport/ITransport.ts +0 -4
- package/test/benchmark/Find.test.ts +1 -1
- package/test/end-to-end/GeoIpLayer0.test.ts +55 -0
- package/test/end-to-end/Layer0-Layer1.test.ts +4 -4
- package/test/end-to-end/Layer0Webrtc-Layer1.test.ts +11 -5
- package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +7 -1
- package/test/end-to-end/Layer1-Scale-Webrtc.test.ts +11 -2
- package/test/integration/ConnectionLocking.test.ts +1 -1
- package/test/integration/ConnectionManager.test.ts +3 -3
- package/test/integration/ConnectivityChecking.test.ts +2 -2
- package/test/integration/DhtNode.test.ts +5 -20
- package/test/integration/GeoIpConnectivityChecking.test.ts +71 -0
- package/test/integration/Layer1-scale.test.ts +6 -6
- package/test/integration/RouteMessage.test.ts +4 -0
- package/test/integration/ScaleDownDht.test.ts +1 -1
- package/test/integration/SimultaneousConnections.test.ts +2 -2
- package/test/integration/WebrtcConnectionManagement.test.ts +1 -1
- package/test/integration/WebsocketConnectionManagement.test.ts +1 -1
- package/test/integration/rpc-connections-over-webrpc.test.ts +1 -1
- package/test/unit/AutoCertifierClientFacade.test.ts +1 -1
- package/test/unit/DiscoverySession.test.ts +4 -2
- package/test/unit/PeerManager.test.ts +45 -51
- package/test/unit/RandomContactList.test.ts +10 -0
- package/test/unit/RecursiveOperationManager.test.ts +4 -2
- package/test/unit/StoreManager.test.ts +42 -34
- package/test/unit/StoreRpcLocal.test.ts +167 -0
- package/test/unit/WebsocketConnector.test.ts +1 -1
- package/test/unit/connectivityRequestHandler.test.ts +1 -1
- package/test/unit/getClosestNodes.test.ts +30 -0
- package/test/utils/FakeTransport.ts +4 -2
- package/test/utils/mock/MockConnectionsView.ts +18 -0
- package/test/utils/mock/{Transport.ts → MockTransport.ts} +0 -15
- package/test/utils/utils.ts +4 -1
- package/tsconfig.jest.json +2 -1
- package/tsconfig.node.json +2 -1
- package/dist/src/connection/ManagedWebrtcConnection.js.map +0 -1
- package/dist/src/dht/contact/getClosestContacts.d.ts +0 -7
- package/dist/src/dht/contact/getClosestContacts.js.map +0 -1
- package/test/unit/getClosestContacts.test.ts +0 -28
- /package/test/utils/mock/{Router.ts → MockRouter.ts} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@streamr/dht",
|
|
3
|
-
"version": "100.2.
|
|
3
|
+
"version": "100.2.4",
|
|
4
4
|
"description": "Streamr Network DHT",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -29,17 +29,18 @@
|
|
|
29
29
|
"@js-sdsl/ordered-map": "^4.4.2",
|
|
30
30
|
"@protobuf-ts/runtime": "^2.8.2",
|
|
31
31
|
"@protobuf-ts/runtime-rpc": "^2.8.2",
|
|
32
|
-
"@streamr/autocertifier-client": "100.2.
|
|
33
|
-
"@streamr/cdn-location": "100.2.
|
|
34
|
-
"@streamr/
|
|
35
|
-
"@streamr/
|
|
32
|
+
"@streamr/autocertifier-client": "100.2.4",
|
|
33
|
+
"@streamr/cdn-location": "100.2.4",
|
|
34
|
+
"@streamr/geoip-location": "100.2.4",
|
|
35
|
+
"@streamr/proto-rpc": "100.2.4",
|
|
36
|
+
"@streamr/utils": "100.2.4",
|
|
36
37
|
"eventemitter3": "^5.0.0",
|
|
37
38
|
"heap": "^0.2.6",
|
|
38
39
|
"ipaddr.js": "^2.0.1",
|
|
39
40
|
"k-bucket": "^5.1.0",
|
|
40
41
|
"lodash": "^4.17.21",
|
|
41
42
|
"lru-cache": "10.2.0",
|
|
42
|
-
"node-datachannel": "^0.
|
|
43
|
+
"node-datachannel": "^0.8.0",
|
|
43
44
|
"querystring": "0.2.1",
|
|
44
45
|
"uuid": "^9.0.1",
|
|
45
46
|
"websocket": "^1.0.34",
|
|
@@ -47,15 +48,13 @@
|
|
|
47
48
|
},
|
|
48
49
|
"devDependencies": {
|
|
49
50
|
"@streamr/browser-test-runner": "^0.0.1",
|
|
50
|
-
"@streamr/test-utils": "100.2.
|
|
51
|
-
"@types/express": "^4.17.21",
|
|
51
|
+
"@streamr/test-utils": "100.2.4",
|
|
52
52
|
"@types/heap": "^0.2.34",
|
|
53
53
|
"@types/k-bucket": "^5.0.1",
|
|
54
54
|
"@types/lodash": "^4.14.202",
|
|
55
55
|
"@types/uuid": "^9.0.8",
|
|
56
56
|
"@types/websocket": "^1.0.10",
|
|
57
57
|
"@types/ws": "^8.5.10",
|
|
58
|
-
"express": "^4.19.2",
|
|
59
58
|
"jest-leak-detector": "^27.3.1",
|
|
60
59
|
"patch-package": "^8.0.0",
|
|
61
60
|
"ts-essentials": "^9.4.1",
|
package/protos/DhtRpc.proto
CHANGED
|
@@ -24,6 +24,7 @@ import { ServerCallContext } from '@protobuf-ts/runtime-rpc'
|
|
|
24
24
|
import { ConnectionLockRpcLocal } from './ConnectionLockRpcLocal'
|
|
25
25
|
import { DhtAddress, areEqualPeerDescriptors, getNodeIdFromPeerDescriptor } from '../identifiers'
|
|
26
26
|
import { getOfferer } from '../helpers/offering'
|
|
27
|
+
import { ConnectionsView } from './ConnectionsView'
|
|
27
28
|
|
|
28
29
|
export interface ConnectionManagerConfig {
|
|
29
30
|
maxConnections?: number
|
|
@@ -93,7 +94,7 @@ export const getNodeIdOrUnknownFromPeerDescriptor = (peerDescriptor: PeerDescrip
|
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
96
|
|
|
96
|
-
export class ConnectionManager extends EventEmitter<TransportEvents> implements ITransport, ConnectionLocker {
|
|
97
|
+
export class ConnectionManager extends EventEmitter<TransportEvents> implements ITransport, ConnectionsView, ConnectionLocker {
|
|
97
98
|
|
|
98
99
|
private config: ConnectionManagerConfig
|
|
99
100
|
private readonly metricsContext: MetricsContext
|
|
@@ -158,15 +159,8 @@ export class ConnectionManager extends EventEmitter<TransportEvents> implements
|
|
|
158
159
|
maxSize: 100000, // TODO use config option or named constant?
|
|
159
160
|
allowToContainReferenceId: false
|
|
160
161
|
})
|
|
161
|
-
this.connections.forEach((connection
|
|
162
|
-
|
|
163
|
-
// server with a different nodeId can remain in the this.connections map.
|
|
164
|
-
// Seems to only happen if the ConnectionManager acting as client is not running a WS server itself.
|
|
165
|
-
if (connection.getPeerDescriptor() !== undefined && !this.hasConnection(getNodeIdFromPeerDescriptor(connection.getPeerDescriptor()!))) {
|
|
166
|
-
logger.trace(`Attempting to disconnect a hanging connection to ${getNodeIdFromPeerDescriptor(connection.getPeerDescriptor()!)}`)
|
|
167
|
-
connection.close(false).catch(() => {})
|
|
168
|
-
this.connections.delete(key)
|
|
169
|
-
} else if (!this.locks.isLocked(connection.getNodeId()) && Date.now() - connection.getLastUsedTimestamp() > maxIdleTime) {
|
|
162
|
+
this.connections.forEach((connection) => {
|
|
163
|
+
if (!this.locks.isLocked(connection.getNodeId()) && Date.now() - connection.getLastUsedTimestamp() > maxIdleTime) {
|
|
170
164
|
logger.trace('disconnecting in timeout interval: ' + getNodeIdOrUnknownFromPeerDescriptor(connection.getPeerDescriptor()))
|
|
171
165
|
disconnectionCandidates.addContact(connection)
|
|
172
166
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { DhtAddress } from '../identifiers'
|
|
2
|
+
import { PeerDescriptor } from '../proto/packages/dht/protos/DhtRpc'
|
|
3
|
+
|
|
4
|
+
export interface ConnectionsView {
|
|
5
|
+
getConnections: () => PeerDescriptor[]
|
|
6
|
+
getConnectionCount: () => number
|
|
7
|
+
hasConnection: (nodeId: DhtAddress) => boolean
|
|
8
|
+
}
|
|
@@ -44,7 +44,8 @@ export interface DefaultConnectorFacadeConfig {
|
|
|
44
44
|
websocketServerEnableTls?: boolean
|
|
45
45
|
autoCertifierUrl?: string
|
|
46
46
|
autoCertifierConfigFile?: string
|
|
47
|
-
|
|
47
|
+
geoIpDatabaseFolder?: string
|
|
48
|
+
createLocalPeerDescriptor: (connectivityResponse: ConnectivityResponse) => Promise<PeerDescriptor>
|
|
48
49
|
}
|
|
49
50
|
|
|
50
51
|
export class DefaultConnectorFacade implements ConnectorFacade {
|
|
@@ -76,7 +77,8 @@ export class DefaultConnectorFacade implements ConnectorFacade {
|
|
|
76
77
|
autoCertifierUrl: this.config.autoCertifierUrl!,
|
|
77
78
|
autoCertifierConfigFile: this.config.autoCertifierConfigFile!,
|
|
78
79
|
autoCertifierTransport,
|
|
79
|
-
maxMessageSize: this.config.maxMessageSize
|
|
80
|
+
maxMessageSize: this.config.maxMessageSize,
|
|
81
|
+
geoIpDatabaseFolder: this.config.geoIpDatabaseFolder
|
|
80
82
|
}
|
|
81
83
|
this.websocketConnector = new WebsocketConnector(webSocketConnectorConfig)
|
|
82
84
|
logger.trace(`Creating WebRtcConnectorRpcLocal`)
|
|
@@ -98,13 +100,13 @@ export class DefaultConnectorFacade implements ConnectorFacade {
|
|
|
98
100
|
// LocalPeerDescriptor could be stored in one place and passed from there to the connectors
|
|
99
101
|
const temporarilySelfSigned = (!this.config.tlsCertificate && this.config.websocketServerEnableTls === true)
|
|
100
102
|
const connectivityResponse = await this.websocketConnector.checkConnectivity(temporarilySelfSigned)
|
|
101
|
-
const localPeerDescriptor = this.config.createLocalPeerDescriptor(connectivityResponse)
|
|
103
|
+
const localPeerDescriptor = await this.config.createLocalPeerDescriptor(connectivityResponse)
|
|
102
104
|
this.setLocalPeerDescriptor(localPeerDescriptor)
|
|
103
105
|
if (localPeerDescriptor.websocket && !this.config.tlsCertificate && this.config.websocketServerEnableTls) {
|
|
104
106
|
try {
|
|
105
107
|
await this.websocketConnector.autoCertify()
|
|
106
108
|
const connectivityResponse = await this.websocketConnector.checkConnectivity(false)
|
|
107
|
-
const autocertifiedLocalPeerDescriptor = this.config.createLocalPeerDescriptor(connectivityResponse)
|
|
109
|
+
const autocertifiedLocalPeerDescriptor = await this.config.createLocalPeerDescriptor(connectivityResponse)
|
|
108
110
|
if (autocertifiedLocalPeerDescriptor.websocket !== undefined) {
|
|
109
111
|
this.setLocalPeerDescriptor(autocertifiedLocalPeerDescriptor)
|
|
110
112
|
} else {
|
|
@@ -135,7 +137,7 @@ export class DefaultConnectorFacade implements ConnectorFacade {
|
|
|
135
137
|
this.websocketConnector = new WebsocketConnector(webSocketConnectorConfig)
|
|
136
138
|
await this.websocketConnector.start()
|
|
137
139
|
const connectivityResponse = await this.websocketConnector.checkConnectivity(false)
|
|
138
|
-
const localPeerDescriptor = this.config.createLocalPeerDescriptor(connectivityResponse)
|
|
140
|
+
const localPeerDescriptor = await this.config.createLocalPeerDescriptor(connectivityResponse)
|
|
139
141
|
this.setLocalPeerDescriptor(localPeerDescriptor)
|
|
140
142
|
}
|
|
141
143
|
|
|
@@ -11,12 +11,13 @@ import { IConnection } from './IConnection'
|
|
|
11
11
|
import { WebsocketServerConnection } from './websocket/WebsocketServerConnection'
|
|
12
12
|
import { connectivityMethodToWebsocketUrl } from './websocket/WebsocketConnector'
|
|
13
13
|
import { LOCAL_PROTOCOL_VERSION } from '../helpers/version'
|
|
14
|
+
import { GeoIpLocator } from '@streamr/geoip-location'
|
|
14
15
|
|
|
15
16
|
export const DISABLE_CONNECTIVITY_PROBE = 0
|
|
16
17
|
|
|
17
18
|
const logger = new Logger(module)
|
|
18
19
|
|
|
19
|
-
export const attachConnectivityRequestHandler = (connectionToListenTo: WebsocketServerConnection): void => {
|
|
20
|
+
export const attachConnectivityRequestHandler = (connectionToListenTo: WebsocketServerConnection, geoIpLocator?: GeoIpLocator): void => {
|
|
20
21
|
connectionToListenTo.on('data', async (data: Uint8Array) => {
|
|
21
22
|
logger.trace('server received data')
|
|
22
23
|
try {
|
|
@@ -24,7 +25,8 @@ export const attachConnectivityRequestHandler = (connectionToListenTo: Websocket
|
|
|
24
25
|
if (message.body.oneofKind === 'connectivityRequest') {
|
|
25
26
|
logger.trace('ConnectivityRequest received: ' + JSON.stringify(Message.toJson(message)))
|
|
26
27
|
try {
|
|
27
|
-
await handleIncomingConnectivityRequest(connectionToListenTo,
|
|
28
|
+
await handleIncomingConnectivityRequest(connectionToListenTo,
|
|
29
|
+
message.body.connectivityRequest, geoIpLocator)
|
|
28
30
|
logger.trace('handleIncomingConnectivityRequest ok')
|
|
29
31
|
} catch (err1) {
|
|
30
32
|
logger.error('handleIncomingConnectivityRequest', { err: err1 })
|
|
@@ -36,9 +38,13 @@ export const attachConnectivityRequestHandler = (connectionToListenTo: Websocket
|
|
|
36
38
|
})
|
|
37
39
|
}
|
|
38
40
|
|
|
39
|
-
const handleIncomingConnectivityRequest = async (
|
|
40
|
-
|
|
41
|
-
|
|
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()
|
|
42
48
|
let connectivityResponse: ConnectivityResponse
|
|
43
49
|
if (connectivityRequest.port !== DISABLE_CONNECTIVITY_PROBE) {
|
|
44
50
|
connectivityResponse = await connectivityProbe(connectivityRequest, ipAddress, host)
|
|
@@ -51,6 +57,13 @@ const handleIncomingConnectivityRequest = async (connection: WebsocketServerConn
|
|
|
51
57
|
version: LOCAL_PROTOCOL_VERSION
|
|
52
58
|
}
|
|
53
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
|
+
}
|
|
54
67
|
const msg: Message = {
|
|
55
68
|
serviceId: CONNECTIVITY_CHECKER_SERVICE_ID,
|
|
56
69
|
messageId: v4(),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { PeerDescriptor } from '
|
|
2
|
-
import { ConnectionType } from '
|
|
3
|
-
import { ManagedConnection } from '
|
|
4
|
-
import { NodeWebrtcConnection } from './
|
|
1
|
+
import { PeerDescriptor } from '../../proto/packages/dht/protos/DhtRpc'
|
|
2
|
+
import { ConnectionType } from '../IConnection'
|
|
3
|
+
import { ManagedConnection } from '../ManagedConnection'
|
|
4
|
+
import { NodeWebrtcConnection } from './NodeWebrtcConnection'
|
|
5
5
|
|
|
6
6
|
export class ManagedWebrtcConnection extends ManagedConnection {
|
|
7
7
|
|
|
@@ -2,7 +2,7 @@ import { IWebrtcConnection, WebrtcConnectionEvents } from './IWebrtcConnection'
|
|
|
2
2
|
import { ConnectionType, IConnection, ConnectionID, ConnectionEvents } from '../IConnection'
|
|
3
3
|
import { PeerDescriptor } from '../../proto/packages/dht/protos/DhtRpc'
|
|
4
4
|
import EventEmitter from 'eventemitter3'
|
|
5
|
-
import
|
|
5
|
+
import { DataChannel, DescriptionType, PeerConnection, cleanup, initLogger } from 'node-datachannel'
|
|
6
6
|
import { Logger } from '@streamr/utils'
|
|
7
7
|
import { IllegalRtcPeerConnectionState } from '../../helpers/errors'
|
|
8
8
|
import { iceServerAsString } from './iceServerAsString'
|
|
@@ -16,7 +16,7 @@ const logger = new Logger(module)
|
|
|
16
16
|
export const WEBRTC_CLEANUP = new class {
|
|
17
17
|
// eslint-disable-next-line class-methods-use-this
|
|
18
18
|
cleanUp(): void {
|
|
19
|
-
|
|
19
|
+
cleanup()
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -42,7 +42,7 @@ enum RtcPeerConnectionStateEnum {
|
|
|
42
42
|
new = 'new'
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
|
|
45
|
+
initLogger('Fatal')
|
|
46
46
|
|
|
47
47
|
type RtcPeerConnectionState = keyof typeof RtcPeerConnectionStateEnum
|
|
48
48
|
|
|
@@ -9,7 +9,7 @@ import { ListeningRpcCommunicator } from '../../transport/ListeningRpcCommunicat
|
|
|
9
9
|
import { NodeWebrtcConnection } from './NodeWebrtcConnection'
|
|
10
10
|
import { WebrtcConnectorRpcRemote } from './WebrtcConnectorRpcRemote'
|
|
11
11
|
import { WebrtcConnectorRpcClient } from '../../proto/packages/dht/protos/DhtRpc.client'
|
|
12
|
-
import { ManagedWebrtcConnection } from '
|
|
12
|
+
import { ManagedWebrtcConnection } from './ManagedWebrtcConnection'
|
|
13
13
|
import { Logger } from '@streamr/utils'
|
|
14
14
|
import * as Err from '../../helpers/errors'
|
|
15
15
|
import { ManagedConnection } from '../ManagedConnection'
|
|
@@ -14,7 +14,7 @@ import { IWebrtcConnectorRpc } from '../../proto/packages/dht/protos/DhtRpc.serv
|
|
|
14
14
|
import { DhtCallContext } from '../../rpc-protocol/DhtCallContext'
|
|
15
15
|
import { ListeningRpcCommunicator } from '../../transport/ListeningRpcCommunicator'
|
|
16
16
|
import { ManagedConnection } from '../ManagedConnection'
|
|
17
|
-
import { ManagedWebrtcConnection } from '
|
|
17
|
+
import { ManagedWebrtcConnection } from './ManagedWebrtcConnection'
|
|
18
18
|
import { NodeWebrtcConnection } from './NodeWebrtcConnection'
|
|
19
19
|
import { WebrtcConnectorRpcRemote } from './WebrtcConnectorRpcRemote'
|
|
20
20
|
import { DhtAddress, getNodeIdFromPeerDescriptor } from '../../identifiers'
|
|
@@ -30,6 +30,7 @@ import * as Err from '../../helpers/errors'
|
|
|
30
30
|
import { Empty } from '../../proto/google/protobuf/empty'
|
|
31
31
|
import { DhtAddress, areEqualPeerDescriptors, getNodeIdFromPeerDescriptor } from '../../identifiers'
|
|
32
32
|
import { LOCAL_PROTOCOL_VERSION, isMaybeSupportedVersion } from '../../helpers/version'
|
|
33
|
+
import { GeoIpLocator } from '@streamr/geoip-location'
|
|
33
34
|
|
|
34
35
|
const logger = new Logger(module)
|
|
35
36
|
|
|
@@ -53,6 +54,7 @@ export interface WebsocketConnectorConfig {
|
|
|
53
54
|
autoCertifierUrl: string
|
|
54
55
|
autoCertifierConfigFile: string
|
|
55
56
|
serverEnableTls: boolean
|
|
57
|
+
geoIpDatabaseFolder?: string
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
export class WebsocketConnector {
|
|
@@ -60,6 +62,7 @@ export class WebsocketConnector {
|
|
|
60
62
|
private static readonly WEBSOCKET_CONNECTOR_SERVICE_ID = 'system/websocket-connector'
|
|
61
63
|
private readonly rpcCommunicator: ListeningRpcCommunicator
|
|
62
64
|
private readonly websocketServer?: WebsocketServer
|
|
65
|
+
private geoIpLocator?: GeoIpLocator
|
|
63
66
|
private readonly ongoingConnectRequests: Map<DhtAddress, ManagedConnection> = new Map()
|
|
64
67
|
private host?: string
|
|
65
68
|
private autoCertifierClient?: AutoCertifierClientFacade
|
|
@@ -87,17 +90,10 @@ export class WebsocketConnector {
|
|
|
87
90
|
private registerLocalRpcMethods(config: WebsocketConnectorConfig) {
|
|
88
91
|
const rpcLocal = new WebsocketConnectorRpcLocal({
|
|
89
92
|
connect: (targetPeerDescriptor: PeerDescriptor) => this.connect(targetPeerDescriptor),
|
|
90
|
-
hasConnection: (nodeId: DhtAddress): boolean =>
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|| config.hasConnection(nodeId)
|
|
95
|
-
) {
|
|
96
|
-
return true
|
|
97
|
-
} else {
|
|
98
|
-
return false
|
|
99
|
-
}
|
|
100
|
-
},
|
|
93
|
+
hasConnection: (nodeId: DhtAddress): boolean => (this.connectingConnections.has(nodeId)
|
|
94
|
+
|| this.ongoingConnectRequests.has(nodeId)
|
|
95
|
+
|| config.hasConnection(nodeId))
|
|
96
|
+
,
|
|
101
97
|
onNewConnection: (connection: ManagedConnection) => config.onNewConnection(connection),
|
|
102
98
|
abortSignal: this.abortController.signal
|
|
103
99
|
})
|
|
@@ -145,9 +141,9 @@ export class WebsocketConnector {
|
|
|
145
141
|
const serverSocket = connection as unknown as WebsocketServerConnection
|
|
146
142
|
const query = queryString.parse(serverSocket.resourceURL.query as string ?? '')
|
|
147
143
|
const action = query.action as (Action | undefined)
|
|
148
|
-
logger.trace('WebSocket client connected', { action, remoteAddress: serverSocket.
|
|
144
|
+
logger.trace('WebSocket client connected', { action, remoteAddress: serverSocket.getRemoteIpAddress() })
|
|
149
145
|
if (action === 'connectivityRequest') {
|
|
150
|
-
attachConnectivityRequestHandler(serverSocket)
|
|
146
|
+
attachConnectivityRequestHandler(serverSocket, this.geoIpLocator)
|
|
151
147
|
} else if (action === 'connectivityProbe') {
|
|
152
148
|
// no-op
|
|
153
149
|
} else {
|
|
@@ -163,6 +159,17 @@ export class WebsocketConnector {
|
|
|
163
159
|
}
|
|
164
160
|
}
|
|
165
161
|
})
|
|
162
|
+
|
|
163
|
+
if (this.config.geoIpDatabaseFolder) {
|
|
164
|
+
const geoIpLocator = new GeoIpLocator(this.config.geoIpDatabaseFolder)
|
|
165
|
+
try {
|
|
166
|
+
await geoIpLocator.start()
|
|
167
|
+
this.geoIpLocator = geoIpLocator
|
|
168
|
+
} catch (err) {
|
|
169
|
+
logger.error('Failed to start GeoIpLocator', { err })
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
166
173
|
const port = await this.websocketServer.start()
|
|
167
174
|
this.selectedPort = port
|
|
168
175
|
}
|
|
@@ -183,9 +190,9 @@ export class WebsocketConnector {
|
|
|
183
190
|
return {
|
|
184
191
|
host: this.host!,
|
|
185
192
|
natType: NatType.OPEN_INTERNET,
|
|
186
|
-
websocket: {
|
|
187
|
-
host: this.host!,
|
|
188
|
-
port: this.selectedPort!,
|
|
193
|
+
websocket: {
|
|
194
|
+
host: this.host!,
|
|
195
|
+
port: this.selectedPort!,
|
|
189
196
|
tls: this.config.tlsCertificate !== undefined
|
|
190
197
|
},
|
|
191
198
|
// TODO: Resolve the given host name or or use as is if IP was given.
|
|
@@ -307,6 +314,8 @@ export class WebsocketConnector {
|
|
|
307
314
|
const ongoingConnectRequest = this.ongoingConnectRequests.get(nodeId)!
|
|
308
315
|
if (!isMaybeSupportedVersion(remoteVersion)) {
|
|
309
316
|
ongoingConnectRequest.rejectHandshake(HandshakeError.UNSUPPORTED_VERSION)
|
|
317
|
+
} else if (targetPeerDescriptor && !areEqualPeerDescriptors(this.localPeerDescriptor!, targetPeerDescriptor)) {
|
|
318
|
+
ongoingConnectRequest.rejectHandshake(HandshakeError.INVALID_TARGET_PEER_DESCRIPTOR)
|
|
310
319
|
} else {
|
|
311
320
|
ongoingConnectRequest.attachImplementation(websocketServerConnection)
|
|
312
321
|
ongoingConnectRequest.acceptHandshake()
|
|
@@ -347,5 +356,6 @@ export class WebsocketConnector {
|
|
|
347
356
|
const attempts = Array.from(this.connectingConnections.values())
|
|
348
357
|
await Promise.allSettled(attempts.map((conn) => conn.close(false)))
|
|
349
358
|
await this.websocketServer?.stop()
|
|
359
|
+
await this.geoIpLocator?.stop()
|
|
350
360
|
}
|
|
351
361
|
}
|
|
@@ -13,7 +13,7 @@ export class WebsocketServerConnection extends EventEmitter<ConnectionEvents> im
|
|
|
13
13
|
public readonly connectionId: ConnectionID
|
|
14
14
|
public readonly connectionType = ConnectionType.WEBSOCKET_SERVER
|
|
15
15
|
public readonly resourceURL: Url
|
|
16
|
-
|
|
16
|
+
private readonly remoteIpAddress: string
|
|
17
17
|
private socket?: WebSocket
|
|
18
18
|
private stopped = false
|
|
19
19
|
|
|
@@ -34,6 +34,11 @@ export class WebsocketServerConnection extends EventEmitter<ConnectionEvents> im
|
|
|
34
34
|
|
|
35
35
|
this.socket = socket
|
|
36
36
|
}
|
|
37
|
+
|
|
38
|
+
// use a getter to make it possible to mock the value in tests
|
|
39
|
+
public getRemoteIpAddress(): string {
|
|
40
|
+
return this.remoteIpAddress
|
|
41
|
+
}
|
|
37
42
|
|
|
38
43
|
private onMessage(message: WebSocket.RawData, isBinary: boolean): void {
|
|
39
44
|
if (!isBinary) {
|