@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,109 +0,0 @@
|
|
|
1
|
-
import EventEmitter from 'eventemitter3'
|
|
2
|
-
import { IConnection, ConnectionID, ConnectionEvents, ConnectionType } from '../IConnection'
|
|
3
|
-
import WebSocket from 'ws'
|
|
4
|
-
import { Logger } from '@streamr/utils'
|
|
5
|
-
import { Url } from 'url'
|
|
6
|
-
import { CUSTOM_GOING_AWAY, GOING_AWAY } from './AbstractWebsocketClientConnection'
|
|
7
|
-
import { createRandomConnectionId } from '../Connection'
|
|
8
|
-
|
|
9
|
-
const logger = new Logger(module)
|
|
10
|
-
|
|
11
|
-
export class WebsocketServerConnection extends EventEmitter<ConnectionEvents> implements IConnection {
|
|
12
|
-
|
|
13
|
-
public readonly connectionId: ConnectionID
|
|
14
|
-
public readonly connectionType = ConnectionType.WEBSOCKET_SERVER
|
|
15
|
-
public readonly resourceURL: Url
|
|
16
|
-
private readonly remoteIpAddress: string
|
|
17
|
-
private socket?: WebSocket
|
|
18
|
-
private stopped = false
|
|
19
|
-
|
|
20
|
-
constructor(socket: WebSocket, resourceURL: Url, remoteAddress: string) {
|
|
21
|
-
super()
|
|
22
|
-
|
|
23
|
-
this.onMessage = this.onMessage.bind(this)
|
|
24
|
-
this.onClose = this.onClose.bind(this)
|
|
25
|
-
this.onError = this.onError.bind(this)
|
|
26
|
-
|
|
27
|
-
this.resourceURL = resourceURL
|
|
28
|
-
this.connectionId = createRandomConnectionId()
|
|
29
|
-
this.remoteIpAddress = remoteAddress
|
|
30
|
-
|
|
31
|
-
socket.on('message', this.onMessage)
|
|
32
|
-
socket.on('close', this.onClose)
|
|
33
|
-
socket.on('error', this.onError)
|
|
34
|
-
|
|
35
|
-
this.socket = socket
|
|
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
|
-
}
|
|
42
|
-
|
|
43
|
-
private onMessage(message: WebSocket.RawData, isBinary: boolean): void {
|
|
44
|
-
if (!isBinary) {
|
|
45
|
-
logger.trace('Received string Message')
|
|
46
|
-
} else {
|
|
47
|
-
logger.trace('Websocket server received Message')
|
|
48
|
-
this.emit('data', new Uint8Array(message as Buffer))
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
private onClose(reasonCode: number, description: string): void {
|
|
53
|
-
logger.trace('Peer ' + this.remoteIpAddress + ' disconnected.')
|
|
54
|
-
this.doDisconnect(reasonCode, description)
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
private onError(error: Error): void {
|
|
58
|
-
this.emit('error', error.name)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
private stopListening(): void {
|
|
62
|
-
this.socket?.off('message', this.onMessage)
|
|
63
|
-
this.socket?.off('close', this.onClose)
|
|
64
|
-
this.socket?.off('error', this.onError)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
private doDisconnect(reasonCode: number, description: string): void {
|
|
68
|
-
this.stopped = true
|
|
69
|
-
this.stopListening()
|
|
70
|
-
this.socket = undefined
|
|
71
|
-
const gracefulLeave = (reasonCode === GOING_AWAY) || (reasonCode === CUSTOM_GOING_AWAY)
|
|
72
|
-
this.emit('disconnected', gracefulLeave, reasonCode, description)
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
public send(data: Uint8Array): void {
|
|
76
|
-
// TODO: no need to check this.socket as it is always defined when stopped is false?
|
|
77
|
-
if (!this.stopped && this.socket) {
|
|
78
|
-
this.socket.send(data, { binary: true })
|
|
79
|
-
} else {
|
|
80
|
-
logger.debug('Tried to call send() on a stopped socket')
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
public async close(gracefulLeave: boolean): Promise<void> {
|
|
86
|
-
this.emit('disconnected', gracefulLeave, undefined, 'close() called')
|
|
87
|
-
this.removeAllListeners()
|
|
88
|
-
if (!this.stopped) {
|
|
89
|
-
this.socket?.close(gracefulLeave ? GOING_AWAY : undefined)
|
|
90
|
-
} else {
|
|
91
|
-
logger.debug('Tried to close a stopped connection')
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
// TODO could rename to "closeSilently?"
|
|
96
|
-
public destroy(): void {
|
|
97
|
-
if (!this.stopped) {
|
|
98
|
-
this.removeAllListeners()
|
|
99
|
-
if (this.socket) {
|
|
100
|
-
this.stopListening()
|
|
101
|
-
this.socket.close()
|
|
102
|
-
this.socket = undefined
|
|
103
|
-
}
|
|
104
|
-
this.stopped = true
|
|
105
|
-
} else {
|
|
106
|
-
logger.debug('Tried to destroy() a stopped connection')
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
@@ -1,290 +0,0 @@
|
|
|
1
|
-
import { GeoIpLocator } from '@streamr/geoip-location'
|
|
2
|
-
import { ListeningRpcCommunicator } from '../../transport/ListeningRpcCommunicator'
|
|
3
|
-
import { Action, connectivityMethodToWebsocketUrl } from './WebsocketClientConnector'
|
|
4
|
-
import { WebsocketServer } from './WebsocketServer'
|
|
5
|
-
import { areEqualPeerDescriptors, DhtAddress, toNodeId } from '../../identifiers'
|
|
6
|
-
import { AutoCertifierClientFacade } from './AutoCertifierClientFacade'
|
|
7
|
-
import { ConnectivityResponse, HandshakeError, PeerDescriptor } from '../../../generated/packages/dht/protos/DhtRpc'
|
|
8
|
-
import { NatType, PortRange, TlsCertificate } from '../ConnectionManager'
|
|
9
|
-
import { ITransport } from '../../transport/ITransport'
|
|
10
|
-
import { ipv4ToNumber, Logger, wait } from '@streamr/utils'
|
|
11
|
-
import { attachConnectivityRequestHandler, DISABLE_CONNECTIVITY_PROBE } from '../connectivityRequestHandler'
|
|
12
|
-
import { WebsocketServerConnection } from './WebsocketServerConnection'
|
|
13
|
-
import { ConnectionType, IConnection } from '../IConnection'
|
|
14
|
-
import queryString from 'querystring'
|
|
15
|
-
import { isMaybeSupportedProtocolVersion, LOCAL_PROTOCOL_VERSION } from '../../helpers/version'
|
|
16
|
-
import { shuffle } from 'lodash'
|
|
17
|
-
import { sendConnectivityRequest } from '../connectivityChecker'
|
|
18
|
-
import { acceptHandshake, Handshaker, rejectHandshake } from '../Handshaker'
|
|
19
|
-
import { WebsocketClientConnectorRpcRemote } from './WebsocketClientConnectorRpcRemote'
|
|
20
|
-
import { WebsocketClientConnectorRpcClient } from '../../../generated/packages/dht/protos/DhtRpc.client'
|
|
21
|
-
import { WebsocketServerStartError } from '../../helpers/errors'
|
|
22
|
-
import * as Err from '../../helpers/errors'
|
|
23
|
-
import { expectedConnectionType } from '../../helpers/Connectivity'
|
|
24
|
-
import { PendingConnection } from '../PendingConnection'
|
|
25
|
-
|
|
26
|
-
const logger = new Logger(module)
|
|
27
|
-
|
|
28
|
-
export interface WebsocketServerConnectorOptions {
|
|
29
|
-
onNewConnection: (connection: PendingConnection) => boolean
|
|
30
|
-
rpcCommunicator: ListeningRpcCommunicator
|
|
31
|
-
hasConnection: (nodeId: DhtAddress) => boolean
|
|
32
|
-
portRange?: PortRange
|
|
33
|
-
maxMessageSize?: number
|
|
34
|
-
host?: string
|
|
35
|
-
entrypoints?: PeerDescriptor[]
|
|
36
|
-
tlsCertificate?: TlsCertificate
|
|
37
|
-
autoCertifierTransport: ITransport
|
|
38
|
-
autoCertifierUrl: string
|
|
39
|
-
autoCertifierConfigFile: string
|
|
40
|
-
serverEnableTls: boolean
|
|
41
|
-
geoIpDatabaseFolder?: string
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// TODO: Could delFunc be removed here if the Handshaker event based clean up works correctly now?
|
|
45
|
-
interface OngoingConnectionRequest {
|
|
46
|
-
delFunc: () => void
|
|
47
|
-
pendingConnection: PendingConnection
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// TODO: Move server starting logic including autocertification and connectivity checking to WebsocketServer.ts?
|
|
51
|
-
export class WebsocketServerConnector {
|
|
52
|
-
|
|
53
|
-
private readonly websocketServer?: WebsocketServer
|
|
54
|
-
private geoIpLocator?: GeoIpLocator
|
|
55
|
-
private readonly ongoingConnectRequests: Map<DhtAddress, OngoingConnectionRequest> = new Map()
|
|
56
|
-
private host?: string
|
|
57
|
-
private autoCertifierClient?: AutoCertifierClientFacade
|
|
58
|
-
private selectedPort?: number
|
|
59
|
-
private localPeerDescriptor?: PeerDescriptor
|
|
60
|
-
private abortController = new AbortController()
|
|
61
|
-
private readonly options: WebsocketServerConnectorOptions
|
|
62
|
-
|
|
63
|
-
constructor(options: WebsocketServerConnectorOptions) {
|
|
64
|
-
this.options = options
|
|
65
|
-
this.websocketServer = options.portRange ? new WebsocketServer({
|
|
66
|
-
portRange: options.portRange,
|
|
67
|
-
tlsCertificate: options.tlsCertificate,
|
|
68
|
-
maxMessageSize: options.maxMessageSize,
|
|
69
|
-
enableTls: options.serverEnableTls
|
|
70
|
-
}) : undefined
|
|
71
|
-
this.host = options.host
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
public async start(): Promise<void> {
|
|
75
|
-
if (!this.abortController.signal.aborted && this.websocketServer) {
|
|
76
|
-
this.websocketServer.on('connected', (connection: IConnection) => {
|
|
77
|
-
const serverSocket = connection as unknown as WebsocketServerConnection
|
|
78
|
-
const query = queryString.parse(serverSocket.resourceURL.query as string ?? '')
|
|
79
|
-
const action = query.action as (Action | undefined)
|
|
80
|
-
logger.trace('WebSocket client connected', { action, remoteAddress: serverSocket.getRemoteIpAddress() })
|
|
81
|
-
if (action === 'connectivityRequest') {
|
|
82
|
-
attachConnectivityRequestHandler(serverSocket, this.geoIpLocator)
|
|
83
|
-
} else if (action === 'connectivityProbe') {
|
|
84
|
-
// no-op
|
|
85
|
-
} else {
|
|
86
|
-
// The localPeerDescriptor can be undefined here as the WS server is used for connectivity checks
|
|
87
|
-
// before the localPeerDescriptor is set during start.
|
|
88
|
-
// Handshaked connections should be rejected before the localPeerDescriptor is set.
|
|
89
|
-
// eslint-disable-next-line no-lonely-if
|
|
90
|
-
if (this.localPeerDescriptor !== undefined) {
|
|
91
|
-
this.attachHandshaker(connection)
|
|
92
|
-
} else {
|
|
93
|
-
logger.trace('incoming Websocket connection before localPeerDescriptor was set, closing connection')
|
|
94
|
-
connection.close(false).catch(() => {})
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
})
|
|
98
|
-
|
|
99
|
-
if (this.options.geoIpDatabaseFolder) {
|
|
100
|
-
const geoIpLocator = new GeoIpLocator(this.options.geoIpDatabaseFolder)
|
|
101
|
-
try {
|
|
102
|
-
await geoIpLocator.start()
|
|
103
|
-
this.geoIpLocator = geoIpLocator
|
|
104
|
-
} catch (err) {
|
|
105
|
-
logger.error('Failed to start GeoIpLocator', { err })
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
const port = await this.websocketServer.start()
|
|
110
|
-
this.selectedPort = port
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
private attachHandshaker(connection: IConnection) {
|
|
115
|
-
// TODO: use createIncomingHandshaker here?
|
|
116
|
-
const handshaker = new Handshaker(this.localPeerDescriptor!, connection)
|
|
117
|
-
handshaker.once('handshakeRequest', (
|
|
118
|
-
localPeerDescriptor: PeerDescriptor,
|
|
119
|
-
remoteProtocolVersion: string,
|
|
120
|
-
remotePeerDescriptor?: PeerDescriptor
|
|
121
|
-
) => {
|
|
122
|
-
this.onServerSocketHandshakeRequest(localPeerDescriptor, connection, handshaker, remoteProtocolVersion, remotePeerDescriptor)
|
|
123
|
-
})
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
private onServerSocketHandshakeRequest(
|
|
127
|
-
remotePeerDescriptor: PeerDescriptor,
|
|
128
|
-
websocketServerConnection: IConnection,
|
|
129
|
-
handshaker: Handshaker,
|
|
130
|
-
remoteProtocolVersion: string,
|
|
131
|
-
targetPeerDescriptor?: PeerDescriptor
|
|
132
|
-
) {
|
|
133
|
-
const nodeId = toNodeId(remotePeerDescriptor)
|
|
134
|
-
if (this.ongoingConnectRequests.has(nodeId)) {
|
|
135
|
-
const { pendingConnection, delFunc } = this.ongoingConnectRequests.get(nodeId)!
|
|
136
|
-
if (!isMaybeSupportedProtocolVersion(remoteProtocolVersion)) {
|
|
137
|
-
rejectHandshake(pendingConnection, websocketServerConnection, handshaker, HandshakeError.UNSUPPORTED_PROTOCOL_VERSION)
|
|
138
|
-
delFunc()
|
|
139
|
-
} else if (targetPeerDescriptor && !areEqualPeerDescriptors(this.localPeerDescriptor!, targetPeerDescriptor)) {
|
|
140
|
-
rejectHandshake(pendingConnection, websocketServerConnection, handshaker, HandshakeError.INVALID_TARGET_PEER_DESCRIPTOR)
|
|
141
|
-
delFunc()
|
|
142
|
-
} else {
|
|
143
|
-
acceptHandshake(handshaker, pendingConnection, websocketServerConnection)
|
|
144
|
-
}
|
|
145
|
-
} else {
|
|
146
|
-
const pendingConnection = new PendingConnection(remotePeerDescriptor)
|
|
147
|
-
|
|
148
|
-
if (!isMaybeSupportedProtocolVersion(remoteProtocolVersion)) {
|
|
149
|
-
rejectHandshake(pendingConnection, websocketServerConnection, handshaker, HandshakeError.UNSUPPORTED_PROTOCOL_VERSION)
|
|
150
|
-
} else if (targetPeerDescriptor && !areEqualPeerDescriptors(this.localPeerDescriptor!, targetPeerDescriptor)) {
|
|
151
|
-
rejectHandshake(pendingConnection, websocketServerConnection, handshaker, HandshakeError.INVALID_TARGET_PEER_DESCRIPTOR)
|
|
152
|
-
} else if (this.options.onNewConnection(pendingConnection)) {
|
|
153
|
-
acceptHandshake(handshaker, pendingConnection, websocketServerConnection)
|
|
154
|
-
} else {
|
|
155
|
-
rejectHandshake(pendingConnection, websocketServerConnection, handshaker, HandshakeError.DUPLICATE_CONNECTION)
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
public async checkConnectivity(allowSelfSignedCertificate: boolean): Promise<ConnectivityResponse> {
|
|
161
|
-
// TODO: this could throw?
|
|
162
|
-
if (this.abortController.signal.aborted) {
|
|
163
|
-
return {
|
|
164
|
-
host: '127.0.0.1',
|
|
165
|
-
natType: NatType.UNKNOWN,
|
|
166
|
-
ipAddress: ipv4ToNumber('127.0.0.1'),
|
|
167
|
-
protocolVersion: LOCAL_PROTOCOL_VERSION
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
if (!this.options.entrypoints || this.options.entrypoints.length === 0) {
|
|
171
|
-
// return connectivity info given in options
|
|
172
|
-
return {
|
|
173
|
-
host: this.host!,
|
|
174
|
-
natType: NatType.OPEN_INTERNET,
|
|
175
|
-
websocket: {
|
|
176
|
-
host: this.host!,
|
|
177
|
-
port: this.selectedPort!,
|
|
178
|
-
tls: this.options.tlsCertificate !== undefined
|
|
179
|
-
},
|
|
180
|
-
// TODO: Resolve the given host name or or use as is if IP was given.
|
|
181
|
-
ipAddress: ipv4ToNumber('127.0.0.1'),
|
|
182
|
-
protocolVersion: LOCAL_PROTOCOL_VERSION
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
const shuffledEntrypoints = shuffle(this.options.entrypoints)
|
|
186
|
-
while (shuffledEntrypoints.length > 0 && !this.abortController.signal.aborted) {
|
|
187
|
-
const entryPoint = shuffledEntrypoints[0]
|
|
188
|
-
try {
|
|
189
|
-
// Do real connectivity checking
|
|
190
|
-
const connectivityRequest = {
|
|
191
|
-
port: this.selectedPort ?? DISABLE_CONNECTIVITY_PROBE,
|
|
192
|
-
host: this.host,
|
|
193
|
-
tls: this.websocketServer ? this.options.serverEnableTls : false,
|
|
194
|
-
allowSelfSignedCertificate
|
|
195
|
-
}
|
|
196
|
-
if (!this.abortController.signal.aborted) {
|
|
197
|
-
return await sendConnectivityRequest(connectivityRequest, entryPoint)
|
|
198
|
-
} else {
|
|
199
|
-
throw new Err.ConnectionFailed('ConnectivityChecker is destroyed')
|
|
200
|
-
}
|
|
201
|
-
} catch (err) {
|
|
202
|
-
const error = `Failed to connect to entrypoint with id ${toNodeId(entryPoint)} `
|
|
203
|
-
+ `and URL ${connectivityMethodToWebsocketUrl(entryPoint.websocket!)}`
|
|
204
|
-
logger.error(error, { err })
|
|
205
|
-
shuffledEntrypoints.shift()
|
|
206
|
-
await wait(2000, this.abortController.signal)
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
throw new WebsocketServerStartError(
|
|
210
|
-
`Failed to connect to the entrypoints after ${this.options.entrypoints.length} attempts\n`
|
|
211
|
-
+ `Attempted hosts: ${this.options.entrypoints.map((entry) => `${entry.websocket!.host}:${entry.websocket!.port}`).join(', ')}`
|
|
212
|
-
)
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
public async autoCertify(): Promise<void> {
|
|
216
|
-
this.autoCertifierClient = new AutoCertifierClientFacade({
|
|
217
|
-
configFile: this.options.autoCertifierConfigFile,
|
|
218
|
-
transport: this.options.autoCertifierTransport,
|
|
219
|
-
url: this.options.autoCertifierUrl,
|
|
220
|
-
wsServerPort: this.selectedPort!,
|
|
221
|
-
setHost: (hostName: string) => this.setHost(hostName),
|
|
222
|
-
updateCertificate: (certificate: string, privateKey: string) => this.websocketServer!.updateCertificate(certificate, privateKey)
|
|
223
|
-
})
|
|
224
|
-
logger.trace(`AutoCertifying subdomain...`)
|
|
225
|
-
await this.autoCertifierClient.start()
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
private setHost(hostName: string): void {
|
|
229
|
-
logger.trace(`Setting host name to ${hostName}`)
|
|
230
|
-
this.host = hostName
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
public connect(targetPeerDescriptor: PeerDescriptor): PendingConnection {
|
|
234
|
-
const nodeId = toNodeId(targetPeerDescriptor)
|
|
235
|
-
if (this.ongoingConnectRequests.has(nodeId)) {
|
|
236
|
-
return this.ongoingConnectRequests.get(nodeId)!.pendingConnection
|
|
237
|
-
}
|
|
238
|
-
return this.requestConnectionFromPeer(this.localPeerDescriptor!, targetPeerDescriptor)
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
private requestConnectionFromPeer(localPeerDescriptor: PeerDescriptor, targetPeerDescriptor: PeerDescriptor): PendingConnection {
|
|
242
|
-
setImmediate(() => {
|
|
243
|
-
const remoteConnector = new WebsocketClientConnectorRpcRemote(
|
|
244
|
-
localPeerDescriptor,
|
|
245
|
-
targetPeerDescriptor,
|
|
246
|
-
this.options.rpcCommunicator,
|
|
247
|
-
WebsocketClientConnectorRpcClient
|
|
248
|
-
)
|
|
249
|
-
remoteConnector.requestConnection().then(() => {
|
|
250
|
-
logger.trace('Sent WebsocketConnectionRequest notification to peer', { targetPeerDescriptor })
|
|
251
|
-
}, (err) => {
|
|
252
|
-
logger.debug('Failed to send WebsocketConnectionRequest notification to peer ', {
|
|
253
|
-
error: err, targetPeerDescriptor
|
|
254
|
-
})
|
|
255
|
-
})
|
|
256
|
-
})
|
|
257
|
-
const pendingConnection = new PendingConnection(targetPeerDescriptor)
|
|
258
|
-
const nodeId = toNodeId(targetPeerDescriptor)
|
|
259
|
-
// TODO: can this leak?
|
|
260
|
-
const delFunc = () => {
|
|
261
|
-
pendingConnection.off('connected', delFunc)
|
|
262
|
-
pendingConnection.off('disconnected', delFunc)
|
|
263
|
-
this.ongoingConnectRequests.delete(nodeId)
|
|
264
|
-
}
|
|
265
|
-
pendingConnection.on('connected', delFunc)
|
|
266
|
-
pendingConnection.on('disconnected', delFunc)
|
|
267
|
-
this.ongoingConnectRequests.set(nodeId, { pendingConnection, delFunc })
|
|
268
|
-
return pendingConnection
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
public isPossibleToFormConnection(targetPeerDescriptor: PeerDescriptor): boolean {
|
|
272
|
-
const connectionType = expectedConnectionType(this.localPeerDescriptor!, targetPeerDescriptor)
|
|
273
|
-
return (connectionType === ConnectionType.WEBSOCKET_SERVER)
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
public setLocalPeerDescriptor(localPeerDescriptor: PeerDescriptor): void {
|
|
277
|
-
this.localPeerDescriptor = localPeerDescriptor
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
public async destroy(): Promise<void> {
|
|
281
|
-
this.abortController.abort()
|
|
282
|
-
|
|
283
|
-
const requests = Array.from(this.ongoingConnectRequests.values())
|
|
284
|
-
await Promise.allSettled(requests.map((ongoingConnectRequest) => ongoingConnectRequest.pendingConnection.close(true)))
|
|
285
|
-
|
|
286
|
-
await this.websocketServer?.stop()
|
|
287
|
-
this.geoIpLocator?.stop()
|
|
288
|
-
}
|
|
289
|
-
|
|
290
|
-
}
|