Merge pull request #3309 from matrix-org/jryans/stun-turn-fallback

Prompt for ICE server fallback permission
This commit is contained in:
J. Ryan Stinnett 2019-08-15 15:16:07 +01:00 committed by GitHub
commit f3e169775a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 71 additions and 5 deletions

View file

@ -1,6 +1,7 @@
/* /*
Copyright 2015, 2016 OpenMarket Ltd Copyright 2015, 2016 OpenMarket Ltd
Copyright 2017, 2018 New Vector Ltd Copyright 2017, 2018 New Vector Ltd
Copyright 2019 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.
@ -64,6 +65,7 @@ import { showUnknownDeviceDialogForCalls } from './cryptodevices';
import WidgetUtils from './utils/WidgetUtils'; import WidgetUtils from './utils/WidgetUtils';
import WidgetEchoStore from './stores/WidgetEchoStore'; import WidgetEchoStore from './stores/WidgetEchoStore';
import {IntegrationManagers} from "./integrations/IntegrationManagers"; import {IntegrationManagers} from "./integrations/IntegrationManagers";
import SettingsStore, { SettingLevel } from './settings/SettingsStore';
global.mxCalls = { global.mxCalls = {
//room_id: MatrixCall //room_id: MatrixCall
@ -117,8 +119,7 @@ function _reAttemptCall(call) {
function _setCallListeners(call) { function _setCallListeners(call) {
call.on("error", function(err) { call.on("error", function(err) {
console.error("Call error: %s", err); console.error("Call error:", err);
console.error(err.stack);
if (err.code === 'unknown_devices') { if (err.code === 'unknown_devices') {
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
@ -146,8 +147,15 @@ function _setCallListeners(call) {
}, },
}); });
} else { } else {
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); if (
MatrixClientPeg.get().getTurnServers().length === 0 &&
SettingsStore.getValue("fallbackICEServerAllowed") === null
) {
_showICEFallbackPrompt();
return;
}
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
Modal.createTrackedDialog('Call Failed', '', ErrorDialog, { Modal.createTrackedDialog('Call Failed', '', ErrorDialog, {
title: _t('Call Failed'), title: _t('Call Failed'),
description: err.message, description: err.message,
@ -217,6 +225,36 @@ function _setCallState(call, roomId, status) {
}); });
} }
function _showICEFallbackPrompt() {
const cli = MatrixClientPeg.get();
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
const code = sub => <code>{sub}</code>;
Modal.createTrackedDialog('No TURN servers', '', QuestionDialog, {
title: _t("Call failed due to misconfigured server"),
description: <div>
<p>{_t(
"Please ask the administrator of your homeserver " +
"(<code>%(homeserverDomain)s</code>) to configure a TURN server in " +
"order for calls to work reliably.",
{ homeserverDomain: cli.getDomain() }, { code },
)}</p>
<p>{_t(
"Alternatively, you can try to use the public server at " +
"<code>turn.matrix.org</code>, but this will not be as reliable, and " +
"it will share your IP address with that server. You can also manage " +
"this in Settings.",
null, { code },
)}</p>
</div>,
button: _t('Try using turn.matrix.org'),
cancelButton: _t('OK'),
onFinished: (allow) => {
SettingsStore.setValue("fallbackICEServerAllowed", null, SettingLevel.DEVICE, allow);
cli.setFallbackICEServerAllowed(allow);
},
}, null, true);
}
function _onAction(payload) { function _onAction(payload) {
function placeCall(newCall) { function placeCall(newCall) {
_setCallListeners(newCall); _setCallListeners(newCall);

View file

@ -216,6 +216,7 @@ class MatrixClientPeg {
deviceId: creds.deviceId, deviceId: creds.deviceId,
timelineSupport: true, timelineSupport: true,
forceTURN: !SettingsStore.getValue('webRtcAllowPeerToPeer', false), forceTURN: !SettingsStore.getValue('webRtcAllowPeerToPeer', false),
fallbackICEServerAllowed: !!SettingsStore.getValue('fallbackICEServerAllowed'),
verificationMethods: [verificationMethods.SAS], verificationMethods: [verificationMethods.SAS],
unstableClientRelationAggregation: true, unstableClientRelationAggregation: true,
}; };

View file

@ -115,6 +115,10 @@ export default class VoiceUserSettingsTab extends React.Component {
MatrixClientPeg.get().setForceTURN(!p2p); MatrixClientPeg.get().setForceTURN(!p2p);
}; };
_changeFallbackICEServerAllowed = (allow) => {
MatrixClientPeg.get().setFallbackICEServerAllowed(allow);
};
_renderDeviceOptions(devices, category) { _renderDeviceOptions(devices, category) {
return devices.map((d) => { return devices.map((d) => {
return (<option key={`${category}-${d.deviceId}`} value={d.deviceId}>{d.label}</option>); return (<option key={`${category}-${d.deviceId}`} value={d.deviceId}>{d.label}</option>);
@ -201,7 +205,16 @@ export default class VoiceUserSettingsTab extends React.Component {
{microphoneDropdown} {microphoneDropdown}
{webcamDropdown} {webcamDropdown}
<SettingsFlag name='VideoView.flipVideoHorizontally' level={SettingLevel.ACCOUNT} /> <SettingsFlag name='VideoView.flipVideoHorizontally' level={SettingLevel.ACCOUNT} />
<SettingsFlag name='webRtcAllowPeerToPeer' level={SettingLevel.DEVICE} onChange={this._changeWebRtcMethod} /> <SettingsFlag
name='webRtcAllowPeerToPeer'
level={SettingLevel.DEVICE}
onChange={this._changeWebRtcMethod}
/>
<SettingsFlag
name='fallbackICEServerAllowed'
level={SettingLevel.DEVICE}
onChange={this._changeFallbackICEServerAllowed}
/>
</div> </div>
</div> </div>
); );

View file

@ -28,6 +28,11 @@
"Answer": "Answer", "Answer": "Answer",
"Call Timeout": "Call Timeout", "Call Timeout": "Call Timeout",
"The remote side failed to pick up": "The remote side failed to pick up", "The remote side failed to pick up": "The remote side failed to pick up",
"Call failed due to misconfigured server": "Call failed due to misconfigured server",
"Please ask the administrator of your homeserver (<code>%(homeserverDomain)s</code>) to configure a TURN server in order for calls to work reliably.": "Please ask the administrator of your homeserver (<code>%(homeserverDomain)s</code>) to configure a TURN server in order for calls to work reliably.",
"Alternatively, you can try to use the public server at <code>turn.matrix.org</code>, but this will not be as reliable, and it will share your IP address with that server. You can also manage this in Settings.": "Alternatively, you can try to use the public server at <code>turn.matrix.org</code>, but this will not be as reliable, and it will share your IP address with that server. You can also manage this in Settings.",
"Try using turn.matrix.org": "Try using turn.matrix.org",
"OK": "OK",
"Unable to capture screen": "Unable to capture screen", "Unable to capture screen": "Unable to capture screen",
"Existing Call": "Existing Call", "Existing Call": "Existing Call",
"You are already in a call.": "You are already in a call.", "You are already in a call.": "You are already in a call.",
@ -355,6 +360,7 @@
"Show recently visited rooms above the room list": "Show recently visited rooms above the room list", "Show recently visited rooms above the room list": "Show recently visited rooms above the room list",
"Show hidden events in timeline": "Show hidden events in timeline", "Show hidden events in timeline": "Show hidden events in timeline",
"Low bandwidth mode": "Low bandwidth mode", "Low bandwidth mode": "Low bandwidth mode",
"Allow fallback call assist server turn.matrix.org when your homeserver does not offer one (your IP address would be shared during a call)": "Allow fallback call assist server turn.matrix.org when your homeserver does not offer one (your IP address would be shared during a call)",
"Collecting app version information": "Collecting app version information", "Collecting app version information": "Collecting app version information",
"Collecting logs": "Collecting logs", "Collecting logs": "Collecting logs",
"Uploading report": "Uploading report", "Uploading report": "Uploading report",
@ -378,7 +384,6 @@
"Decline": "Decline", "Decline": "Decline",
"Accept": "Accept", "Accept": "Accept",
"The other party cancelled the verification.": "The other party cancelled the verification.", "The other party cancelled the verification.": "The other party cancelled the verification.",
"OK": "OK",
"Verified!": "Verified!", "Verified!": "Verified!",
"You've successfully verified this user.": "You've successfully verified this user.", "You've successfully verified this user.": "You've successfully verified this user.",
"Secure messages with this user are end-to-end encrypted and not able to be read by third parties.": "Secure messages with this user are end-to-end encrypted and not able to be read by third parties.", "Secure messages with this user are end-to-end encrypted and not able to be read by third parties.": "Secure messages with this user are end-to-end encrypted and not able to be read by third parties.",

View file

@ -372,4 +372,13 @@ export const SETTINGS = {
default: false, default: false,
controller: new LowBandwidthController(), controller: new LowBandwidthController(),
}, },
"fallbackICEServerAllowed": {
supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS,
displayName: _td(
"Allow fallback call assist server turn.matrix.org when your homeserver " +
"does not offer one (your IP address would be shared during a call)",
),
// This is a tri-state value, where `null` means "prompt the user".
default: null,
},
}; };