@streamr/dht 0.0.1-tatum.6 → 0.0.1-tatum.7
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/src/connection/ConnectionLockHandler.d.ts +1 -1
- package/dist/src/connection/ConnectionLockHandler.js.map +1 -1
- package/dist/src/connection/ConnectionManager.d.ts +17 -40
- package/dist/src/connection/ConnectionManager.js +138 -204
- package/dist/src/connection/ConnectionManager.js.map +1 -1
- package/dist/src/connection/ConnectivityChecker.js +14 -11
- package/dist/src/connection/ConnectivityChecker.js.map +1 -1
- package/dist/src/connection/ConnectorFacade.d.ts +49 -0
- package/dist/src/connection/ConnectorFacade.js +86 -0
- package/dist/src/connection/ConnectorFacade.js.map +1 -0
- package/dist/src/connection/ManagedConnection.d.ts +1 -4
- package/dist/src/connection/ManagedConnection.js +23 -31
- package/dist/src/connection/ManagedConnection.js.map +1 -1
- package/dist/src/connection/RemoteConnectionLocker.js +4 -3
- package/dist/src/connection/RemoteConnectionLocker.js.map +1 -1
- package/dist/src/connection/Simulator/Simulator.d.ts +0 -2
- package/dist/src/connection/Simulator/Simulator.js +0 -5
- package/dist/src/connection/Simulator/Simulator.js.map +1 -1
- package/dist/src/connection/Simulator/SimulatorConnection.js +16 -13
- package/dist/src/connection/Simulator/SimulatorConnection.js.map +1 -1
- package/dist/src/connection/Simulator/SimulatorConnector.d.ts +2 -2
- package/dist/src/connection/Simulator/SimulatorConnector.js +10 -11
- package/dist/src/connection/Simulator/SimulatorConnector.js.map +1 -1
- package/dist/src/connection/Simulator/SimulatorTransport.js +6 -1
- package/dist/src/connection/Simulator/SimulatorTransport.js.map +1 -1
- package/dist/src/connection/WebRTC/NodeWebRtcConnection.d.ts +2 -0
- package/dist/src/connection/WebRTC/NodeWebRtcConnection.js +12 -12
- package/dist/src/connection/WebRTC/NodeWebRtcConnection.js.map +1 -1
- package/dist/src/connection/WebRTC/WebRtcConnector.d.ts +9 -9
- package/dist/src/connection/WebRTC/WebRtcConnector.js +22 -22
- package/dist/src/connection/WebRTC/WebRtcConnector.js.map +1 -1
- package/dist/src/connection/WebSocket/RemoteWebSocketConnector.js +2 -1
- package/dist/src/connection/WebSocket/RemoteWebSocketConnector.js.map +1 -1
- package/dist/src/connection/WebSocket/WebSocketConnector.d.ts +19 -8
- package/dist/src/connection/WebSocket/WebSocketConnector.js +67 -46
- package/dist/src/connection/WebSocket/WebSocketConnector.js.map +1 -1
- package/dist/src/connection/WebSocket/WebSocketServer.d.ts +11 -1
- package/dist/src/connection/WebSocket/WebSocketServer.js +15 -10
- package/dist/src/connection/WebSocket/WebSocketServer.js.map +1 -1
- package/dist/src/dht/DhtNode.d.ts +15 -51
- package/dist/src/dht/DhtNode.js +107 -129
- package/dist/src/dht/DhtNode.js.map +1 -1
- package/dist/src/dht/{DhtPeer.d.ts → RemoteDhtNode.d.ts} +2 -3
- package/dist/src/dht/{DhtPeer.js → RemoteDhtNode.js} +21 -19
- package/dist/src/dht/RemoteDhtNode.js.map +1 -0
- package/dist/src/dht/contact/ContactList.d.ts +0 -1
- package/dist/src/dht/contact/ContactList.js +0 -3
- package/dist/src/dht/contact/ContactList.js.map +1 -1
- package/dist/src/dht/contact/RandomContactList.d.ts +0 -1
- package/dist/src/dht/contact/RandomContactList.js +0 -3
- package/dist/src/dht/contact/RandomContactList.js.map +1 -1
- package/dist/src/dht/contact/SortedContactList.d.ts +0 -3
- package/dist/src/dht/contact/SortedContactList.js +0 -9
- package/dist/src/dht/contact/SortedContactList.js.map +1 -1
- package/dist/src/dht/discovery/DiscoverySession.d.ts +5 -7
- package/dist/src/dht/discovery/DiscoverySession.js +9 -10
- package/dist/src/dht/discovery/DiscoverySession.js.map +1 -1
- package/dist/src/dht/discovery/PeerDiscovery.d.ts +11 -10
- package/dist/src/dht/discovery/PeerDiscovery.js +32 -37
- package/dist/src/dht/discovery/PeerDiscovery.js.map +1 -1
- package/dist/src/dht/find/RecursiveFindSession.d.ts +5 -6
- package/dist/src/dht/find/RecursiveFindSession.js +8 -8
- package/dist/src/dht/find/RecursiveFindSession.js.map +1 -1
- package/dist/src/dht/find/RecursiveFinder.d.ts +2 -4
- package/dist/src/dht/find/RecursiveFinder.js +11 -12
- package/dist/src/dht/find/RecursiveFinder.js.map +1 -1
- package/dist/src/dht/registerExternalApiRpcMethods.d.ts +1 -1
- package/dist/src/dht/routing/DuplicateDetector.d.ts +1 -2
- package/dist/src/dht/routing/DuplicateDetector.js +2 -7
- package/dist/src/dht/routing/DuplicateDetector.js.map +1 -1
- package/dist/src/dht/routing/RemoteRouter.js +1 -1
- package/dist/src/dht/routing/RemoteRouter.js.map +1 -1
- package/dist/src/dht/routing/Router.d.ts +10 -13
- package/dist/src/dht/routing/Router.js +28 -29
- package/dist/src/dht/routing/Router.js.map +1 -1
- package/dist/src/dht/routing/RoutingSession.d.ts +3 -4
- package/dist/src/dht/routing/RoutingSession.js +4 -3
- package/dist/src/dht/routing/RoutingSession.js.map +1 -1
- package/dist/src/dht/store/DataStore.d.ts +2 -2
- package/dist/src/dht/store/DataStore.js +7 -7
- package/dist/src/dht/store/DataStore.js.map +1 -1
- package/dist/src/exports.d.ts +1 -7
- package/dist/src/exports.js +2 -14
- package/dist/src/exports.js.map +1 -1
- package/dist/src/helpers/PeerID.d.ts +0 -1
- package/dist/src/helpers/PeerID.js +0 -6
- package/dist/src/helpers/PeerID.js.map +1 -1
- package/dist/src/helpers/browser/isBrowserEnvironment.d.ts +1 -0
- package/dist/src/helpers/browser/isBrowserEnvironment.js +6 -0
- package/dist/src/helpers/browser/isBrowserEnvironment.js.map +1 -0
- package/dist/src/helpers/browser/isBrowserEnvironment_override.d.ts +1 -0
- package/dist/src/helpers/browser/isBrowserEnvironment_override.js +7 -0
- package/dist/src/helpers/browser/isBrowserEnvironment_override.js.map +1 -0
- package/dist/src/helpers/kademliaId.d.ts +1 -0
- package/dist/src/helpers/kademliaId.js +14 -0
- package/dist/src/helpers/kademliaId.js.map +1 -0
- package/dist/src/helpers/peerIdFromPeerDescriptor.d.ts +1 -1
- package/dist/src/helpers/peerIdFromPeerDescriptor.js +3 -3
- package/dist/src/helpers/peerIdFromPeerDescriptor.js.map +1 -1
- package/dist/src/proto/packages/dht/protos/DhtRpc.d.ts +0 -4
- package/dist/src/proto/packages/dht/protos/DhtRpc.js +1 -2
- package/dist/src/proto/packages/dht/protos/DhtRpc.js.map +1 -1
- package/package.json +10 -9
- package/protos/DhtRpc.proto +0 -1
- package/src/connection/ConnectionLockHandler.ts +1 -1
- package/src/connection/ConnectionManager.ts +157 -254
- package/src/connection/ConnectivityChecker.ts +14 -11
- package/src/connection/ConnectorFacade.ts +143 -0
- package/src/connection/ManagedConnection.ts +23 -34
- package/src/connection/RemoteConnectionLocker.ts +4 -3
- package/src/connection/Simulator/Simulator.ts +0 -7
- package/src/connection/Simulator/SimulatorConnection.ts +16 -13
- package/src/connection/Simulator/SimulatorConnector.ts +11 -12
- package/src/connection/Simulator/SimulatorTransport.ts +6 -1
- package/src/connection/WebRTC/NodeWebRtcConnection.ts +14 -13
- package/src/connection/WebRTC/WebRtcConnector.ts +31 -31
- package/src/connection/WebSocket/RemoteWebSocketConnector.ts +2 -1
- package/src/connection/WebSocket/WebSocketConnector.ts +85 -62
- package/src/connection/WebSocket/WebSocketServer.ts +26 -8
- package/src/dht/DhtNode.ts +155 -181
- package/src/dht/{DhtPeer.ts → RemoteDhtNode.ts} +11 -9
- package/src/dht/contact/ContactList.ts +0 -4
- package/src/dht/contact/RandomContactList.ts +0 -4
- package/src/dht/contact/SortedContactList.ts +0 -12
- package/src/dht/discovery/DiscoverySession.ts +20 -23
- package/src/dht/discovery/PeerDiscovery.ts +45 -44
- package/src/dht/find/RecursiveFindSession.ts +12 -13
- package/src/dht/find/RecursiveFinder.ts +16 -19
- package/src/dht/registerExternalApiRpcMethods.ts +1 -1
- package/src/dht/routing/DuplicateDetector.ts +3 -10
- package/src/dht/routing/RemoteRouter.ts +2 -2
- package/src/dht/routing/Router.ts +35 -39
- package/src/dht/routing/RoutingSession.ts +9 -9
- package/src/dht/store/DataStore.ts +11 -11
- package/src/exports.ts +1 -7
- package/src/helpers/PeerID.ts +0 -7
- package/src/helpers/browser/isBrowserEnvironment.ts +1 -0
- package/src/helpers/browser/isBrowserEnvironment_override.ts +3 -0
- package/src/helpers/kademliaId.ts +8 -0
- package/src/helpers/peerIdFromPeerDescriptor.ts +1 -1
- package/src/proto/packages/dht/protos/DhtRpc.ts +1 -6
- package/test/benchmark/KademliaCorrectness.test.ts +4 -2
- package/test/benchmark/RecursiveFind.test.ts +6 -6
- package/test/end-to-end/Layer0-Layer1.test.ts +9 -9
- package/test/end-to-end/Layer0WebRTC-Layer1.test.ts +5 -5
- package/test/end-to-end/Layer0WebRTC.test.ts +5 -6
- package/test/end-to-end/Layer1-Scale-WebRTC.test.ts +13 -8
- package/test/end-to-end/Layer1-Scale-WebSocket.test.ts +15 -10
- package/test/end-to-end/WebSocketConnectionRequest.test.ts +5 -5
- package/test/integration/ConnectionLocking.test.ts +32 -26
- package/test/integration/ConnectionManager.test.ts +90 -93
- package/test/integration/DhtJoinPeerDiscovery.test.ts +53 -0
- package/test/integration/DhtRpc.test.ts +4 -6
- package/test/integration/Layer1-scale.test.ts +8 -8
- package/test/integration/MigrateData.test.ts +9 -9
- package/test/integration/Mock-Layer1-Layer0.test.ts +1 -2
- package/test/integration/RecursiveFind.test.ts +5 -5
- package/test/integration/{DhtPeer.test.ts → RemoteDhtNode.test.ts} +11 -12
- package/test/integration/RemoteRouter.test.ts +5 -6
- package/test/integration/RemoteStore.test.ts +4 -5
- package/test/integration/RouteMessage.test.ts +7 -9
- package/test/integration/RpcErrors.test.ts +25 -10
- package/test/integration/ScaleDownDht.test.ts +8 -8
- package/test/integration/SimultaneousConnections.test.ts +35 -36
- package/test/integration/Store.test.ts +8 -9
- package/test/integration/StoreAndDelete.test.ts +11 -11
- package/test/integration/StoreOnDhtWithTwoNodes.test.ts +7 -7
- package/test/integration/WebRtcConnectionManagement.test.ts +26 -19
- package/test/integration/WebRtcConnectorRpc.test.ts +6 -8
- package/test/integration/WebSocket.test.ts +4 -2
- package/test/integration/WebSocketConnectionManagement.test.ts +30 -17
- package/test/integration/WebSocketConnectorRpc.test.ts +2 -3
- package/test/unit/DuplicateDetector.test.ts +3 -4
- package/test/unit/LocalDataStore.test.ts +6 -8
- package/test/unit/RandomContactList.test.ts +1 -1
- package/test/unit/RecursiveFinder.test.ts +8 -12
- package/test/unit/Router.test.ts +18 -21
- package/test/unit/WebSocketConnector.test.ts +64 -0
- package/test/unit/WebSocketServer.test.ts +24 -12
- package/test/utils/mock/RecursiveFinder.ts +2 -2
- package/test/utils/mock/Router.ts +9 -11
- package/test/utils/mock/Transport.ts +2 -2
- package/test/utils/utils.ts +40 -49
- package/dist/src/dht/DhtPeer.js.map +0 -1
- package/dist/src/helpers/browser/isBrowser.d.ts +0 -1
- package/dist/src/helpers/browser/isBrowser.js +0 -6
- package/dist/src/helpers/browser/isBrowser.js.map +0 -1
- package/dist/src/helpers/browser/isNodeJS.d.ts +0 -1
- package/dist/src/helpers/browser/isNodeJS.js +0 -6
- package/dist/src/helpers/browser/isNodeJS.js.map +0 -1
- package/src/helpers/browser/isBrowser.ts +0 -1
- package/src/helpers/browser/isNodeJS.ts +0 -1
- package/test/integration/DhtWithMockConnectionLatencies.test.ts +0 -46
- package/test/integration/DhtWithMockConnections.test.ts +0 -46
- package/test/integration/DhtWithRealConnectionLatencies.test.ts +0 -47
- /package/test/unit/{webrtcReplaceInternalIpWithExternalIp.ts → webrtcReplaceInternalIpWithExternalIp.test.ts} +0 -0
|
@@ -13,8 +13,6 @@ import { PortRange } from '../ConnectionManager'
|
|
|
13
13
|
|
|
14
14
|
const logger = new Logger(module)
|
|
15
15
|
|
|
16
|
-
const MAX_MESSAGE_SIZE = 1048576
|
|
17
|
-
|
|
18
16
|
export const WEB_RTC_CLEANUP = new class {
|
|
19
17
|
// eslint-disable-next-line class-methods-use-this
|
|
20
18
|
cleanUp(): void {
|
|
@@ -27,6 +25,7 @@ export interface Params {
|
|
|
27
25
|
bufferThresholdHigh?: number
|
|
28
26
|
bufferThresholdLow?: number
|
|
29
27
|
connectingTimeout?: number
|
|
28
|
+
maxMessageSize?: number
|
|
30
29
|
iceServers?: IceServer[]
|
|
31
30
|
portRange?: PortRange
|
|
32
31
|
}
|
|
@@ -65,27 +64,29 @@ export class NodeWebRtcConnection extends EventEmitter<Events> implements IConne
|
|
|
65
64
|
private readonly connectingTimeout: number
|
|
66
65
|
private readonly remotePeerDescriptor: PeerDescriptor
|
|
67
66
|
private readonly portRange?: PortRange
|
|
67
|
+
private readonly maxMessageSize?: number
|
|
68
68
|
private closed = false
|
|
69
69
|
|
|
70
70
|
constructor(params: Params) {
|
|
71
71
|
super()
|
|
72
72
|
this.connectionId = new ConnectionID()
|
|
73
|
-
this.iceServers = params.iceServers
|
|
73
|
+
this.iceServers = params.iceServers ?? []
|
|
74
74
|
// eslint-disable-next-line no-underscore-dangle
|
|
75
|
-
this._bufferThresholdHigh = params.bufferThresholdHigh
|
|
76
|
-
this.bufferThresholdLow = params.bufferThresholdLow
|
|
77
|
-
this.connectingTimeout = params.connectingTimeout
|
|
75
|
+
this._bufferThresholdHigh = params.bufferThresholdHigh ?? 2 ** 17
|
|
76
|
+
this.bufferThresholdLow = params.bufferThresholdLow ?? 2 ** 15
|
|
77
|
+
this.connectingTimeout = params.connectingTimeout ?? 20000
|
|
78
78
|
this.remotePeerDescriptor = params.remotePeerDescriptor
|
|
79
|
+
this.maxMessageSize = params.maxMessageSize ?? 1048576
|
|
79
80
|
this.portRange = params.portRange
|
|
80
81
|
}
|
|
81
82
|
|
|
82
83
|
public start(isOffering: boolean): void {
|
|
83
|
-
logger.trace(`Staring new connection for peer: ${this.remotePeerDescriptor
|
|
84
|
-
const
|
|
85
|
-
logger.trace(`Staring new connection for peer: ${
|
|
86
|
-
this.connection = new PeerConnection(
|
|
84
|
+
logger.trace(`Staring new connection for peer: ${keyFromPeerDescriptor(this.remotePeerDescriptor)}`)
|
|
85
|
+
const peerIdKey = keyFromPeerDescriptor(this.remotePeerDescriptor)
|
|
86
|
+
logger.trace(`Staring new connection for peer: ${peerIdKey} offering: ${isOffering}`)
|
|
87
|
+
this.connection = new PeerConnection(peerIdKey, {
|
|
87
88
|
iceServers: this.iceServers.map(iceServerAsString),
|
|
88
|
-
maxMessageSize:
|
|
89
|
+
maxMessageSize: this.maxMessageSize,
|
|
89
90
|
portRangeBegin: this.portRange?.min,
|
|
90
91
|
portRangeEnd: this.portRange?.max,
|
|
91
92
|
})
|
|
@@ -96,7 +97,7 @@ export class NodeWebRtcConnection extends EventEmitter<Events> implements IConne
|
|
|
96
97
|
}, this.connectingTimeout)
|
|
97
98
|
|
|
98
99
|
this.connection.onStateChange((state: string) => this.onStateChange(state))
|
|
99
|
-
this.connection.onGatheringStateChange((
|
|
100
|
+
this.connection.onGatheringStateChange(() => {})
|
|
100
101
|
|
|
101
102
|
this.connection.onLocalDescription((description: string, type: DescriptionType) => {
|
|
102
103
|
this.emit('localDescription', description, type.toString())
|
|
@@ -232,7 +233,7 @@ export class NodeWebRtcConnection extends EventEmitter<Events> implements IConne
|
|
|
232
233
|
clearTimeout(this.connectingTimeoutRef)
|
|
233
234
|
}
|
|
234
235
|
this.dataChannel = dataChannel
|
|
235
|
-
logger.trace(`DataChannel opened for peer ${this.remotePeerDescriptor
|
|
236
|
+
logger.trace(`DataChannel opened for peer ${keyFromPeerDescriptor(this.remotePeerDescriptor)}`)
|
|
236
237
|
this.emit('connected')
|
|
237
238
|
}
|
|
238
239
|
|
|
@@ -15,11 +15,10 @@ import { ManagedWebRtcConnection } from '../ManagedWebRtcConnection'
|
|
|
15
15
|
import { Logger } from '@streamr/utils'
|
|
16
16
|
import * as Err from '../../helpers/errors'
|
|
17
17
|
import { IWebRtcConnectorService } from '../../proto/packages/dht/protos/DhtRpc.server'
|
|
18
|
-
import { ServerCallContext } from '@protobuf-ts/runtime-rpc'
|
|
19
18
|
import { ManagedConnection } from '../ManagedConnection'
|
|
20
19
|
import { toProtoRpcClient } from '@streamr/proto-rpc'
|
|
21
20
|
import {
|
|
22
|
-
|
|
21
|
+
areEqualPeerDescriptors,
|
|
23
22
|
keyFromPeerDescriptor,
|
|
24
23
|
peerIdFromPeerDescriptor
|
|
25
24
|
} from '../../helpers/peerIdFromPeerDescriptor'
|
|
@@ -38,12 +37,13 @@ export const replaceInternalIpWithExternalIp = (candidate: string, ip: string):
|
|
|
38
37
|
}
|
|
39
38
|
|
|
40
39
|
export interface WebRtcConnectorConfig {
|
|
41
|
-
|
|
40
|
+
transport: ITransport
|
|
42
41
|
protocolVersion: string
|
|
43
42
|
iceServers?: IceServer[]
|
|
44
43
|
allowPrivateAddresses?: boolean
|
|
45
44
|
bufferThresholdLow?: number
|
|
46
45
|
bufferThresholdHigh?: number
|
|
46
|
+
maxMessageSize?: number
|
|
47
47
|
connectionTimeout?: number
|
|
48
48
|
externalIp?: string
|
|
49
49
|
portRange?: PortRange
|
|
@@ -58,7 +58,7 @@ export interface IceServer {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
export class WebRtcConnector implements IWebRtcConnectorService {
|
|
61
|
-
private static readonly WEBRTC_CONNECTOR_SERVICE_ID = 'system/
|
|
61
|
+
private static readonly WEBRTC_CONNECTOR_SERVICE_ID = 'system/webrtc-connector'
|
|
62
62
|
private readonly rpcCommunicator: ListeningRpcCommunicator
|
|
63
63
|
private readonly ongoingConnectAttempts: Map<PeerIDKey, ManagedWebRtcConnection> = new Map()
|
|
64
64
|
private ownPeerDescriptor?: PeerDescriptor
|
|
@@ -66,36 +66,36 @@ export class WebRtcConnector implements IWebRtcConnectorService {
|
|
|
66
66
|
private iceServers: IceServer[]
|
|
67
67
|
private allowPrivateAddresses: boolean
|
|
68
68
|
private config: WebRtcConnectorConfig
|
|
69
|
-
private
|
|
69
|
+
private onIncomingConnection: (connection: ManagedConnection) => boolean
|
|
70
70
|
|
|
71
71
|
constructor(
|
|
72
72
|
config: WebRtcConnectorConfig,
|
|
73
|
-
|
|
73
|
+
onIncomingConnection: (connection: ManagedConnection) => boolean
|
|
74
74
|
) {
|
|
75
75
|
this.config = config
|
|
76
76
|
this.iceServers = config.iceServers || []
|
|
77
77
|
this.allowPrivateAddresses = config.allowPrivateAddresses || true
|
|
78
|
-
this.
|
|
78
|
+
this.onIncomingConnection = onIncomingConnection
|
|
79
79
|
|
|
80
|
-
this.rpcCommunicator = new ListeningRpcCommunicator(WebRtcConnector.WEBRTC_CONNECTOR_SERVICE_ID, config.
|
|
80
|
+
this.rpcCommunicator = new ListeningRpcCommunicator(WebRtcConnector.WEBRTC_CONNECTOR_SERVICE_ID, config.transport, {
|
|
81
81
|
rpcRequestTimeout: 15000
|
|
82
82
|
})
|
|
83
83
|
this.rpcCommunicator.registerRpcNotification(RtcOffer, 'rtcOffer',
|
|
84
|
-
(req: RtcOffer
|
|
84
|
+
(req: RtcOffer) => this.rtcOffer(req))
|
|
85
85
|
this.rpcCommunicator.registerRpcNotification(RtcAnswer, 'rtcAnswer',
|
|
86
|
-
(req: RtcAnswer
|
|
86
|
+
(req: RtcAnswer) => this.rtcAnswer(req))
|
|
87
87
|
this.rpcCommunicator.registerRpcNotification(IceCandidate, 'iceCandidate',
|
|
88
|
-
(req: IceCandidate
|
|
88
|
+
(req: IceCandidate) => this.iceCandidate(req))
|
|
89
89
|
this.rpcCommunicator.registerRpcNotification(WebRtcConnectionRequest, 'requestConnection',
|
|
90
|
-
(req: WebRtcConnectionRequest
|
|
90
|
+
(req: WebRtcConnectionRequest) => this.requestConnection(req))
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
connect(targetPeerDescriptor: PeerDescriptor): ManagedConnection {
|
|
94
|
-
if (
|
|
94
|
+
if (areEqualPeerDescriptors(targetPeerDescriptor, this.ownPeerDescriptor!)) {
|
|
95
95
|
throw new Err.CannotConnectToSelf('Cannot open WebRTC Connection to self')
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
logger.trace(`Opening WebRTC connection to ${targetPeerDescriptor
|
|
98
|
+
logger.trace(`Opening WebRTC connection to ${keyFromPeerDescriptor(targetPeerDescriptor)}`)
|
|
99
99
|
|
|
100
100
|
const peerKey = keyFromPeerDescriptor(targetPeerDescriptor)
|
|
101
101
|
const existingConnection = this.ongoingConnectAttempts.get(peerKey)
|
|
@@ -103,7 +103,7 @@ export class WebRtcConnector implements IWebRtcConnectorService {
|
|
|
103
103
|
return existingConnection
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
const connection = new NodeWebRtcConnection({
|
|
106
|
+
const connection = new NodeWebRtcConnection({
|
|
107
107
|
remotePeerDescriptor: targetPeerDescriptor,
|
|
108
108
|
iceServers: this.iceServers,
|
|
109
109
|
bufferThresholdLow: this.config.bufferThresholdLow,
|
|
@@ -149,11 +149,11 @@ export class WebRtcConnector implements IWebRtcConnectorService {
|
|
|
149
149
|
})
|
|
150
150
|
|
|
151
151
|
if (offering) {
|
|
152
|
-
connection.once('localDescription', (description: string
|
|
152
|
+
connection.once('localDescription', (description: string) => {
|
|
153
153
|
remoteConnector.sendRtcOffer(this.ownPeerDescriptor!, description, connection.connectionId.toString())
|
|
154
154
|
})
|
|
155
155
|
} else {
|
|
156
|
-
connection.once('localDescription', (description: string
|
|
156
|
+
connection.once('localDescription', (description: string) => {
|
|
157
157
|
remoteConnector.sendRtcAnswer(this.ownPeerDescriptor!, description, connection.connectionId.toString())
|
|
158
158
|
})
|
|
159
159
|
}
|
|
@@ -171,7 +171,7 @@ export class WebRtcConnector implements IWebRtcConnectorService {
|
|
|
171
171
|
this.ownPeerDescriptor = peerDescriptor
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
isIceCandidateAllowed(candidate: string): boolean {
|
|
174
|
+
private isIceCandidateAllowed(candidate: string): boolean {
|
|
175
175
|
if (!this.allowPrivateAddresses) {
|
|
176
176
|
const address = getAddressFromIceCandidate(candidate)
|
|
177
177
|
if (address && isPrivateIPv4(address)) {
|
|
@@ -187,7 +187,7 @@ export class WebRtcConnector implements IWebRtcConnectorService {
|
|
|
187
187
|
description: string,
|
|
188
188
|
connectionId: string
|
|
189
189
|
): void {
|
|
190
|
-
if (this.stopped || !
|
|
190
|
+
if (this.stopped || !areEqualPeerDescriptors(targetPeer, this.ownPeerDescriptor!)) {
|
|
191
191
|
return
|
|
192
192
|
}
|
|
193
193
|
const peerKey = keyFromPeerDescriptor(remotePeer)
|
|
@@ -197,11 +197,11 @@ export class WebRtcConnector implements IWebRtcConnectorService {
|
|
|
197
197
|
if (!managedConnection) {
|
|
198
198
|
connection = new NodeWebRtcConnection({ remotePeerDescriptor: remotePeer })
|
|
199
199
|
managedConnection = new ManagedWebRtcConnection(this.ownPeerDescriptor!, this.config.protocolVersion, undefined, connection)
|
|
200
|
-
|
|
200
|
+
|
|
201
201
|
managedConnection.setPeerDescriptor(remotePeer)
|
|
202
202
|
|
|
203
203
|
this.ongoingConnectAttempts.set(peerKey, managedConnection)
|
|
204
|
-
this.
|
|
204
|
+
this.onIncomingConnection(managedConnection)
|
|
205
205
|
|
|
206
206
|
const remoteConnector = new RemoteWebrtcConnector(
|
|
207
207
|
remotePeer,
|
|
@@ -212,7 +212,7 @@ export class WebRtcConnector implements IWebRtcConnectorService {
|
|
|
212
212
|
remoteConnector.sendIceCandidate(this.ownPeerDescriptor!, candidate, mid, connection!.connectionId.toString())
|
|
213
213
|
})
|
|
214
214
|
|
|
215
|
-
connection.once('localDescription', (description: string
|
|
215
|
+
connection.once('localDescription', (description: string) => {
|
|
216
216
|
remoteConnector.sendRtcAnswer(this.ownPeerDescriptor!, description, connection!.connectionId.toString())
|
|
217
217
|
})
|
|
218
218
|
|
|
@@ -223,7 +223,7 @@ export class WebRtcConnector implements IWebRtcConnectorService {
|
|
|
223
223
|
// Always use offerers connectionId
|
|
224
224
|
connection!.setConnectionId(connectionId)
|
|
225
225
|
connection!.setRemoteDescription(description, 'offer')
|
|
226
|
-
|
|
226
|
+
|
|
227
227
|
managedConnection.on('handshakeRequest', () => {
|
|
228
228
|
if (this.ongoingConnectAttempts.has(peerKey)) {
|
|
229
229
|
this.ongoingConnectAttempts.delete(peerKey)
|
|
@@ -238,7 +238,7 @@ export class WebRtcConnector implements IWebRtcConnectorService {
|
|
|
238
238
|
description: string,
|
|
239
239
|
connectionId: string
|
|
240
240
|
): void {
|
|
241
|
-
if (this.stopped || !
|
|
241
|
+
if (this.stopped || !areEqualPeerDescriptors(targetPeerDescriptor, this.ownPeerDescriptor!)) {
|
|
242
242
|
return
|
|
243
243
|
}
|
|
244
244
|
const peerKey = keyFromPeerDescriptor(remotePeerDescriptor)
|
|
@@ -259,7 +259,7 @@ export class WebRtcConnector implements IWebRtcConnectorService {
|
|
|
259
259
|
const managedConnection = this.connect(targetPeerDescriptor)
|
|
260
260
|
managedConnection.setPeerDescriptor(targetPeerDescriptor)
|
|
261
261
|
|
|
262
|
-
this.
|
|
262
|
+
this.onIncomingConnection(managedConnection)
|
|
263
263
|
}
|
|
264
264
|
private onRemoteCandidate(
|
|
265
265
|
remotePeerDescriptor: PeerDescriptor,
|
|
@@ -268,7 +268,7 @@ export class WebRtcConnector implements IWebRtcConnectorService {
|
|
|
268
268
|
mid: string,
|
|
269
269
|
connectionId: string
|
|
270
270
|
): void {
|
|
271
|
-
if (this.stopped || !
|
|
271
|
+
if (this.stopped || !areEqualPeerDescriptors(targetPeerDescriptor, this.ownPeerDescriptor!)) {
|
|
272
272
|
return
|
|
273
273
|
}
|
|
274
274
|
const peerKey = keyFromPeerDescriptor(remotePeerDescriptor)
|
|
@@ -290,7 +290,7 @@ export class WebRtcConnector implements IWebRtcConnectorService {
|
|
|
290
290
|
|
|
291
291
|
const attempts = Array.from(this.ongoingConnectAttempts.values())
|
|
292
292
|
await Promise.allSettled(attempts.map((conn) => conn.close('OTHER')))
|
|
293
|
-
|
|
293
|
+
|
|
294
294
|
this.rpcCommunicator.stop()
|
|
295
295
|
}
|
|
296
296
|
|
|
@@ -301,22 +301,22 @@ export class WebRtcConnector implements IWebRtcConnectorService {
|
|
|
301
301
|
}
|
|
302
302
|
|
|
303
303
|
// IWebRTCConnector implementation
|
|
304
|
-
async requestConnection(request: WebRtcConnectionRequest
|
|
304
|
+
async requestConnection(request: WebRtcConnectionRequest): Promise<Empty> {
|
|
305
305
|
this.onConnectionRequest(request.requester!)
|
|
306
306
|
return {}
|
|
307
307
|
}
|
|
308
308
|
|
|
309
|
-
async rtcOffer(request: RtcOffer
|
|
309
|
+
async rtcOffer(request: RtcOffer): Promise<Empty> {
|
|
310
310
|
this.onRtcOffer(request.requester!, request.target!, request.description, request.connectionId)
|
|
311
311
|
return {}
|
|
312
312
|
}
|
|
313
313
|
|
|
314
|
-
async rtcAnswer(request: RtcAnswer
|
|
314
|
+
async rtcAnswer(request: RtcAnswer): Promise<Empty> {
|
|
315
315
|
this.onRtcAnswer(request.requester!, request.target!, request.description, request.connectionId)
|
|
316
316
|
return {}
|
|
317
317
|
}
|
|
318
318
|
|
|
319
|
-
async iceCandidate(request: IceCandidate
|
|
319
|
+
async iceCandidate(request: IceCandidate): Promise<Empty> {
|
|
320
320
|
this.onRemoteCandidate(request.requester!, request.target!, request.candidate, request.mid, request.connectionId)
|
|
321
321
|
return {}
|
|
322
322
|
}
|
|
@@ -7,6 +7,7 @@ import { DhtRpcOptions } from '../../rpc-protocol/DhtRpcOptions'
|
|
|
7
7
|
import { Logger } from '@streamr/utils'
|
|
8
8
|
import * as Err from '../../helpers/errors'
|
|
9
9
|
import { ProtoRpcClient } from '@streamr/proto-rpc'
|
|
10
|
+
import { keyFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
|
|
10
11
|
|
|
11
12
|
const logger = new Logger(module)
|
|
12
13
|
|
|
@@ -21,7 +22,7 @@ export class RemoteWebSocketConnector {
|
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
async requestConnection(sourceDescriptor: PeerDescriptor, ip: string, port: number): Promise<boolean> {
|
|
24
|
-
logger.trace(`Requesting WebSocket connection from ${this.peerDescriptor
|
|
25
|
+
logger.trace(`Requesting WebSocket connection from ${keyFromPeerDescriptor(this.peerDescriptor)}`)
|
|
25
26
|
const request: WebSocketConnectionRequest = {
|
|
26
27
|
target: this.peerDescriptor,
|
|
27
28
|
requester: sourceDescriptor,
|
|
@@ -6,14 +6,14 @@ import { RemoteWebSocketConnector } from './RemoteWebSocketConnector'
|
|
|
6
6
|
import {
|
|
7
7
|
ConnectivityMethod,
|
|
8
8
|
ConnectivityResponse,
|
|
9
|
+
NodeType,
|
|
9
10
|
PeerDescriptor,
|
|
10
11
|
WebSocketConnectionRequest,
|
|
11
12
|
WebSocketConnectionResponse
|
|
12
13
|
} from '../../proto/packages/dht/protos/DhtRpc'
|
|
13
14
|
import { WebSocketConnectorServiceClient } from '../../proto/packages/dht/protos/DhtRpc.client'
|
|
14
|
-
import { Logger, wait } from '@streamr/utils'
|
|
15
|
+
import { Logger, binaryToHex, wait } from '@streamr/utils'
|
|
15
16
|
import { IWebSocketConnectorService } from '../../proto/packages/dht/protos/DhtRpc.server'
|
|
16
|
-
import { ServerCallContext } from '@protobuf-ts/runtime-rpc'
|
|
17
17
|
import { ManagedConnection } from '../ManagedConnection'
|
|
18
18
|
import { WebSocketServer } from './WebSocketServer'
|
|
19
19
|
import { ConnectivityChecker } from '../ConnectivityChecker'
|
|
@@ -24,7 +24,8 @@ import { toProtoRpcClient } from '@streamr/proto-rpc'
|
|
|
24
24
|
import { Handshaker } from '../Handshaker'
|
|
25
25
|
import { keyFromPeerDescriptor, peerIdFromPeerDescriptor } from '../../helpers/peerIdFromPeerDescriptor'
|
|
26
26
|
import { ParsedUrlQuery } from 'querystring'
|
|
27
|
-
import { sample } from 'lodash'
|
|
27
|
+
import { range, sample } from 'lodash'
|
|
28
|
+
import { isPrivateIPv4 } from '../../helpers/AddressTools'
|
|
28
29
|
|
|
29
30
|
const logger = new Logger(module)
|
|
30
31
|
|
|
@@ -32,19 +33,35 @@ export const connectivityMethodToWebSocketUrl = (ws: ConnectivityMethod): string
|
|
|
32
33
|
return (ws.tls ? 'wss://' : 'ws://') + ws.host + ':' + ws.port
|
|
33
34
|
}
|
|
34
35
|
|
|
36
|
+
const canOpenConnectionFromBrowser = (websocketServer: ConnectivityMethod) => {
|
|
37
|
+
const hasPrivateAddress = ((websocketServer.host === 'localhost') || isPrivateIPv4(websocketServer.host))
|
|
38
|
+
return websocketServer.tls || hasPrivateAddress
|
|
39
|
+
}
|
|
40
|
+
|
|
35
41
|
const ENTRY_POINT_CONNECTION_ATTEMPTS = 5
|
|
36
42
|
|
|
43
|
+
interface WebSocketConnectorConfig {
|
|
44
|
+
protocolVersion: string
|
|
45
|
+
transport: ITransport
|
|
46
|
+
canConnect: (peerDescriptor: PeerDescriptor, _ip: string, port: number) => boolean
|
|
47
|
+
onIncomingConnection: (connection: ManagedConnection) => boolean
|
|
48
|
+
portRange?: PortRange
|
|
49
|
+
maxMessageSize?: number
|
|
50
|
+
host?: string
|
|
51
|
+
entrypoints?: PeerDescriptor[]
|
|
52
|
+
tlsCertificate?: TlsCertificate
|
|
53
|
+
}
|
|
54
|
+
|
|
37
55
|
export class WebSocketConnector implements IWebSocketConnectorService {
|
|
38
|
-
private static readonly WEBSOCKET_CONNECTOR_SERVICE_ID = 'system/
|
|
56
|
+
private static readonly WEBSOCKET_CONNECTOR_SERVICE_ID = 'system/websocket-connector'
|
|
39
57
|
private readonly rpcCommunicator: ListeningRpcCommunicator
|
|
40
58
|
private readonly canConnectFunction: (peerDescriptor: PeerDescriptor, _ip: string, port: number) => boolean
|
|
41
59
|
private readonly webSocketServer?: WebSocketServer
|
|
42
60
|
private connectivityChecker?: ConnectivityChecker
|
|
43
61
|
private readonly ongoingConnectRequests: Map<PeerIDKey, ManagedConnection> = new Map()
|
|
44
|
-
private
|
|
45
|
-
private portRange?: PortRange
|
|
62
|
+
private onIncomingConnection: (connection: ManagedConnection) => boolean
|
|
46
63
|
private host?: string
|
|
47
|
-
private entrypoints?: PeerDescriptor[]
|
|
64
|
+
private readonly entrypoints?: PeerDescriptor[]
|
|
48
65
|
private readonly tlsCertificate?: TlsCertificate
|
|
49
66
|
private selectedPort?: number
|
|
50
67
|
private readonly protocolVersion: string
|
|
@@ -52,27 +69,21 @@ export class WebSocketConnector implements IWebSocketConnectorService {
|
|
|
52
69
|
private connectingConnections: Map<PeerIDKey, ManagedConnection> = new Map()
|
|
53
70
|
private destroyed = false
|
|
54
71
|
|
|
55
|
-
constructor(
|
|
56
|
-
protocolVersion
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
this.
|
|
66
|
-
|
|
67
|
-
this.
|
|
68
|
-
|
|
69
|
-
this.
|
|
70
|
-
this.entrypoints = entrypoints
|
|
71
|
-
this.tlsCertificate = tlsCertificate
|
|
72
|
-
|
|
73
|
-
this.canConnectFunction = fnCanConnect.bind(this)
|
|
74
|
-
|
|
75
|
-
this.rpcCommunicator = new ListeningRpcCommunicator(WebSocketConnector.WEBSOCKET_CONNECTOR_SERVICE_ID, rpcTransport, {
|
|
72
|
+
constructor(config: WebSocketConnectorConfig) {
|
|
73
|
+
this.protocolVersion = config.protocolVersion
|
|
74
|
+
this.webSocketServer = config.portRange ? new WebSocketServer({
|
|
75
|
+
portRange: config.portRange!,
|
|
76
|
+
tlsCertificate: config.tlsCertificate,
|
|
77
|
+
maxMessageSize: config.maxMessageSize
|
|
78
|
+
}) : undefined
|
|
79
|
+
this.onIncomingConnection = config.onIncomingConnection
|
|
80
|
+
this.host = config.host
|
|
81
|
+
this.entrypoints = config.entrypoints
|
|
82
|
+
this.tlsCertificate = config.tlsCertificate
|
|
83
|
+
|
|
84
|
+
this.canConnectFunction = config.canConnect.bind(this)
|
|
85
|
+
|
|
86
|
+
this.rpcCommunicator = new ListeningRpcCommunicator(WebSocketConnector.WEBSOCKET_CONNECTOR_SERVICE_ID, config.transport, {
|
|
76
87
|
rpcRequestTimeout: 15000
|
|
77
88
|
})
|
|
78
89
|
|
|
@@ -80,7 +91,7 @@ export class WebSocketConnector implements IWebSocketConnectorService {
|
|
|
80
91
|
WebSocketConnectionRequest,
|
|
81
92
|
WebSocketConnectionResponse,
|
|
82
93
|
'requestConnection',
|
|
83
|
-
(req: WebSocketConnectionRequest
|
|
94
|
+
(req: WebSocketConnectionRequest) => this.requestConnection(req)
|
|
84
95
|
)
|
|
85
96
|
}
|
|
86
97
|
|
|
@@ -100,10 +111,10 @@ export class WebSocketConnector implements IWebSocketConnectorService {
|
|
|
100
111
|
serverSocket.resourceURL.query) {
|
|
101
112
|
const query = serverSocket.resourceURL.query as unknown as ParsedUrlQuery
|
|
102
113
|
if (query.connectivityRequest) {
|
|
103
|
-
logger.trace('Received connectivity request connection')
|
|
114
|
+
logger.trace('Received connectivity request connection from ' + serverSocket.getRemoteAddress())
|
|
104
115
|
this.connectivityChecker!.listenToIncomingConnectivityRequests(serverSocket)
|
|
105
116
|
} else if (query.connectivityProbe) {
|
|
106
|
-
logger.trace('Received connectivity probe connection')
|
|
117
|
+
logger.trace('Received connectivity probe connection from ' + serverSocket.getRemoteAddress())
|
|
107
118
|
} else {
|
|
108
119
|
this.attachHandshaker(connection)
|
|
109
120
|
}
|
|
@@ -111,13 +122,13 @@ export class WebSocketConnector implements IWebSocketConnectorService {
|
|
|
111
122
|
this.attachHandshaker(connection)
|
|
112
123
|
}
|
|
113
124
|
})
|
|
114
|
-
const port = await this.webSocketServer.start(
|
|
125
|
+
const port = await this.webSocketServer.start()
|
|
115
126
|
this.selectedPort = port
|
|
116
127
|
this.connectivityChecker = new ConnectivityChecker(this.selectedPort, this.tlsCertificate !== undefined, this.host)
|
|
117
128
|
}
|
|
118
129
|
}
|
|
119
130
|
|
|
120
|
-
public async checkConnectivity(
|
|
131
|
+
public async checkConnectivity(): Promise<ConnectivityResponse> {
|
|
121
132
|
// TODO: this could throw if the server is not running
|
|
122
133
|
const noServerConnectivityResponse: ConnectivityResponse = {
|
|
123
134
|
openInternet: false,
|
|
@@ -127,35 +138,47 @@ export class WebSocketConnector implements IWebSocketConnectorService {
|
|
|
127
138
|
if (this.destroyed) {
|
|
128
139
|
return noServerConnectivityResponse
|
|
129
140
|
}
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
// return connectivity info given in config
|
|
137
|
-
const preconfiguredConnectivityResponse: ConnectivityResponse = {
|
|
138
|
-
openInternet: true,
|
|
139
|
-
host: this.host!,
|
|
140
|
-
natType: NatType.OPEN_INTERNET,
|
|
141
|
-
websocket: { host: this.host!, port: this.selectedPort!, tls: this.tlsCertificate !== undefined }
|
|
142
|
-
}
|
|
143
|
-
return preconfiguredConnectivityResponse
|
|
141
|
+
for (const reattempt of range(ENTRY_POINT_CONNECTION_ATTEMPTS)) {
|
|
142
|
+
const entryPoint = sample(this.entrypoints)!
|
|
143
|
+
try {
|
|
144
|
+
if (!this.webSocketServer) {
|
|
145
|
+
// If no websocket server, return openInternet: false
|
|
146
|
+
return noServerConnectivityResponse
|
|
144
147
|
} else {
|
|
145
|
-
|
|
146
|
-
|
|
148
|
+
if (!this.entrypoints || this.entrypoints.length < 1) {
|
|
149
|
+
// return connectivity info given in config
|
|
150
|
+
const preconfiguredConnectivityResponse: ConnectivityResponse = {
|
|
151
|
+
openInternet: true,
|
|
152
|
+
host: this.host!,
|
|
153
|
+
natType: NatType.OPEN_INTERNET,
|
|
154
|
+
websocket: { host: this.host!, port: this.selectedPort!, tls: this.tlsCertificate !== undefined }
|
|
155
|
+
}
|
|
156
|
+
return preconfiguredConnectivityResponse
|
|
157
|
+
} else {
|
|
158
|
+
// Do real connectivity checking
|
|
159
|
+
return await this.connectivityChecker!.sendConnectivityRequest(entryPoint)
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
} catch (err) {
|
|
163
|
+
if (reattempt < ENTRY_POINT_CONNECTION_ATTEMPTS) {
|
|
164
|
+
const error = `Failed to connect to entrypoint with id ${binaryToHex(entryPoint.kademliaId)} `
|
|
165
|
+
+ `and URL ${connectivityMethodToWebSocketUrl(entryPoint.websocket!)}`
|
|
166
|
+
logger.error(error, { error: err })
|
|
167
|
+
await wait(2000)
|
|
147
168
|
}
|
|
148
|
-
}
|
|
149
|
-
} catch (err) {
|
|
150
|
-
if (reattempt < ENTRY_POINT_CONNECTION_ATTEMPTS) {
|
|
151
|
-
logger.error('Failed to connect to the entrypoint', { error: err })
|
|
152
|
-
await wait(2000)
|
|
153
|
-
return this.checkConnectivity(reattempt + 1)
|
|
154
|
-
} else {
|
|
155
|
-
throw err
|
|
156
169
|
}
|
|
157
170
|
}
|
|
171
|
+
throw Error(`Failed to connect to the entrypoints after ${ENTRY_POINT_CONNECTION_ATTEMPTS} attempts`)
|
|
172
|
+
}
|
|
158
173
|
|
|
174
|
+
public isPossibleToFormConnection(targetPeerDescriptor: PeerDescriptor): boolean {
|
|
175
|
+
if (this.ownPeerDescriptor!.websocket !== undefined) {
|
|
176
|
+
return (targetPeerDescriptor.type !== NodeType.BROWSER) || canOpenConnectionFromBrowser(this.ownPeerDescriptor!.websocket)
|
|
177
|
+
} else if (targetPeerDescriptor.websocket !== undefined) {
|
|
178
|
+
return (this.ownPeerDescriptor!.type !== NodeType.BROWSER) || canOpenConnectionFromBrowser(targetPeerDescriptor.websocket)
|
|
179
|
+
} else {
|
|
180
|
+
return false
|
|
181
|
+
}
|
|
159
182
|
}
|
|
160
183
|
|
|
161
184
|
public connect(targetPeerDescriptor: PeerDescriptor): ManagedConnection {
|
|
@@ -194,7 +217,7 @@ export class WebSocketConnector implements IWebSocketConnectorService {
|
|
|
194
217
|
}
|
|
195
218
|
}
|
|
196
219
|
|
|
197
|
-
|
|
220
|
+
private requestConnectionFromPeer(ownPeerDescriptor: PeerDescriptor, targetPeerDescriptor: PeerDescriptor): ManagedConnection {
|
|
198
221
|
setImmediate(() => {
|
|
199
222
|
const remoteConnector = new RemoteWebSocketConnector(
|
|
200
223
|
targetPeerDescriptor,
|
|
@@ -215,7 +238,7 @@ export class WebSocketConnector implements IWebSocketConnectorService {
|
|
|
215
238
|
|
|
216
239
|
if (this.ongoingConnectRequests.has(peerId.toKey())) {
|
|
217
240
|
const ongoingConnectReguest = this.ongoingConnectRequests.get(peerId.toKey())!
|
|
218
|
-
ongoingConnectReguest.attachImplementation(serverWebSocket
|
|
241
|
+
ongoingConnectReguest.attachImplementation(serverWebSocket)
|
|
219
242
|
ongoingConnectReguest.acceptHandshake()
|
|
220
243
|
this.ongoingConnectRequests.delete(peerId.toKey())
|
|
221
244
|
} else {
|
|
@@ -224,7 +247,7 @@ export class WebSocketConnector implements IWebSocketConnectorService {
|
|
|
224
247
|
|
|
225
248
|
managedConnection.setPeerDescriptor(peerDescriptor)
|
|
226
249
|
|
|
227
|
-
if (this.
|
|
250
|
+
if (this.onIncomingConnection(managedConnection)) {
|
|
228
251
|
managedConnection.acceptHandshake()
|
|
229
252
|
} else {
|
|
230
253
|
managedConnection.rejectHandshake('Duplicate connection')
|
|
@@ -251,14 +274,14 @@ export class WebSocketConnector implements IWebSocketConnectorService {
|
|
|
251
274
|
}
|
|
252
275
|
|
|
253
276
|
// IWebSocketConnectorService implementation
|
|
254
|
-
public async requestConnection(request: WebSocketConnectionRequest
|
|
277
|
+
public async requestConnection(request: WebSocketConnectionRequest): Promise<WebSocketConnectionResponse> {
|
|
255
278
|
if (!this.destroyed && this.canConnectFunction(request.requester!, request.ip, request.port)) {
|
|
256
279
|
setImmediate(() => {
|
|
257
280
|
if (this.destroyed) {
|
|
258
281
|
return
|
|
259
282
|
}
|
|
260
283
|
const connection = this.connect(request.requester!)
|
|
261
|
-
this.
|
|
284
|
+
this.onIncomingConnection(connection)
|
|
262
285
|
})
|
|
263
286
|
const res: WebSocketConnectionResponse = {
|
|
264
287
|
accepted: true
|
|
@@ -22,17 +22,33 @@ const logger = new Logger(module)
|
|
|
22
22
|
|
|
23
23
|
declare class NodeJsWsServer extends WsServer { }
|
|
24
24
|
|
|
25
|
+
interface WebSocketServerConfig {
|
|
26
|
+
portRange: PortRange
|
|
27
|
+
tlsCertificate?: TlsCertificate
|
|
28
|
+
maxMessageSize?: number
|
|
29
|
+
}
|
|
30
|
+
|
|
25
31
|
export class WebSocketServer extends EventEmitter<ConnectionSourceEvents> {
|
|
26
32
|
|
|
27
33
|
private httpServer?: HttpServer | HttpsServer
|
|
28
34
|
private wsServer?: WsServer
|
|
29
35
|
private readonly abortController = new AbortController()
|
|
36
|
+
private readonly portRange: PortRange
|
|
37
|
+
private readonly tlsCertificate?: TlsCertificate
|
|
38
|
+
private readonly maxMessageSize: number
|
|
39
|
+
|
|
40
|
+
constructor(config: WebSocketServerConfig) {
|
|
41
|
+
super()
|
|
42
|
+
this.portRange = config.portRange
|
|
43
|
+
this.tlsCertificate = config.tlsCertificate
|
|
44
|
+
this.maxMessageSize = config.maxMessageSize ?? 1048576
|
|
45
|
+
}
|
|
30
46
|
|
|
31
|
-
public async start(
|
|
32
|
-
const ports = range(portRange.min, portRange.max + 1)
|
|
47
|
+
public async start(): Promise<number> {
|
|
48
|
+
const ports = range(this.portRange.min, this.portRange.max + 1)
|
|
33
49
|
for (const port of ports) {
|
|
34
50
|
try {
|
|
35
|
-
await asAbortable(this.startServer(port, tlsCertificate), this.abortController.signal)
|
|
51
|
+
await asAbortable(this.startServer(port, this.tlsCertificate), this.abortController.signal)
|
|
36
52
|
return port
|
|
37
53
|
} catch (err) {
|
|
38
54
|
if (err.originalError?.code === 'EADDRINUSE') {
|
|
@@ -42,7 +58,7 @@ export class WebSocketServer extends EventEmitter<ConnectionSourceEvents> {
|
|
|
42
58
|
}
|
|
43
59
|
}
|
|
44
60
|
}
|
|
45
|
-
throw new WebSocketServerStartError(`Failed to start WebSocket server on any port in range: ${portRange.min}-${portRange.min}`)
|
|
61
|
+
throw new WebSocketServerStartError(`Failed to start WebSocket server on any port in range: ${this.portRange.min}-${this.portRange.min}`)
|
|
46
62
|
}
|
|
47
63
|
|
|
48
64
|
private startServer(port: number, tlsCertificate?: TlsCertificate): Promise<void> {
|
|
@@ -60,14 +76,14 @@ export class WebSocketServer extends EventEmitter<ConnectionSourceEvents> {
|
|
|
60
76
|
:
|
|
61
77
|
createHttpServer(requestListener)
|
|
62
78
|
|
|
63
|
-
function originIsAllowed(
|
|
79
|
+
function originIsAllowed() {
|
|
64
80
|
return true
|
|
65
81
|
}
|
|
66
82
|
|
|
67
83
|
this.wsServer = this.createWsServer(this.httpServer)
|
|
68
84
|
|
|
69
85
|
this.wsServer.on('request', (request) => {
|
|
70
|
-
if (!originIsAllowed(
|
|
86
|
+
if (!originIsAllowed()) {
|
|
71
87
|
// Make sure we only accept requests from an allowed origin
|
|
72
88
|
request.reject()
|
|
73
89
|
logger.trace('IConnection from origin ' + request.origin + ' rejected.')
|
|
@@ -115,12 +131,14 @@ export class WebSocketServer extends EventEmitter<ConnectionSourceEvents> {
|
|
|
115
131
|
if (typeof NodeJsWsServer !== 'undefined') {
|
|
116
132
|
return new NodeJsWsServer({
|
|
117
133
|
httpServer,
|
|
118
|
-
autoAcceptConnections: false
|
|
134
|
+
autoAcceptConnections: false,
|
|
135
|
+
maxReceivedMessageSize: this.maxMessageSize
|
|
119
136
|
})
|
|
120
137
|
} else {
|
|
121
138
|
return this.wsServer = new WsServer({
|
|
122
139
|
httpServer,
|
|
123
|
-
autoAcceptConnections: false
|
|
140
|
+
autoAcceptConnections: false,
|
|
141
|
+
maxReceivedMessageSize: this.maxMessageSize
|
|
124
142
|
})
|
|
125
143
|
}
|
|
126
144
|
}
|