@webex/plugin-meetings 3.10.0-next.8 → 3.10.0-webex-services-ready.1
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/annotation/annotation.types.js.map +1 -1
- package/dist/annotation/constants.js.map +1 -1
- package/dist/annotation/index.js +19 -22
- package/dist/annotation/index.js.map +1 -1
- package/dist/breakouts/breakout.js +6 -6
- package/dist/breakouts/breakout.js.map +1 -1
- package/dist/breakouts/collection.js.map +1 -1
- package/dist/breakouts/edit-lock-error.js +9 -11
- package/dist/breakouts/edit-lock-error.js.map +1 -1
- package/dist/breakouts/events.js.map +1 -1
- package/dist/breakouts/index.js +126 -127
- package/dist/breakouts/index.js.map +1 -1
- package/dist/breakouts/request.js +6 -8
- package/dist/breakouts/request.js.map +1 -1
- package/dist/breakouts/utils.js.map +1 -1
- package/dist/common/browser-detection.js.map +1 -1
- package/dist/common/collection.js +1 -2
- package/dist/common/collection.js.map +1 -1
- package/dist/common/config.js.map +1 -1
- package/dist/common/errors/captcha-error.js +9 -11
- package/dist/common/errors/captcha-error.js.map +1 -1
- package/dist/common/errors/intent-to-join.js +10 -12
- package/dist/common/errors/intent-to-join.js.map +1 -1
- package/dist/common/errors/join-forbidden-error.js +10 -12
- package/dist/common/errors/join-forbidden-error.js.map +1 -1
- package/dist/common/errors/join-meeting.js +10 -12
- package/dist/common/errors/join-meeting.js.map +1 -1
- package/dist/common/errors/join-webinar-error.js +9 -11
- package/dist/common/errors/join-webinar-error.js.map +1 -1
- package/dist/common/errors/media.js +9 -11
- package/dist/common/errors/media.js.map +1 -1
- package/dist/common/errors/multistream-not-supported-error.js +9 -11
- package/dist/common/errors/multistream-not-supported-error.js.map +1 -1
- package/dist/common/errors/no-meeting-info.js +9 -11
- package/dist/common/errors/no-meeting-info.js.map +1 -1
- package/dist/common/errors/parameter.js +11 -14
- package/dist/common/errors/parameter.js.map +1 -1
- package/dist/common/errors/password-error.js +9 -11
- package/dist/common/errors/password-error.js.map +1 -1
- package/dist/common/errors/permission.js +9 -11
- package/dist/common/errors/permission.js.map +1 -1
- package/dist/common/errors/reclaim-host-role-errors.js +32 -38
- package/dist/common/errors/reclaim-host-role-errors.js.map +1 -1
- package/dist/common/errors/reconnection-not-started.js +5 -6
- package/dist/common/errors/reconnection-not-started.js.map +1 -1
- package/dist/common/errors/reconnection.js +9 -11
- package/dist/common/errors/reconnection.js.map +1 -1
- package/dist/common/errors/stats.js +9 -11
- package/dist/common/errors/stats.js.map +1 -1
- package/dist/common/errors/webex-errors.js +20 -29
- package/dist/common/errors/webex-errors.js.map +1 -1
- package/dist/common/errors/webex-meetings-error.js +9 -12
- package/dist/common/errors/webex-meetings-error.js.map +1 -1
- package/dist/common/events/events-scope.js +9 -10
- package/dist/common/events/events-scope.js.map +1 -1
- package/dist/common/events/events.js +9 -10
- package/dist/common/events/events.js.map +1 -1
- package/dist/common/events/trigger-proxy.js.map +1 -1
- package/dist/common/events/util.js.map +1 -1
- package/dist/common/logs/logger-config.js.map +1 -1
- package/dist/common/logs/logger-proxy.js.map +1 -1
- package/dist/common/logs/request.js +17 -17
- package/dist/common/logs/request.js.map +1 -1
- package/dist/common/queue.js +1 -2
- package/dist/common/queue.js.map +1 -1
- package/dist/config.js +0 -1
- package/dist/config.js.map +1 -1
- package/dist/constants.js +11 -8
- package/dist/constants.js.map +1 -1
- package/dist/controls-options-manager/constants.js.map +1 -1
- package/dist/controls-options-manager/enums.js.map +1 -1
- package/dist/controls-options-manager/index.js +1 -2
- package/dist/controls-options-manager/index.js.map +1 -1
- package/dist/controls-options-manager/types.js.map +1 -1
- package/dist/controls-options-manager/util.js +1 -2
- package/dist/controls-options-manager/util.js.map +1 -1
- package/dist/hashTree/constants.js +20 -0
- package/dist/hashTree/constants.js.map +1 -0
- package/dist/hashTree/hashTree.js +515 -0
- package/dist/hashTree/hashTree.js.map +1 -0
- package/dist/hashTree/hashTreeParser.js +1266 -0
- package/dist/hashTree/hashTreeParser.js.map +1 -0
- package/dist/hashTree/types.js +21 -0
- package/dist/hashTree/types.js.map +1 -0
- package/dist/hashTree/utils.js +48 -0
- package/dist/hashTree/utils.js.map +1 -0
- package/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/interceptors/index.js.map +1 -1
- package/dist/interceptors/locusRetry.js +6 -8
- package/dist/interceptors/locusRetry.js.map +1 -1
- package/dist/interceptors/locusRouteToken.js +6 -8
- package/dist/interceptors/locusRouteToken.js.map +1 -1
- package/dist/interpretation/collection.js.map +1 -1
- package/dist/interpretation/index.js +1 -2
- package/dist/interpretation/index.js.map +1 -1
- package/dist/interpretation/siLanguage.js +1 -1
- package/dist/interpretation/siLanguage.js.map +1 -1
- package/dist/locus-info/controlsUtils.js.map +1 -1
- package/dist/locus-info/embeddedAppsUtils.js.map +1 -1
- package/dist/locus-info/fullState.js.map +1 -1
- package/dist/locus-info/hostUtils.js.map +1 -1
- package/dist/locus-info/index.js +551 -94
- package/dist/locus-info/index.js.map +1 -1
- package/dist/locus-info/infoUtils.js.map +1 -1
- package/dist/locus-info/mediaSharesUtils.js.map +1 -1
- package/dist/locus-info/parser.js +3 -4
- package/dist/locus-info/parser.js.map +1 -1
- package/dist/locus-info/selfUtils.js.map +1 -1
- package/dist/locus-info/types.js +7 -0
- package/dist/locus-info/types.js.map +1 -0
- package/dist/media/MediaConnectionAwaiter.js +1 -2
- package/dist/media/MediaConnectionAwaiter.js.map +1 -1
- package/dist/media/index.js +0 -2
- package/dist/media/index.js.map +1 -1
- package/dist/media/properties.js +15 -17
- package/dist/media/properties.js.map +1 -1
- package/dist/media/util.js.map +1 -1
- package/dist/meeting/brbState.js +8 -9
- package/dist/meeting/brbState.js.map +1 -1
- package/dist/meeting/connectionStateHandler.js +10 -13
- package/dist/meeting/connectionStateHandler.js.map +1 -1
- package/dist/meeting/in-meeting-actions.js.map +1 -1
- package/dist/meeting/index.js +1555 -1527
- package/dist/meeting/index.js.map +1 -1
- package/dist/meeting/locusMediaRequest.js +13 -17
- package/dist/meeting/locusMediaRequest.js.map +1 -1
- package/dist/meeting/muteState.js +11 -12
- package/dist/meeting/muteState.js.map +1 -1
- package/dist/meeting/request.js +101 -104
- package/dist/meeting/request.js.map +1 -1
- package/dist/meeting/request.type.js.map +1 -1
- package/dist/meeting/state.js.map +1 -1
- package/dist/meeting/type.js.map +1 -1
- package/dist/meeting/util.js +24 -23
- package/dist/meeting/util.js.map +1 -1
- package/dist/meeting/voicea-meeting.js +3 -3
- package/dist/meeting/voicea-meeting.js.map +1 -1
- package/dist/meeting-info/collection.js +7 -10
- package/dist/meeting-info/collection.js.map +1 -1
- package/dist/meeting-info/index.js +1 -2
- package/dist/meeting-info/index.js.map +1 -1
- package/dist/meeting-info/meeting-info-v2.js +135 -146
- package/dist/meeting-info/meeting-info-v2.js.map +1 -1
- package/dist/meeting-info/request.js +1 -2
- package/dist/meeting-info/request.js.map +1 -1
- package/dist/meeting-info/util.js +36 -37
- package/dist/meeting-info/util.js.map +1 -1
- package/dist/meeting-info/utilv2.js +30 -31
- package/dist/meeting-info/utilv2.js.map +1 -1
- package/dist/meetings/collection.js +6 -8
- package/dist/meetings/collection.js.map +1 -1
- package/dist/meetings/index.js +179 -141
- package/dist/meetings/index.js.map +1 -1
- package/dist/meetings/meetings.types.js.map +1 -1
- package/dist/meetings/request.js +6 -8
- package/dist/meetings/request.js.map +1 -1
- package/dist/meetings/util.js +25 -23
- package/dist/meetings/util.js.map +1 -1
- package/dist/member/index.js +1 -2
- package/dist/member/index.js.map +1 -1
- package/dist/member/types.js +6 -3
- package/dist/member/types.js.map +1 -1
- package/dist/member/util.js.map +1 -1
- package/dist/members/collection.js +1 -2
- package/dist/members/collection.js.map +1 -1
- package/dist/members/index.js +18 -21
- package/dist/members/index.js.map +1 -1
- package/dist/members/request.js +8 -11
- package/dist/members/request.js.map +1 -1
- package/dist/members/types.js.map +1 -1
- package/dist/members/util.js.map +1 -1
- package/dist/metrics/constants.js +3 -1
- package/dist/metrics/constants.js.map +1 -1
- package/dist/metrics/index.js +3 -4
- package/dist/metrics/index.js.map +1 -1
- package/dist/multistream/mediaRequestManager.js +1 -2
- package/dist/multistream/mediaRequestManager.js.map +1 -1
- package/dist/multistream/receiveSlot.js +34 -45
- package/dist/multistream/receiveSlot.js.map +1 -1
- package/dist/multistream/receiveSlotManager.js +8 -9
- package/dist/multistream/receiveSlotManager.js.map +1 -1
- package/dist/multistream/remoteMedia.js +12 -15
- package/dist/multistream/remoteMedia.js.map +1 -1
- package/dist/multistream/remoteMediaGroup.js +1 -2
- package/dist/multistream/remoteMediaGroup.js.map +1 -1
- package/dist/multistream/remoteMediaManager.js +122 -123
- package/dist/multistream/remoteMediaManager.js.map +1 -1
- package/dist/multistream/sendSlotManager.js +29 -30
- package/dist/multistream/sendSlotManager.js.map +1 -1
- package/dist/personal-meeting-room/index.js +16 -19
- package/dist/personal-meeting-room/index.js.map +1 -1
- package/dist/personal-meeting-room/request.js +7 -10
- package/dist/personal-meeting-room/request.js.map +1 -1
- package/dist/personal-meeting-room/util.js.map +1 -1
- package/dist/reachability/clusterReachability.js +56 -373
- package/dist/reachability/clusterReachability.js.map +1 -1
- package/dist/reachability/index.js +203 -205
- package/dist/reachability/index.js.map +1 -1
- package/dist/reachability/reachability.types.js +14 -1
- package/dist/reachability/reachability.types.js.map +1 -1
- package/dist/reachability/reachabilityPeerConnection.js +445 -0
- package/dist/reachability/reachabilityPeerConnection.js.map +1 -0
- package/dist/reachability/request.js.map +1 -1
- package/dist/reachability/util.js.map +1 -1
- package/dist/reactions/constants.js.map +1 -1
- package/dist/reactions/reactions.js.map +1 -1
- package/dist/reactions/reactions.type.js.map +1 -1
- package/dist/reconnection-manager/index.js +178 -176
- package/dist/reconnection-manager/index.js.map +1 -1
- package/dist/recording-controller/enums.js.map +1 -1
- package/dist/recording-controller/index.js +1 -2
- package/dist/recording-controller/index.js.map +1 -1
- package/dist/recording-controller/util.js.map +1 -1
- package/dist/roap/index.js +12 -15
- package/dist/roap/index.js.map +1 -1
- package/dist/roap/request.js +24 -26
- package/dist/roap/request.js.map +1 -1
- package/dist/roap/turnDiscovery.js +75 -76
- package/dist/roap/turnDiscovery.js.map +1 -1
- package/dist/roap/types.js.map +1 -1
- package/dist/transcription/index.js +4 -5
- package/dist/transcription/index.js.map +1 -1
- package/dist/types/constants.d.ts +26 -21
- package/dist/types/hashTree/constants.d.ts +8 -0
- package/dist/types/hashTree/hashTree.d.ts +129 -0
- package/dist/types/hashTree/hashTreeParser.d.ts +260 -0
- package/dist/types/hashTree/types.d.ts +25 -0
- package/dist/types/hashTree/utils.d.ts +9 -0
- package/dist/types/locus-info/index.d.ts +91 -42
- package/dist/types/locus-info/types.d.ts +46 -0
- package/dist/types/meeting/index.d.ts +22 -9
- package/dist/types/meetings/index.d.ts +9 -2
- package/dist/types/metrics/constants.d.ts +2 -0
- package/dist/types/reachability/clusterReachability.d.ts +10 -88
- package/dist/types/reachability/reachability.types.d.ts +12 -1
- package/dist/types/reachability/reachabilityPeerConnection.d.ts +111 -0
- package/dist/webinar/collection.js +1 -2
- package/dist/webinar/collection.js.map +1 -1
- package/dist/webinar/index.js +148 -158
- package/dist/webinar/index.js.map +1 -1
- package/package.json +22 -21
- package/src/constants.ts +13 -1
- package/src/hashTree/constants.ts +9 -0
- package/src/hashTree/hashTree.ts +463 -0
- package/src/hashTree/hashTreeParser.ts +1161 -0
- package/src/hashTree/types.ts +30 -0
- package/src/hashTree/utils.ts +42 -0
- package/src/locus-info/index.ts +556 -85
- package/src/locus-info/types.ts +48 -0
- package/src/meeting/index.ts +58 -26
- package/src/meeting/util.ts +1 -0
- package/src/meetings/index.ts +104 -51
- package/src/metrics/constants.ts +2 -0
- package/src/reachability/clusterReachability.ts +50 -347
- package/src/reachability/reachability.types.ts +15 -1
- package/src/reachability/reachabilityPeerConnection.ts +416 -0
- package/test/unit/spec/hashTree/hashTree.ts +655 -0
- package/test/unit/spec/hashTree/hashTreeParser.ts +1532 -0
- package/test/unit/spec/hashTree/utils.ts +103 -0
- package/test/unit/spec/locus-info/index.js +667 -1
- package/test/unit/spec/meeting/index.js +91 -20
- package/test/unit/spec/meeting/utils.js +77 -0
- package/test/unit/spec/meetings/index.js +71 -26
- package/test/unit/spec/reachability/clusterReachability.ts +281 -138
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
var _Reflect$construct = require("@babel/runtime-corejs2/core-js/reflect/construct");
|
|
4
|
-
var _Object$keys = require("@babel/runtime-corejs2/core-js/object/keys");
|
|
5
|
-
var _Object$getOwnPropertySymbols = require("@babel/runtime-corejs2/core-js/object/get-own-property-symbols");
|
|
6
|
-
var _Object$getOwnPropertyDescriptor = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptor");
|
|
7
|
-
var _Object$getOwnPropertyDescriptors = require("@babel/runtime-corejs2/core-js/object/get-own-property-descriptors");
|
|
8
|
-
var _Object$defineProperties = require("@babel/runtime-corejs2/core-js/object/define-properties");
|
|
9
4
|
var _Object$defineProperty = require("@babel/runtime-corejs2/core-js/object/define-property");
|
|
10
5
|
var _interopRequireDefault = require("@babel/runtime-corejs2/helpers/interopRequireDefault");
|
|
11
6
|
_Object$defineProperty(exports, "__esModule", {
|
|
@@ -14,27 +9,18 @@ _Object$defineProperty(exports, "__esModule", {
|
|
|
14
9
|
exports.Events = exports.ClusterReachability = void 0;
|
|
15
10
|
var _regenerator = _interopRequireDefault(require("@babel/runtime-corejs2/regenerator"));
|
|
16
11
|
var _set = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/set"));
|
|
17
|
-
var _entries = _interopRequireDefault(require("@babel/runtime-corejs2/core-js/object/entries"));
|
|
18
12
|
var _asyncToGenerator2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/asyncToGenerator"));
|
|
19
|
-
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/slicedToArray"));
|
|
20
|
-
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/toConsumableArray"));
|
|
21
13
|
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/classCallCheck"));
|
|
22
14
|
var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/createClass"));
|
|
23
|
-
var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/assertThisInitialized"));
|
|
24
|
-
var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inherits"));
|
|
25
15
|
var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/possibleConstructorReturn"));
|
|
26
16
|
var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/getPrototypeOf"));
|
|
17
|
+
var _inherits2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/inherits"));
|
|
27
18
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime-corejs2/helpers/defineProperty"));
|
|
28
|
-
var _common = require("@webex/common");
|
|
29
|
-
var _loggerProxy = _interopRequireDefault(require("../common/logs/logger-proxy"));
|
|
30
|
-
var _util = require("./util");
|
|
31
19
|
var _eventsScope = _interopRequireDefault(require("../common/events/events-scope"));
|
|
32
|
-
var _constants = require("../constants");
|
|
33
20
|
var _reachability = require("./reachability.types");
|
|
34
|
-
|
|
35
|
-
function
|
|
36
|
-
function
|
|
37
|
-
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !_Reflect$construct) return false; if (_Reflect$construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
|
|
21
|
+
var _reachabilityPeerConnection = require("./reachabilityPeerConnection");
|
|
22
|
+
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? _Reflect$construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
|
|
23
|
+
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(_Reflect$construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
38
24
|
// data for the Events.resultReady event
|
|
39
25
|
|
|
40
26
|
// data for the Events.clientMediaIpsUpdated event
|
|
@@ -48,11 +34,10 @@ var Events = exports.Events = {
|
|
|
48
34
|
};
|
|
49
35
|
/**
|
|
50
36
|
* A class that handles reachability checks for a single cluster.
|
|
51
|
-
*
|
|
37
|
+
* Creates and orchestrates a ReachabilityPeerConnection instance.
|
|
38
|
+
* Listens to events and emits them to consumers.
|
|
52
39
|
*/
|
|
53
40
|
var ClusterReachability = exports.ClusterReachability = /*#__PURE__*/function (_EventsScope) {
|
|
54
|
-
(0, _inherits2.default)(ClusterReachability, _EventsScope);
|
|
55
|
-
var _super = _createSuper(ClusterReachability);
|
|
56
41
|
/**
|
|
57
42
|
* Constructor for ClusterReachability
|
|
58
43
|
* @param {string} name cluster name
|
|
@@ -61,106 +46,50 @@ var ClusterReachability = exports.ClusterReachability = /*#__PURE__*/function (_
|
|
|
61
46
|
function ClusterReachability(name, clusterInfo) {
|
|
62
47
|
var _this;
|
|
63
48
|
(0, _classCallCheck2.default)(this, ClusterReachability);
|
|
64
|
-
_this =
|
|
65
|
-
(0, _defineProperty2.default)(
|
|
66
|
-
(0, _defineProperty2.default)(
|
|
67
|
-
(0, _defineProperty2.default)(
|
|
68
|
-
(0, _defineProperty2.default)(
|
|
69
|
-
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "pc", void 0);
|
|
70
|
-
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "defer", void 0);
|
|
71
|
-
// this defer is resolved once reachability checks for this cluster are completed
|
|
72
|
-
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "startTimestamp", void 0);
|
|
73
|
-
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "srflxIceCandidates", []);
|
|
74
|
-
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "isVideoMesh", void 0);
|
|
75
|
-
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "name", void 0);
|
|
76
|
-
(0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "reachedSubnets", new _set.default());
|
|
49
|
+
_this = _callSuper(this, ClusterReachability);
|
|
50
|
+
(0, _defineProperty2.default)(_this, "reachabilityPeerConnection", void 0);
|
|
51
|
+
(0, _defineProperty2.default)(_this, "isVideoMesh", void 0);
|
|
52
|
+
(0, _defineProperty2.default)(_this, "name", void 0);
|
|
53
|
+
(0, _defineProperty2.default)(_this, "reachedSubnets", new _set.default());
|
|
77
54
|
_this.name = name;
|
|
78
55
|
_this.isVideoMesh = clusterInfo.isVideoMesh;
|
|
79
|
-
_this.
|
|
80
|
-
_this.
|
|
81
|
-
_this.numXTlsUrls = clusterInfo.xtls.length;
|
|
82
|
-
_this.pc = _this.createPeerConnection(clusterInfo);
|
|
83
|
-
_this.defer = new _common.Defer();
|
|
84
|
-
_this.result = {
|
|
85
|
-
udp: {
|
|
86
|
-
result: 'untested'
|
|
87
|
-
},
|
|
88
|
-
tcp: {
|
|
89
|
-
result: 'untested'
|
|
90
|
-
},
|
|
91
|
-
xtls: {
|
|
92
|
-
result: 'untested'
|
|
93
|
-
}
|
|
94
|
-
};
|
|
56
|
+
_this.reachabilityPeerConnection = new _reachabilityPeerConnection.ReachabilityPeerConnection(name, clusterInfo);
|
|
57
|
+
_this.setupReachabilityPeerConnectionEventListeners();
|
|
95
58
|
return _this;
|
|
96
59
|
}
|
|
97
60
|
|
|
98
61
|
/**
|
|
99
|
-
*
|
|
100
|
-
* @returns {
|
|
62
|
+
* Sets up event listeners for the ReachabilityPeerConnection instance
|
|
63
|
+
* @returns {void}
|
|
101
64
|
*/
|
|
102
|
-
(0,
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
*/
|
|
113
|
-
}, {
|
|
114
|
-
key: "buildPeerConnectionConfig",
|
|
115
|
-
value: function buildPeerConnectionConfig(cluster) {
|
|
116
|
-
var udpIceServers = cluster.udp.map(function (url) {
|
|
117
|
-
return {
|
|
118
|
-
username: '',
|
|
119
|
-
credential: '',
|
|
120
|
-
urls: [url]
|
|
121
|
-
};
|
|
65
|
+
(0, _inherits2.default)(ClusterReachability, _EventsScope);
|
|
66
|
+
return (0, _createClass2.default)(ClusterReachability, [{
|
|
67
|
+
key: "setupReachabilityPeerConnectionEventListeners",
|
|
68
|
+
value: function setupReachabilityPeerConnectionEventListeners() {
|
|
69
|
+
var _this2 = this;
|
|
70
|
+
this.reachabilityPeerConnection.on(_reachability.ReachabilityPeerConnectionEvents.resultReady, function (data) {
|
|
71
|
+
_this2.emit({
|
|
72
|
+
file: 'clusterReachability',
|
|
73
|
+
function: 'setupReachabilityPeerConnectionEventListeners'
|
|
74
|
+
}, Events.resultReady, data);
|
|
122
75
|
});
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
return {
|
|
129
|
-
username: 'webexturnreachuser',
|
|
130
|
-
credential: 'webexturnreachpwd',
|
|
131
|
-
urls: [(0, _util.convertStunUrlToTurn)(urlString, 'tcp')]
|
|
132
|
-
};
|
|
76
|
+
this.reachabilityPeerConnection.on(_reachability.ReachabilityPeerConnectionEvents.clientMediaIpsUpdated, function (data) {
|
|
77
|
+
_this2.emit({
|
|
78
|
+
file: 'clusterReachability',
|
|
79
|
+
function: 'setupReachabilityPeerConnectionEventListeners'
|
|
80
|
+
}, Events.clientMediaIpsUpdated, data);
|
|
133
81
|
});
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
82
|
+
this.reachabilityPeerConnection.on(_reachability.ReachabilityPeerConnectionEvents.natTypeUpdated, function (data) {
|
|
83
|
+
_this2.emit({
|
|
84
|
+
file: 'clusterReachability',
|
|
85
|
+
function: 'setupReachabilityPeerConnectionEventListeners'
|
|
86
|
+
}, Events.natTypeUpdated, data);
|
|
87
|
+
});
|
|
88
|
+
this.reachabilityPeerConnection.on(_reachability.ReachabilityPeerConnectionEvents.reachedSubnets, function (data) {
|
|
89
|
+
data.subnets.forEach(function (subnet) {
|
|
90
|
+
_this2.reachedSubnets.add(subnet);
|
|
91
|
+
});
|
|
140
92
|
});
|
|
141
|
-
return {
|
|
142
|
-
iceServers: [].concat((0, _toConsumableArray2.default)(udpIceServers), (0, _toConsumableArray2.default)(tcpIceServers), (0, _toConsumableArray2.default)(turnTlsIceServers)),
|
|
143
|
-
iceCandidatePoolSize: 0,
|
|
144
|
-
iceTransportPolicy: 'all'
|
|
145
|
-
};
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* Creates an RTCPeerConnection
|
|
150
|
-
* @param {ClusterNode} clusterInfo information about the media cluster
|
|
151
|
-
* @returns {RTCPeerConnection} peerConnection
|
|
152
|
-
*/
|
|
153
|
-
}, {
|
|
154
|
-
key: "createPeerConnection",
|
|
155
|
-
value: function createPeerConnection(clusterInfo) {
|
|
156
|
-
try {
|
|
157
|
-
var config = this.buildPeerConnectionConfig(clusterInfo);
|
|
158
|
-
var peerConnection = new RTCPeerConnection(config);
|
|
159
|
-
return peerConnection;
|
|
160
|
-
} catch (peerConnectionError) {
|
|
161
|
-
_loggerProxy.default.logger.warn("Reachability:index#createPeerConnection --> Error creating peerConnection:", peerConnectionError);
|
|
162
|
-
return undefined;
|
|
163
|
-
}
|
|
164
93
|
}
|
|
165
94
|
|
|
166
95
|
/**
|
|
@@ -169,271 +98,29 @@ var ClusterReachability = exports.ClusterReachability = /*#__PURE__*/function (_
|
|
|
169
98
|
}, {
|
|
170
99
|
key: "getResult",
|
|
171
100
|
value: function getResult() {
|
|
172
|
-
return this.
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Closes the peerConnection
|
|
177
|
-
*
|
|
178
|
-
* @returns {void}
|
|
179
|
-
*/
|
|
180
|
-
}, {
|
|
181
|
-
key: "closePeerConnection",
|
|
182
|
-
value: function closePeerConnection() {
|
|
183
|
-
if (this.pc) {
|
|
184
|
-
this.pc.onicecandidate = null;
|
|
185
|
-
this.pc.onicegatheringstatechange = null;
|
|
186
|
-
this.pc.close();
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* Resolves the defer, indicating that reachability checks for this cluster are completed
|
|
192
|
-
*
|
|
193
|
-
* @returns {void}
|
|
194
|
-
*/
|
|
195
|
-
}, {
|
|
196
|
-
key: "finishReachabilityCheck",
|
|
197
|
-
value: function finishReachabilityCheck() {
|
|
198
|
-
this.defer.resolve();
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Aborts the cluster reachability checks by closing the peer connection
|
|
203
|
-
*
|
|
204
|
-
* @returns {void}
|
|
205
|
-
*/
|
|
206
|
-
}, {
|
|
207
|
-
key: "abort",
|
|
208
|
-
value: function abort() {
|
|
209
|
-
var CLOSED = _constants.CONNECTION_STATE.CLOSED;
|
|
210
|
-
if (this.pc.connectionState !== CLOSED) {
|
|
211
|
-
this.closePeerConnection();
|
|
212
|
-
this.finishReachabilityCheck();
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/**
|
|
217
|
-
* Adds public IP (client media IPs)
|
|
218
|
-
* @param {string} protocol
|
|
219
|
-
* @param {string} publicIP
|
|
220
|
-
* @returns {void}
|
|
221
|
-
*/
|
|
222
|
-
}, {
|
|
223
|
-
key: "addPublicIP",
|
|
224
|
-
value: function addPublicIP(protocol, publicIP) {
|
|
225
|
-
var result = this.result[protocol];
|
|
226
|
-
if (publicIP) {
|
|
227
|
-
var ipAdded = false;
|
|
228
|
-
if (result.clientMediaIPs) {
|
|
229
|
-
if (!result.clientMediaIPs.includes(publicIP)) {
|
|
230
|
-
result.clientMediaIPs.push(publicIP);
|
|
231
|
-
ipAdded = true;
|
|
232
|
-
}
|
|
233
|
-
} else {
|
|
234
|
-
result.clientMediaIPs = [publicIP];
|
|
235
|
-
ipAdded = true;
|
|
236
|
-
}
|
|
237
|
-
if (ipAdded) this.emit({
|
|
238
|
-
file: 'clusterReachability',
|
|
239
|
-
function: 'addPublicIP'
|
|
240
|
-
}, Events.clientMediaIpsUpdated, {
|
|
241
|
-
protocol: protocol,
|
|
242
|
-
clientMediaIPs: result.clientMediaIPs
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* Registers a listener for the iceGatheringStateChange event
|
|
249
|
-
*
|
|
250
|
-
* @returns {void}
|
|
251
|
-
*/
|
|
252
|
-
}, {
|
|
253
|
-
key: "registerIceGatheringStateChangeListener",
|
|
254
|
-
value: function registerIceGatheringStateChangeListener() {
|
|
255
|
-
var _this2 = this;
|
|
256
|
-
this.pc.onicegatheringstatechange = function () {
|
|
257
|
-
if (_this2.pc.iceGatheringState === _constants.ICE_GATHERING_STATE.COMPLETE) {
|
|
258
|
-
_this2.closePeerConnection();
|
|
259
|
-
_this2.finishReachabilityCheck();
|
|
260
|
-
}
|
|
261
|
-
};
|
|
101
|
+
return this.reachabilityPeerConnection.getResult();
|
|
262
102
|
}
|
|
263
103
|
|
|
264
104
|
/**
|
|
265
|
-
*
|
|
266
|
-
*
|
|
267
|
-
* emits the "clientMediaIpsUpdated" event if we already had a result and only found
|
|
268
|
-
* a new client IP
|
|
269
|
-
*
|
|
270
|
-
* @param {string} protocol
|
|
271
|
-
* @param {number} latency
|
|
272
|
-
* @param {string|null} [publicIp]
|
|
273
|
-
* @param {string|null} [serverIp]
|
|
274
|
-
* @returns {void}
|
|
275
|
-
*/
|
|
276
|
-
}, {
|
|
277
|
-
key: "saveResult",
|
|
278
|
-
value: function saveResult(protocol, latency, publicIp, serverIp) {
|
|
279
|
-
var result = this.result[protocol];
|
|
280
|
-
if (result.latencyInMilliseconds === undefined) {
|
|
281
|
-
_loggerProxy.default.logger.log( // @ts-ignore
|
|
282
|
-
"Reachability:index#saveResult --> Successfully reached ".concat(this.name, " over ").concat(protocol, ": ").concat(latency, "ms"));
|
|
283
|
-
result.latencyInMilliseconds = latency;
|
|
284
|
-
result.result = 'reachable';
|
|
285
|
-
if (publicIp) {
|
|
286
|
-
result.clientMediaIPs = [publicIp];
|
|
287
|
-
}
|
|
288
|
-
this.emit({
|
|
289
|
-
file: 'clusterReachability',
|
|
290
|
-
function: 'saveResult'
|
|
291
|
-
}, Events.resultReady, _objectSpread({
|
|
292
|
-
protocol: protocol
|
|
293
|
-
}, result));
|
|
294
|
-
} else {
|
|
295
|
-
this.addPublicIP(protocol, publicIp);
|
|
296
|
-
}
|
|
297
|
-
if (serverIp) {
|
|
298
|
-
this.reachedSubnets.add(serverIp);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* Determines NAT Type.
|
|
304
|
-
*
|
|
305
|
-
* @param {RTCIceCandidate} candidate
|
|
306
|
-
* @returns {void}
|
|
307
|
-
*/
|
|
308
|
-
}, {
|
|
309
|
-
key: "determineNatType",
|
|
310
|
-
value: function determineNatType(candidate) {
|
|
311
|
-
var _this3 = this;
|
|
312
|
-
this.srflxIceCandidates.push(candidate);
|
|
313
|
-
if (this.srflxIceCandidates.length > 1) {
|
|
314
|
-
var portsFound = {};
|
|
315
|
-
this.srflxIceCandidates.forEach(function (c) {
|
|
316
|
-
var key = "".concat(c.address, ":").concat(c.relatedPort);
|
|
317
|
-
if (!portsFound[key]) {
|
|
318
|
-
portsFound[key] = new _set.default();
|
|
319
|
-
}
|
|
320
|
-
portsFound[key].add(c.port);
|
|
321
|
-
});
|
|
322
|
-
(0, _entries.default)(portsFound).forEach(function (_ref) {
|
|
323
|
-
var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
|
|
324
|
-
ports = _ref2[1];
|
|
325
|
-
if (ports.size > 1) {
|
|
326
|
-
// Found candidates with the same address and relatedPort, but different ports
|
|
327
|
-
_this3.emit({
|
|
328
|
-
file: 'clusterReachability',
|
|
329
|
-
function: 'determineNatType'
|
|
330
|
-
}, Events.natTypeUpdated, {
|
|
331
|
-
natType: _reachability.NatType.SymmetricNat
|
|
332
|
-
});
|
|
333
|
-
}
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
/**
|
|
339
|
-
* Registers a listener for the icecandidate event
|
|
340
|
-
*
|
|
341
|
-
* @returns {void}
|
|
342
|
-
*/
|
|
343
|
-
}, {
|
|
344
|
-
key: "registerIceCandidateListener",
|
|
345
|
-
value: function registerIceCandidateListener() {
|
|
346
|
-
var _this4 = this;
|
|
347
|
-
this.pc.onicecandidate = function (e) {
|
|
348
|
-
var TURN_TLS_PORT = 443;
|
|
349
|
-
var CANDIDATE_TYPES = {
|
|
350
|
-
SERVER_REFLEXIVE: 'srflx',
|
|
351
|
-
RELAY: 'relay'
|
|
352
|
-
};
|
|
353
|
-
var latencyInMilliseconds = _this4.getElapsedTime();
|
|
354
|
-
if (e.candidate) {
|
|
355
|
-
if (e.candidate.type === CANDIDATE_TYPES.SERVER_REFLEXIVE) {
|
|
356
|
-
var serverIp = null;
|
|
357
|
-
if ('url' in e.candidate) {
|
|
358
|
-
var stunServerUrlRegex = /stun:([\d.]+):\d+/;
|
|
359
|
-
var match = e.candidate.url.match(stunServerUrlRegex);
|
|
360
|
-
if (match) {
|
|
361
|
-
// eslint-disable-next-line prefer-destructuring
|
|
362
|
-
serverIp = match[1];
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
_this4.saveResult('udp', latencyInMilliseconds, e.candidate.address, serverIp);
|
|
366
|
-
_this4.determineNatType(e.candidate);
|
|
367
|
-
}
|
|
368
|
-
if (e.candidate.type === CANDIDATE_TYPES.RELAY) {
|
|
369
|
-
var protocol = e.candidate.port === TURN_TLS_PORT ? 'xtls' : 'tcp';
|
|
370
|
-
_this4.saveResult(protocol, latencyInMilliseconds, null, e.candidate.address);
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
};
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
/**
|
|
377
|
-
* Starts the process of doing UDP and TCP reachability checks on the media cluster.
|
|
378
|
-
* XTLS reachability checking is not supported.
|
|
379
|
-
*
|
|
380
|
-
* @returns {Promise}
|
|
105
|
+
* Starts the process of doing UDP, TCP, and XTLS reachability checks on the media cluster.
|
|
106
|
+
* @returns {Promise<ClusterReachabilityResult>}
|
|
381
107
|
*/
|
|
382
108
|
}, {
|
|
383
109
|
key: "start",
|
|
384
110
|
value: (function () {
|
|
385
|
-
var _start = (0, _asyncToGenerator2.default)(
|
|
386
|
-
|
|
387
|
-
return _regenerator.default.wrap(function _callee$(_context) {
|
|
111
|
+
var _start = (0, _asyncToGenerator2.default)(/*#__PURE__*/_regenerator.default.mark(function _callee() {
|
|
112
|
+
return _regenerator.default.wrap(function (_context) {
|
|
388
113
|
while (1) switch (_context.prev = _context.next) {
|
|
389
114
|
case 0:
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
return _context.abrupt("return", this.result);
|
|
396
|
-
case 3:
|
|
397
|
-
// Initialize this.result as saying that nothing is reachable.
|
|
398
|
-
// It will get updated as we go along and successfully gather ICE candidates.
|
|
399
|
-
this.result.udp = {
|
|
400
|
-
result: this.numUdpUrls > 0 ? 'unreachable' : 'untested'
|
|
401
|
-
};
|
|
402
|
-
this.result.tcp = {
|
|
403
|
-
result: this.numTcpUrls > 0 ? 'unreachable' : 'untested'
|
|
404
|
-
};
|
|
405
|
-
this.result.xtls = {
|
|
406
|
-
result: this.numXTlsUrls > 0 ? 'unreachable' : 'untested'
|
|
407
|
-
};
|
|
408
|
-
_context.prev = 6;
|
|
409
|
-
_context.next = 9;
|
|
410
|
-
return this.pc.createOffer({
|
|
411
|
-
offerToReceiveAudio: true
|
|
412
|
-
});
|
|
413
|
-
case 9:
|
|
414
|
-
offer = _context.sent;
|
|
415
|
-
this.startTimestamp = performance.now();
|
|
416
|
-
|
|
417
|
-
// Set up the state change listeners before triggering the ICE gathering
|
|
418
|
-
gatherIceCandidatePromise = this.gatherIceCandidates(); // not awaiting the next call on purpose, because we're not sending the offer anywhere and there won't be any answer
|
|
419
|
-
// we just need to make this call to trigger the ICE gathering process
|
|
420
|
-
this.pc.setLocalDescription(offer);
|
|
421
|
-
_context.next = 15;
|
|
422
|
-
return gatherIceCandidatePromise;
|
|
423
|
-
case 15:
|
|
424
|
-
_context.next = 20;
|
|
425
|
-
break;
|
|
426
|
-
case 17:
|
|
427
|
-
_context.prev = 17;
|
|
428
|
-
_context.t0 = _context["catch"](6);
|
|
429
|
-
_loggerProxy.default.logger.warn("Reachability:ClusterReachability#start --> Error: ", _context.t0);
|
|
430
|
-
case 20:
|
|
431
|
-
return _context.abrupt("return", this.result);
|
|
432
|
-
case 21:
|
|
115
|
+
_context.next = 1;
|
|
116
|
+
return this.reachabilityPeerConnection.start();
|
|
117
|
+
case 1:
|
|
118
|
+
return _context.abrupt("return", this.getResult());
|
|
119
|
+
case 2:
|
|
433
120
|
case "end":
|
|
434
121
|
return _context.stop();
|
|
435
122
|
}
|
|
436
|
-
}, _callee, this
|
|
123
|
+
}, _callee, this);
|
|
437
124
|
}));
|
|
438
125
|
function start() {
|
|
439
126
|
return _start.apply(this, arguments);
|
|
@@ -441,19 +128,15 @@ var ClusterReachability = exports.ClusterReachability = /*#__PURE__*/function (_
|
|
|
441
128
|
return start;
|
|
442
129
|
}()
|
|
443
130
|
/**
|
|
444
|
-
*
|
|
445
|
-
*
|
|
446
|
-
* @returns {Promise} promise that's resolved once reachability checks for this cluster are completed or timeout is reached
|
|
131
|
+
* Aborts the cluster reachability checks
|
|
132
|
+
* @returns {void}
|
|
447
133
|
*/
|
|
448
134
|
)
|
|
449
135
|
}, {
|
|
450
|
-
key: "
|
|
451
|
-
value: function
|
|
452
|
-
this.
|
|
453
|
-
this.registerIceCandidateListener();
|
|
454
|
-
return this.defer.promise;
|
|
136
|
+
key: "abort",
|
|
137
|
+
value: function abort() {
|
|
138
|
+
this.reachabilityPeerConnection.abort();
|
|
455
139
|
}
|
|
456
140
|
}]);
|
|
457
|
-
return ClusterReachability;
|
|
458
141
|
}(_eventsScope.default);
|
|
459
142
|
//# sourceMappingURL=clusterReachability.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["_common","require","_loggerProxy","_interopRequireDefault","_util","_eventsScope","_constants","_reachability","ownKeys","e","r","t","_Object$keys","_Object$getOwnPropertySymbols","o","filter","_Object$getOwnPropertyDescriptor","enumerable","push","apply","_objectSpread","arguments","length","Object","forEach","_defineProperty2","default","_Object$getOwnPropertyDescriptors","_Object$defineProperties","_Object$defineProperty","_createSuper","Derived","hasNativeReflectConstruct","_isNativeReflectConstruct","_createSuperInternal","Super","_getPrototypeOf2","result","NewTarget","constructor","_Reflect$construct","_possibleConstructorReturn2","Reflect","sham","Proxy","Boolean","prototype","valueOf","call","Events","exports","resultReady","clientMediaIpsUpdated","natTypeUpdated","ClusterReachability","_EventsScope","_inherits2","_super","name","clusterInfo","_this","_classCallCheck2","_assertThisInitialized2","_set","isVideoMesh","numUdpUrls","udp","numTcpUrls","tcp","numXTlsUrls","xtls","pc","createPeerConnection","defer","Defer","_createClass2","key","value","getElapsedTime","Math","round","performance","now","startTimestamp","buildPeerConnectionConfig","cluster","udpIceServers","map","url","username","credential","urls","tcpIceServers","urlString","convertStunUrlToTurn","turnTlsIceServers","convertStunUrlToTurnTls","iceServers","concat","_toConsumableArray2","iceCandidatePoolSize","iceTransportPolicy","config","peerConnection","RTCPeerConnection","peerConnectionError","LoggerProxy","logger","warn","undefined","getResult","closePeerConnection","onicecandidate","onicegatheringstatechange","close","finishReachabilityCheck","resolve","abort","CLOSED","CONNECTION_STATE","connectionState","addPublicIP","protocol","publicIP","ipAdded","clientMediaIPs","includes","emit","file","function","registerIceGatheringStateChangeListener","_this2","iceGatheringState","ICE_GATHERING_STATE","COMPLETE","saveResult","latency","publicIp","serverIp","latencyInMilliseconds","log","reachedSubnets","add","determineNatType","candidate","_this3","srflxIceCandidates","portsFound","c","address","relatedPort","port","_entries","_ref","_ref2","_slicedToArray2","ports","size","natType","NatType","SymmetricNat","registerIceCandidateListener","_this4","TURN_TLS_PORT","CANDIDATE_TYPES","SERVER_REFLEXIVE","RELAY","type","stunServerUrlRegex","match","_start","_asyncToGenerator2","_regenerator","mark","_callee","offer","gatherIceCandidatePromise","wrap","_callee$","_context","prev","next","abrupt","createOffer","offerToReceiveAudio","sent","gatherIceCandidates","setLocalDescription","t0","stop","start","promise","EventsScope"],"sources":["clusterReachability.ts"],"sourcesContent":["import {Defer} from '@webex/common';\n\nimport LoggerProxy from '../common/logs/logger-proxy';\nimport {ClusterNode} from './request';\nimport {convertStunUrlToTurn, convertStunUrlToTurnTls} from './util';\nimport EventsScope from '../common/events/events-scope';\n\nimport {CONNECTION_STATE, Enum, ICE_GATHERING_STATE} from '../constants';\nimport {ClusterReachabilityResult, NatType} from './reachability.types';\n\n// data for the Events.resultReady event\nexport type ResultEventData = {\n protocol: 'udp' | 'tcp' | 'xtls';\n result: 'reachable' | 'unreachable' | 'untested';\n latencyInMilliseconds: number; // amount of time it took to get the ICE candidate\n clientMediaIPs?: string[];\n};\n\n// data for the Events.clientMediaIpsUpdated event\nexport type ClientMediaIpsUpdatedEventData = {\n protocol: 'udp' | 'tcp' | 'xtls';\n clientMediaIPs: string[];\n};\n\nexport type NatTypeUpdatedEventData = {\n natType: NatType;\n};\n\nexport const Events = {\n resultReady: 'resultReady', // emitted when a cluster is reached successfully using specific protocol\n clientMediaIpsUpdated: 'clientMediaIpsUpdated', // emitted when more public IPs are found after resultReady was already sent for a given protocol\n natTypeUpdated: 'natTypeUpdated', // emitted when NAT type is determined\n} as const;\n\nexport type Events = Enum<typeof Events>;\n\n/**\n * A class that handles reachability checks for a single cluster.\n * It emits events from Events enum\n */\nexport class ClusterReachability extends EventsScope {\n private numUdpUrls: number;\n private numTcpUrls: number;\n private numXTlsUrls: number;\n private result: ClusterReachabilityResult;\n private pc?: RTCPeerConnection;\n private defer: Defer; // this defer is resolved once reachability checks for this cluster are completed\n private startTimestamp: number;\n private srflxIceCandidates: RTCIceCandidate[] = [];\n public readonly isVideoMesh: boolean;\n public readonly name;\n public readonly reachedSubnets: Set<string> = new Set();\n\n /**\n * Constructor for ClusterReachability\n * @param {string} name cluster name\n * @param {ClusterNode} clusterInfo information about the media cluster\n */\n constructor(name: string, clusterInfo: ClusterNode) {\n super();\n this.name = name;\n this.isVideoMesh = clusterInfo.isVideoMesh;\n this.numUdpUrls = clusterInfo.udp.length;\n this.numTcpUrls = clusterInfo.tcp.length;\n this.numXTlsUrls = clusterInfo.xtls.length;\n\n this.pc = this.createPeerConnection(clusterInfo);\n\n this.defer = new Defer();\n this.result = {\n udp: {\n result: 'untested',\n },\n tcp: {\n result: 'untested',\n },\n xtls: {\n result: 'untested',\n },\n };\n }\n\n /**\n * Gets total elapsed time, can be called only after start() is called\n * @returns {Number} Milliseconds\n */\n private getElapsedTime() {\n return Math.round(performance.now() - this.startTimestamp);\n }\n\n /**\n * Generate peerConnection config settings\n * @param {ClusterNode} cluster\n * @returns {RTCConfiguration} peerConnectionConfig\n */\n private buildPeerConnectionConfig(cluster: ClusterNode): RTCConfiguration {\n const udpIceServers = cluster.udp.map((url) => ({\n username: '',\n credential: '',\n urls: [url],\n }));\n\n // STUN servers are contacted only using UDP, so in order to test TCP reachability\n // we pretend that Linus is a TURN server, because we can explicitly say \"transport=tcp\" in TURN urls.\n // We then check for relay candidates to know if TURN-TCP worked (see registerIceCandidateListener()).\n const tcpIceServers = cluster.tcp.map((urlString: string) => {\n return {\n username: 'webexturnreachuser',\n credential: 'webexturnreachpwd',\n urls: [convertStunUrlToTurn(urlString, 'tcp')],\n };\n });\n\n const turnTlsIceServers = cluster.xtls.map((urlString: string) => {\n return {\n username: 'webexturnreachuser',\n credential: 'webexturnreachpwd',\n urls: [convertStunUrlToTurnTls(urlString)],\n };\n });\n\n return {\n iceServers: [...udpIceServers, ...tcpIceServers, ...turnTlsIceServers],\n iceCandidatePoolSize: 0,\n iceTransportPolicy: 'all',\n };\n }\n\n /**\n * Creates an RTCPeerConnection\n * @param {ClusterNode} clusterInfo information about the media cluster\n * @returns {RTCPeerConnection} peerConnection\n */\n private createPeerConnection(clusterInfo: ClusterNode) {\n try {\n const config = this.buildPeerConnectionConfig(clusterInfo);\n\n const peerConnection = new RTCPeerConnection(config);\n\n return peerConnection;\n } catch (peerConnectionError) {\n LoggerProxy.logger.warn(\n `Reachability:index#createPeerConnection --> Error creating peerConnection:`,\n peerConnectionError\n );\n\n return undefined;\n }\n }\n\n /**\n * @returns {ClusterReachabilityResult} reachability result for this cluster\n */\n getResult() {\n return this.result;\n }\n\n /**\n * Closes the peerConnection\n *\n * @returns {void}\n */\n private closePeerConnection() {\n if (this.pc) {\n this.pc.onicecandidate = null;\n this.pc.onicegatheringstatechange = null;\n this.pc.close();\n }\n }\n\n /**\n * Resolves the defer, indicating that reachability checks for this cluster are completed\n *\n * @returns {void}\n */\n private finishReachabilityCheck() {\n this.defer.resolve();\n }\n\n /**\n * Aborts the cluster reachability checks by closing the peer connection\n *\n * @returns {void}\n */\n public abort() {\n const {CLOSED} = CONNECTION_STATE;\n\n if (this.pc.connectionState !== CLOSED) {\n this.closePeerConnection();\n this.finishReachabilityCheck();\n }\n }\n\n /**\n * Adds public IP (client media IPs)\n * @param {string} protocol\n * @param {string} publicIP\n * @returns {void}\n */\n private addPublicIP(protocol: 'udp' | 'tcp' | 'xtls', publicIP?: string | null) {\n const result = this.result[protocol];\n\n if (publicIP) {\n let ipAdded = false;\n\n if (result.clientMediaIPs) {\n if (!result.clientMediaIPs.includes(publicIP)) {\n result.clientMediaIPs.push(publicIP);\n ipAdded = true;\n }\n } else {\n result.clientMediaIPs = [publicIP];\n ipAdded = true;\n }\n\n if (ipAdded)\n this.emit(\n {\n file: 'clusterReachability',\n function: 'addPublicIP',\n },\n Events.clientMediaIpsUpdated,\n {\n protocol,\n clientMediaIPs: result.clientMediaIPs,\n }\n );\n }\n }\n\n /**\n * Registers a listener for the iceGatheringStateChange event\n *\n * @returns {void}\n */\n private registerIceGatheringStateChangeListener() {\n this.pc.onicegatheringstatechange = () => {\n if (this.pc.iceGatheringState === ICE_GATHERING_STATE.COMPLETE) {\n this.closePeerConnection();\n this.finishReachabilityCheck();\n }\n };\n }\n\n /**\n * Saves the latency in the result for the given protocol and marks it as reachable,\n * emits the \"resultReady\" event if this is the first result for that protocol,\n * emits the \"clientMediaIpsUpdated\" event if we already had a result and only found\n * a new client IP\n *\n * @param {string} protocol\n * @param {number} latency\n * @param {string|null} [publicIp]\n * @param {string|null} [serverIp]\n * @returns {void}\n */\n private saveResult(\n protocol: 'udp' | 'tcp' | 'xtls',\n latency: number,\n publicIp?: string | null,\n serverIp?: string | null\n ) {\n const result = this.result[protocol];\n\n if (result.latencyInMilliseconds === undefined) {\n LoggerProxy.logger.log(\n // @ts-ignore\n `Reachability:index#saveResult --> Successfully reached ${this.name} over ${protocol}: ${latency}ms`\n );\n result.latencyInMilliseconds = latency;\n result.result = 'reachable';\n if (publicIp) {\n result.clientMediaIPs = [publicIp];\n }\n\n this.emit(\n {\n file: 'clusterReachability',\n function: 'saveResult',\n },\n Events.resultReady,\n {\n protocol,\n ...result,\n }\n );\n } else {\n this.addPublicIP(protocol, publicIp);\n }\n\n if (serverIp) {\n this.reachedSubnets.add(serverIp);\n }\n }\n\n /**\n * Determines NAT Type.\n *\n * @param {RTCIceCandidate} candidate\n * @returns {void}\n */\n private determineNatType(candidate: RTCIceCandidate) {\n this.srflxIceCandidates.push(candidate);\n\n if (this.srflxIceCandidates.length > 1) {\n const portsFound: Record<string, Set<number>> = {};\n\n this.srflxIceCandidates.forEach((c) => {\n const key = `${c.address}:${c.relatedPort}`;\n if (!portsFound[key]) {\n portsFound[key] = new Set();\n }\n portsFound[key].add(c.port);\n });\n\n Object.entries(portsFound).forEach(([, ports]) => {\n if (ports.size > 1) {\n // Found candidates with the same address and relatedPort, but different ports\n this.emit(\n {\n file: 'clusterReachability',\n function: 'determineNatType',\n },\n Events.natTypeUpdated,\n {\n natType: NatType.SymmetricNat,\n }\n );\n }\n });\n }\n }\n\n /**\n * Registers a listener for the icecandidate event\n *\n * @returns {void}\n */\n private registerIceCandidateListener() {\n this.pc.onicecandidate = (e) => {\n const TURN_TLS_PORT = 443;\n const CANDIDATE_TYPES = {\n SERVER_REFLEXIVE: 'srflx',\n RELAY: 'relay',\n };\n\n const latencyInMilliseconds = this.getElapsedTime();\n\n if (e.candidate) {\n if (e.candidate.type === CANDIDATE_TYPES.SERVER_REFLEXIVE) {\n let serverIp = null;\n if ('url' in e.candidate) {\n const stunServerUrlRegex = /stun:([\\d.]+):\\d+/;\n\n const match = (e.candidate as any).url.match(stunServerUrlRegex);\n if (match) {\n // eslint-disable-next-line prefer-destructuring\n serverIp = match[1];\n }\n }\n\n this.saveResult('udp', latencyInMilliseconds, e.candidate.address, serverIp);\n\n this.determineNatType(e.candidate);\n }\n\n if (e.candidate.type === CANDIDATE_TYPES.RELAY) {\n const protocol = e.candidate.port === TURN_TLS_PORT ? 'xtls' : 'tcp';\n this.saveResult(protocol, latencyInMilliseconds, null, e.candidate.address);\n }\n }\n };\n }\n\n /**\n * Starts the process of doing UDP and TCP reachability checks on the media cluster.\n * XTLS reachability checking is not supported.\n *\n * @returns {Promise}\n */\n async start(): Promise<ClusterReachabilityResult> {\n if (!this.pc) {\n LoggerProxy.logger.warn(\n `Reachability:ClusterReachability#start --> Error: peerConnection is undefined`\n );\n\n return this.result;\n }\n\n // Initialize this.result as saying that nothing is reachable.\n // It will get updated as we go along and successfully gather ICE candidates.\n this.result.udp = {\n result: this.numUdpUrls > 0 ? 'unreachable' : 'untested',\n };\n this.result.tcp = {\n result: this.numTcpUrls > 0 ? 'unreachable' : 'untested',\n };\n this.result.xtls = {\n result: this.numXTlsUrls > 0 ? 'unreachable' : 'untested',\n };\n\n try {\n const offer = await this.pc.createOffer({offerToReceiveAudio: true});\n\n this.startTimestamp = performance.now();\n\n // Set up the state change listeners before triggering the ICE gathering\n const gatherIceCandidatePromise = this.gatherIceCandidates();\n\n // not awaiting the next call on purpose, because we're not sending the offer anywhere and there won't be any answer\n // we just need to make this call to trigger the ICE gathering process\n this.pc.setLocalDescription(offer);\n\n await gatherIceCandidatePromise;\n } catch (error) {\n LoggerProxy.logger.warn(`Reachability:ClusterReachability#start --> Error: `, error);\n }\n\n return this.result;\n }\n\n /**\n * Starts the process of gathering ICE candidates\n *\n * @returns {Promise} promise that's resolved once reachability checks for this cluster are completed or timeout is reached\n */\n private gatherIceCandidates() {\n this.registerIceGatheringStateChangeListener();\n this.registerIceCandidateListener();\n\n return this.defer.promise;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"names":["_eventsScope","_interopRequireDefault","require","_reachability","_reachabilityPeerConnection","_callSuper","t","o","e","_getPrototypeOf2","default","_possibleConstructorReturn2","_isNativeReflectConstruct","_Reflect$construct","constructor","apply","Boolean","prototype","valueOf","call","Events","exports","resultReady","clientMediaIpsUpdated","natTypeUpdated","ClusterReachability","_EventsScope","name","clusterInfo","_this","_classCallCheck2","_defineProperty2","_set","isVideoMesh","reachabilityPeerConnection","ReachabilityPeerConnection","setupReachabilityPeerConnectionEventListeners","_inherits2","_createClass2","key","value","_this2","on","ReachabilityPeerConnectionEvents","data","emit","file","function","reachedSubnets","subnets","forEach","subnet","add","getResult","_start","_asyncToGenerator2","_regenerator","mark","_callee","wrap","_context","prev","next","start","abrupt","stop","arguments","abort","EventsScope"],"sources":["clusterReachability.ts"],"sourcesContent":["import {ClusterNode} from './request';\nimport EventsScope from '../common/events/events-scope';\n\nimport {Enum} from '../constants';\nimport {\n ClusterReachabilityResult,\n NatType,\n ReachabilityPeerConnectionEvents,\n} from './reachability.types';\nimport {ReachabilityPeerConnection} from './reachabilityPeerConnection';\n\n// data for the Events.resultReady event\nexport type ResultEventData = {\n protocol: 'udp' | 'tcp' | 'xtls';\n result: 'reachable' | 'unreachable' | 'untested';\n latencyInMilliseconds: number; // amount of time it took to get the ICE candidate\n clientMediaIPs?: string[];\n};\n\n// data for the Events.clientMediaIpsUpdated event\nexport type ClientMediaIpsUpdatedEventData = {\n protocol: 'udp' | 'tcp' | 'xtls';\n clientMediaIPs: string[];\n};\n\nexport type NatTypeUpdatedEventData = {\n natType: NatType;\n};\n\nexport const Events = {\n resultReady: 'resultReady', // emitted when a cluster is reached successfully using specific protocol\n clientMediaIpsUpdated: 'clientMediaIpsUpdated', // emitted when more public IPs are found after resultReady was already sent for a given protocol\n natTypeUpdated: 'natTypeUpdated', // emitted when NAT type is determined\n} as const;\n\nexport type Events = Enum<typeof Events>;\n\n/**\n * A class that handles reachability checks for a single cluster.\n * Creates and orchestrates a ReachabilityPeerConnection instance.\n * Listens to events and emits them to consumers.\n */\nexport class ClusterReachability extends EventsScope {\n private reachabilityPeerConnection: ReachabilityPeerConnection;\n public readonly isVideoMesh: boolean;\n public readonly name;\n public readonly reachedSubnets: Set<string> = new Set();\n\n /**\n * Constructor for ClusterReachability\n * @param {string} name cluster name\n * @param {ClusterNode} clusterInfo information about the media cluster\n */\n constructor(name: string, clusterInfo: ClusterNode) {\n super();\n this.name = name;\n this.isVideoMesh = clusterInfo.isVideoMesh;\n\n this.reachabilityPeerConnection = new ReachabilityPeerConnection(name, clusterInfo);\n\n this.setupReachabilityPeerConnectionEventListeners();\n }\n\n /**\n * Sets up event listeners for the ReachabilityPeerConnection instance\n * @returns {void}\n */\n private setupReachabilityPeerConnectionEventListeners() {\n this.reachabilityPeerConnection.on(ReachabilityPeerConnectionEvents.resultReady, (data) => {\n this.emit(\n {\n file: 'clusterReachability',\n function: 'setupReachabilityPeerConnectionEventListeners',\n },\n Events.resultReady,\n data\n );\n });\n\n this.reachabilityPeerConnection.on(\n ReachabilityPeerConnectionEvents.clientMediaIpsUpdated,\n (data) => {\n this.emit(\n {\n file: 'clusterReachability',\n function: 'setupReachabilityPeerConnectionEventListeners',\n },\n Events.clientMediaIpsUpdated,\n data\n );\n }\n );\n\n this.reachabilityPeerConnection.on(ReachabilityPeerConnectionEvents.natTypeUpdated, (data) => {\n this.emit(\n {\n file: 'clusterReachability',\n function: 'setupReachabilityPeerConnectionEventListeners',\n },\n Events.natTypeUpdated,\n data\n );\n });\n\n this.reachabilityPeerConnection.on(ReachabilityPeerConnectionEvents.reachedSubnets, (data) => {\n data.subnets.forEach((subnet) => {\n this.reachedSubnets.add(subnet);\n });\n });\n }\n\n /**\n * @returns {ClusterReachabilityResult} reachability result for this cluster\n */\n getResult(): ClusterReachabilityResult {\n return this.reachabilityPeerConnection.getResult();\n }\n\n /**\n * Starts the process of doing UDP, TCP, and XTLS reachability checks on the media cluster.\n * @returns {Promise<ClusterReachabilityResult>}\n */\n async start(): Promise<ClusterReachabilityResult> {\n await this.reachabilityPeerConnection.start();\n\n return this.getResult();\n }\n\n /**\n * Aborts the cluster reachability checks\n * @returns {void}\n */\n public abort() {\n this.reachabilityPeerConnection.abort();\n }\n}\n"],"mappings":"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","ignoreList":[]}
|