From 0fcb9423bf64d04c572ee9dc81f85713a93f3b2a Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 26 Oct 2021 11:21:23 +1300 Subject: [PATCH 01/13] Fix ICE servers used for STUN --- .../src/webrtc/WebRTCDataChannels.cpp | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/libraries/networking/src/webrtc/WebRTCDataChannels.cpp b/libraries/networking/src/webrtc/WebRTCDataChannels.cpp index cbc5a8ff6e..a44cc65d2b 100644 --- a/libraries/networking/src/webrtc/WebRTCDataChannels.cpp +++ b/libraries/networking/src/webrtc/WebRTCDataChannels.cpp @@ -20,10 +20,15 @@ // - https://webrtc.github.io/webrtc-org/native-code/native-apis/ // - https://webrtc.googlesource.com/src/+/master/api/peer_connection_interface.h -const std::string ICE_SERVER_URI = "stun://ice.vircadia.com:7337"; +// FIXME: stun:ice.vircadia.com:7337 doesn't work for WebRTC. +const std::list ICE_SERVER_URIS = { + "stun:stun1.l.google.com:19302", + "stun:stun4.l.google.com:19302", + "stun:stun.schlund.de" +}; const int MAX_WEBRTC_BUFFER_SIZE = 16777216; // 16MB -// #define WEBRTC_DEBUG +#define WEBRTC_DEBUG using namespace webrtc; @@ -545,9 +550,11 @@ rtc::scoped_refptr WebRTCDataChannels::createPeerConnec #endif PeerConnectionInterface::RTCConfiguration configuration; - PeerConnectionInterface::IceServer iceServer; - iceServer.uri = ICE_SERVER_URI; - configuration.servers.push_back(iceServer); + for (const auto& uri : ICE_SERVER_URIS) { + PeerConnectionInterface::IceServer iceServer; + iceServer.uri = uri; + configuration.servers.push_back(iceServer); + } #ifdef WEBRTC_DEBUG qCDebug(networking_webrtc) << "2. Create a new peer connection"; From 2971dd61852253cc8ad6507fb252228db0266203 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 26 Oct 2021 12:13:25 +1300 Subject: [PATCH 02/13] Fix handling of ICE candidate received from client --- libraries/networking/src/webrtc/WebRTCDataChannels.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/webrtc/WebRTCDataChannels.cpp b/libraries/networking/src/webrtc/WebRTCDataChannels.cpp index a44cc65d2b..92b667e18f 100644 --- a/libraries/networking/src/webrtc/WebRTCDataChannels.cpp +++ b/libraries/networking/src/webrtc/WebRTCDataChannels.cpp @@ -489,7 +489,7 @@ void WebRTCDataChannels::onSignalingMessage(const QJsonObject& message) { // Add a remote ICE candidate. if (data.contains("candidate")) { - connection->addIceCandidate(data); + connection->addIceCandidate(data.value("candidate").toObject()); } } From eb21eb3f386c183b25fe6a9fb812f76d268e639e Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 26 Oct 2021 21:06:23 +1300 Subject: [PATCH 03/13] Add WebRTC on/off switch to domain server settings --- .../resources/describe-settings.json | 16 ++++++++++- domain-server/src/DomainServer.cpp | 28 +++++++++++++------ domain-server/src/DomainServer.h | 2 +- .../src/DomainServerSettingsManager.cpp | 2 ++ 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index b91a10a17c..9032d3fbd9 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -1,5 +1,5 @@ { - "version": 2.5, + "version": 2.6, "settings": [ { "name": "metaverse", @@ -73,6 +73,20 @@ } ] }, + { + "name": "webrtc", + "label": "Networking / WebRTC", + "settings": [ + { + "name": "enable_webrtc", + "label": "Enable WebRTC Client Connections", + "help": "Allow web clients to connect over WebRTC data channels.", + "type": "checkbox", + "default": false, + "advanced": true + } + ] + }, { "name": "authentication", "label": "Networking / WordPress OAuth2", diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index b295e5eaea..c93c1f9acf 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -196,10 +196,6 @@ DomainServer::DomainServer(int argc, char* argv[]) : _gatekeeper(this), _httpManager(QHostAddress::AnyIPv4, DOMAIN_SERVER_HTTP_PORT, QString("%1/resources/web/").arg(QCoreApplication::applicationDirPath()), this) -#if defined(WEBRTC_DATA_CHANNELS) - , - _webrtcSignalingServer(this) -#endif { if (_parentPID != -1) { watchParentProcess(_parentPID); @@ -275,6 +271,17 @@ DomainServer::DomainServer(int argc, char* argv[]) : _settingsManager.apiRefreshGroupInformation(); +#if defined(WEBRTC_DATA_CHANNELS) + const QString WEBRTC_ENABLE = "webrtc.enable_webrtc"; + bool isWebRTCEnabled = _settingsManager.valueForKeyPath(WEBRTC_ENABLE).toBool(); + qDebug() << "WebRTC enabled:" << isWebRTCEnabled; + // The domain server's WebRTC signaling server is used by the domain server and the assignment clients, so disabling it + // disables WebRTC for the server as a whole. + if (isWebRTCEnabled) { + _webrtcSignalingServer.reset(new WebRTCSignalingServer(this)); + } +#endif + setupNodeListAndAssignments(); updateReplicatedNodes(); @@ -282,7 +289,9 @@ DomainServer::DomainServer(int argc, char* argv[]) : updateUpstreamNodes(); #if defined(WEBRTC_DATA_CHANNELS) - setUpWebRTCSignalingServer(); + if (isWebRTCEnabled) { + setUpWebRTCSignalingServer(); + } #endif if (_type != NonMetaverse) { @@ -889,7 +898,7 @@ void DomainServer::setupNodeListAndAssignments() { // Sets up the WebRTC signaling server that's hosted by the domain server. void DomainServer::setUpWebRTCSignalingServer() { // Bind the WebRTC signaling server's WebSocket to its port. - bool isBound = _webrtcSignalingServer.bind(QHostAddress::AnyIPv4, DEFAULT_DOMAIN_SERVER_WS_PORT); + bool isBound = _webrtcSignalingServer->bind(QHostAddress::AnyIPv4, DEFAULT_DOMAIN_SERVER_WS_PORT); if (!isBound) { qWarning() << "WebRTC signaling server not bound to port. WebRTC connections are not supported."; return; @@ -898,13 +907,14 @@ void DomainServer::setUpWebRTCSignalingServer() { auto limitedNodeList = DependencyManager::get(); // Route inbound WebRTC signaling messages received from user clients. - connect(&_webrtcSignalingServer, &WebRTCSignalingServer::messageReceived, + connect(_webrtcSignalingServer.get(), &WebRTCSignalingServer::messageReceived, this, &DomainServer::routeWebRTCSignalingMessage); // Route domain server signaling messages. auto webrtcSocket = limitedNodeList->getWebRTCSocket(); connect(this, &DomainServer::webrtcSignalingMessageForDomainServer, webrtcSocket, &WebRTCSocket::onSignalingMessage); - connect(webrtcSocket, &WebRTCSocket::sendSignalingMessage, &_webrtcSignalingServer, &WebRTCSignalingServer::sendMessage); + connect(webrtcSocket, &WebRTCSocket::sendSignalingMessage, + _webrtcSignalingServer.get(), &WebRTCSignalingServer::sendMessage); // Forward signaling messages received from assignment clients to user client. PacketReceiver& packetReceiver = limitedNodeList->getPacketReceiver(); @@ -912,7 +922,7 @@ void DomainServer::setUpWebRTCSignalingServer() { PacketReceiver::makeUnsourcedListenerReference(this, &DomainServer::forwardAssignmentClientSignalingMessageToUserClient)); connect(this, &DomainServer::webrtcSignalingMessageForUserClient, - &_webrtcSignalingServer, &WebRTCSignalingServer::sendMessage); + _webrtcSignalingServer.get(), &WebRTCSignalingServer::sendMessage); } // Routes an inbound WebRTC signaling message received from a client app to the appropriate recipient. diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 83816a132a..13c715d5e3 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -333,7 +333,7 @@ private: QThread _assetClientThread; #if defined(WEBRTC_DATA_CHANNELS) - WebRTCSignalingServer _webrtcSignalingServer; + std::unique_ptr _webrtcSignalingServer { nullptr }; #endif }; diff --git a/domain-server/src/DomainServerSettingsManager.cpp b/domain-server/src/DomainServerSettingsManager.cpp index 7b04c72845..912a771ab3 100644 --- a/domain-server/src/DomainServerSettingsManager.cpp +++ b/domain-server/src/DomainServerSettingsManager.cpp @@ -551,6 +551,8 @@ void DomainServerSettingsManager::setupConfigMap(const QString& userConfigFilena packPermissions(); } + // No migration needed to version 2.6. + // write the current description version to our settings *versionVariant = _descriptionVersion; From 92e3d1465eb17dd892d1b5a933931521cd5b719d Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 27 Oct 2021 21:41:12 +1300 Subject: [PATCH 04/13] Reduce the number of ICE servers used --- libraries/networking/src/webrtc/WebRTCDataChannels.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/networking/src/webrtc/WebRTCDataChannels.cpp b/libraries/networking/src/webrtc/WebRTCDataChannels.cpp index 92b667e18f..0d069d7171 100644 --- a/libraries/networking/src/webrtc/WebRTCDataChannels.cpp +++ b/libraries/networking/src/webrtc/WebRTCDataChannels.cpp @@ -21,9 +21,9 @@ // - https://webrtc.googlesource.com/src/+/master/api/peer_connection_interface.h // FIXME: stun:ice.vircadia.com:7337 doesn't work for WebRTC. -const std::list ICE_SERVER_URIS = { +// Firefox warns: "WebRTC: Using more than two STUN/TURN servers slows down discovery" +const std::list ICE_SERVER_URIS = { "stun:stun1.l.google.com:19302", - "stun:stun4.l.google.com:19302", "stun:stun.schlund.de" }; const int MAX_WEBRTC_BUFFER_SIZE = 16777216; // 16MB From bb3d0fa5fa13ba4c352613c7fe52b209ca10b5cb Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 27 Oct 2021 21:42:58 +1300 Subject: [PATCH 05/13] Add secure WebSocket support --- .../resources/describe-settings.json | 8 +++ domain-server/src/DomainServer.cpp | 5 +- .../src/webrtc/WebRTCSignalingServer.cpp | 57 ++++++++++++++++++- .../src/webrtc/WebRTCSignalingServer.h | 3 +- 4 files changed, 68 insertions(+), 5 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index 9032d3fbd9..f83a4c47b4 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -84,6 +84,14 @@ "type": "checkbox", "default": false, "advanced": true + }, + { + "name": "enable_webrtc_websocket_ssl", + "label": "Enable WebRTC WebSocket SSL", + "help": "Use secure WebSocket (wss:// protocol) for WebRTC signaling channel. If \"on\", the key, cert, and CA files are expected to be in the local Vircadia app directory, in a /domain-server/ subdirectory with filenames cert.key, cert.crt, and crt-ca.crt.", + "type": "checkbox", + "default": false, + "advanced": true } ] }, diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index c93c1f9acf..67f961d36f 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -278,7 +278,10 @@ DomainServer::DomainServer(int argc, char* argv[]) : // The domain server's WebRTC signaling server is used by the domain server and the assignment clients, so disabling it // disables WebRTC for the server as a whole. if (isWebRTCEnabled) { - _webrtcSignalingServer.reset(new WebRTCSignalingServer(this)); + const QString WEBRTC_WSS_ENABLE = "webrtc.enable_webrtc_websocket_ssl"; + bool isWebRTCEnabled = _settingsManager.valueForKeyPath(WEBRTC_WSS_ENABLE).toBool(); + qDebug() << "WebRTC WSS enabled:" << isWebRTCEnabled; + _webrtcSignalingServer.reset(new WebRTCSignalingServer(this, isWebRTCEnabled)); } #endif diff --git a/libraries/networking/src/webrtc/WebRTCSignalingServer.cpp b/libraries/networking/src/webrtc/WebRTCSignalingServer.cpp index b35cd5158b..987bf6b02f 100644 --- a/libraries/networking/src/webrtc/WebRTCSignalingServer.cpp +++ b/libraries/networking/src/webrtc/WebRTCSignalingServer.cpp @@ -10,19 +10,70 @@ #if defined(WEBRTC_DATA_CHANNELS) +#include #include #include +#include +#include + #include "../NetworkLogging.h" #include "../NodeType.h" const int WEBRTC_SOCKET_CHECK_INTERVAL_IN_MS = 30000; -WebRTCSignalingServer::WebRTCSignalingServer(QObject* parent) : - QObject(parent), - _webSocketServer(new QWebSocketServer(QStringLiteral("WebRTC Signaling Server"), QWebSocketServer::NonSecureMode, this)) +WebRTCSignalingServer::WebRTCSignalingServer(QObject* parent, bool isWSSEnabled) : + QObject(parent) { + if (isWSSEnabled) { + _webSocketServer = (new QWebSocketServer(QStringLiteral("WebRTC Signaling Server"), QWebSocketServer::SecureMode, + this)); + + auto dsDirPath = PathUtils::getAppLocalDataPath(); + const QString KEY_FILENAME = "cert.key"; + const QString CRT_FILENAME = "cert.crt"; + const QString CA_CRT_FILENAME = "cert-ca.crt"; + qCDebug(networking_webrtc) << "WebSocket WSS key file:" << dsDirPath + KEY_FILENAME; + qCDebug(networking_webrtc) << "WebSocket WSS cert file:" << dsDirPath + CRT_FILENAME; + qCDebug(networking_webrtc) << "WebSocket WSS CA cert file:" << dsDirPath + CA_CRT_FILENAME; + + QFile sslCaFile(dsDirPath + CA_CRT_FILENAME); + sslCaFile.open(QIODevice::ReadOnly); + QSslCertificate sslCaCertificate(&sslCaFile, QSsl::Pem); + sslCaFile.close(); + + QSslConfiguration sslConfiguration; + QFile sslCrtFile(dsDirPath + CRT_FILENAME); + sslCrtFile.open(QIODevice::ReadOnly); + QSslCertificate sslCertificate(&sslCrtFile, QSsl::Pem); + sslCrtFile.close(); + + QFile sslKeyFile(dsDirPath + KEY_FILENAME); + sslKeyFile.open(QIODevice::ReadOnly); + QSslKey sslKey(&sslKeyFile, QSsl::Rsa, QSsl::Pem); + sslKeyFile.close(); + + if (!sslCaCertificate.isNull() && !sslKey.isNull() && !sslCertificate.isNull()) { + sslConfiguration.setPeerVerifyMode(QSslSocket::VerifyNone); + sslConfiguration.addCaCertificate(sslCaCertificate); + sslConfiguration.setLocalCertificate(sslCertificate); + sslConfiguration.setPrivateKey(sslKey); + _webSocketServer->setSslConfiguration(sslConfiguration); + qCDebug(networking_webrtc) << "WebSocket SSL mode enabled:" + << (_webSocketServer->secureMode() == QWebSocketServer::SecureMode); + } else { + qCWarning(networking_webrtc) << "Error creating WebSocket SSL key."; + } + + } else { + _webSocketServer = (new QWebSocketServer(QStringLiteral("WebRTC Signaling Server"), QWebSocketServer::NonSecureMode, + this)); + } +#ifdef WEBRTC_DEBUG + qCDebug(networking_webrtc) << "WebRTCSignalingServer mode =" << _webSocketServer->secureMode(); +#endif + connect(_webSocketServer, &QWebSocketServer::newConnection, this, &WebRTCSignalingServer::newWebSocketConnection); // Automatically recover from network interruptions. diff --git a/libraries/networking/src/webrtc/WebRTCSignalingServer.h b/libraries/networking/src/webrtc/WebRTCSignalingServer.h index fb695cc6fc..3a2eebbcef 100644 --- a/libraries/networking/src/webrtc/WebRTCSignalingServer.h +++ b/libraries/networking/src/webrtc/WebRTCSignalingServer.h @@ -61,7 +61,8 @@ public: /// @brief Constructs a new WebRTCSignalingServer object. /// @param parent Qt parent object. - WebRTCSignalingServer(QObject* parent); + /// @param isWSSEnabled Whether the WebSocket used for WebRTC signaling should be secure (WSS protocol). + WebRTCSignalingServer(QObject* parent, bool isWSSEnabled); /// @brief Binds the WebRTC signaling server's WebSocket to an address and port. /// @param address The address to use for the WebSocket. From 8e3cfe9805dbc3fa3a29bbbcaf857d9d239e668f Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 29 Oct 2021 23:04:41 +1300 Subject: [PATCH 06/13] Fix non-const lvalue reference --- libraries/networking/src/webrtc/WebRTCDataChannels.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/networking/src/webrtc/WebRTCDataChannels.cpp b/libraries/networking/src/webrtc/WebRTCDataChannels.cpp index 0d069d7171..128d48f42a 100644 --- a/libraries/networking/src/webrtc/WebRTCDataChannels.cpp +++ b/libraries/networking/src/webrtc/WebRTCDataChannels.cpp @@ -489,7 +489,8 @@ void WebRTCDataChannels::onSignalingMessage(const QJsonObject& message) { // Add a remote ICE candidate. if (data.contains("candidate")) { - connection->addIceCandidate(data.value("candidate").toObject()); + auto candidate = data.value("candidate").toObject(); + connection->addIceCandidate(candidate); } } From ccd525a89b4bd8e77c8aacc5fa92544f40e57ff5 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 30 Oct 2021 08:30:05 +1300 Subject: [PATCH 07/13] CR --- domain-server/src/DomainServer.cpp | 4 ++-- libraries/networking/src/webrtc/WebRTCSignalingServer.cpp | 4 ---- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 67f961d36f..d14a909a1a 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -274,13 +274,13 @@ DomainServer::DomainServer(int argc, char* argv[]) : #if defined(WEBRTC_DATA_CHANNELS) const QString WEBRTC_ENABLE = "webrtc.enable_webrtc"; bool isWebRTCEnabled = _settingsManager.valueForKeyPath(WEBRTC_ENABLE).toBool(); - qDebug() << "WebRTC enabled:" << isWebRTCEnabled; + qCDebug(domain_server) << "WebRTC enabled:" << isWebRTCEnabled; // The domain server's WebRTC signaling server is used by the domain server and the assignment clients, so disabling it // disables WebRTC for the server as a whole. if (isWebRTCEnabled) { const QString WEBRTC_WSS_ENABLE = "webrtc.enable_webrtc_websocket_ssl"; bool isWebRTCEnabled = _settingsManager.valueForKeyPath(WEBRTC_WSS_ENABLE).toBool(); - qDebug() << "WebRTC WSS enabled:" << isWebRTCEnabled; + qCDebug(domain_server) << "WebRTC WSS enabled:" << isWebRTCEnabled; _webrtcSignalingServer.reset(new WebRTCSignalingServer(this, isWebRTCEnabled)); } #endif diff --git a/libraries/networking/src/webrtc/WebRTCSignalingServer.cpp b/libraries/networking/src/webrtc/WebRTCSignalingServer.cpp index 987bf6b02f..bd8cd2fef4 100644 --- a/libraries/networking/src/webrtc/WebRTCSignalingServer.cpp +++ b/libraries/networking/src/webrtc/WebRTCSignalingServer.cpp @@ -70,10 +70,6 @@ WebRTCSignalingServer::WebRTCSignalingServer(QObject* parent, bool isWSSEnabled) _webSocketServer = (new QWebSocketServer(QStringLiteral("WebRTC Signaling Server"), QWebSocketServer::NonSecureMode, this)); } -#ifdef WEBRTC_DEBUG - qCDebug(networking_webrtc) << "WebRTCSignalingServer mode =" << _webSocketServer->secureMode(); -#endif - connect(_webSocketServer, &QWebSocketServer::newConnection, this, &WebRTCSignalingServer::newWebSocketConnection); // Automatically recover from network interruptions. From c76dc5358ba0976b416eabe202f03aafc2e74089 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sun, 31 Oct 2021 10:01:04 +1300 Subject: [PATCH 08/13] Rename domain server cert files --- domain-server/resources/describe-settings.json | 2 +- libraries/networking/src/webrtc/WebRTCSignalingServer.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/domain-server/resources/describe-settings.json b/domain-server/resources/describe-settings.json index f83a4c47b4..f6882d6a05 100644 --- a/domain-server/resources/describe-settings.json +++ b/domain-server/resources/describe-settings.json @@ -88,7 +88,7 @@ { "name": "enable_webrtc_websocket_ssl", "label": "Enable WebRTC WebSocket SSL", - "help": "Use secure WebSocket (wss:// protocol) for WebRTC signaling channel. If \"on\", the key, cert, and CA files are expected to be in the local Vircadia app directory, in a /domain-server/ subdirectory with filenames cert.key, cert.crt, and crt-ca.crt.", + "help": "Use secure WebSocket (wss:// protocol) for WebRTC signaling channel. If \"on\", the key, cert, and CA files are expected to be in the local Vircadia app directory, in a /domain-server/ subdirectory with filenames vircadia-cert.key, vircadia-cert.crt, and vircadia-crt-ca.crt.", "type": "checkbox", "default": false, "advanced": true diff --git a/libraries/networking/src/webrtc/WebRTCSignalingServer.cpp b/libraries/networking/src/webrtc/WebRTCSignalingServer.cpp index bd8cd2fef4..f3837a874b 100644 --- a/libraries/networking/src/webrtc/WebRTCSignalingServer.cpp +++ b/libraries/networking/src/webrtc/WebRTCSignalingServer.cpp @@ -31,9 +31,9 @@ WebRTCSignalingServer::WebRTCSignalingServer(QObject* parent, bool isWSSEnabled) this)); auto dsDirPath = PathUtils::getAppLocalDataPath(); - const QString KEY_FILENAME = "cert.key"; - const QString CRT_FILENAME = "cert.crt"; - const QString CA_CRT_FILENAME = "cert-ca.crt"; + const QString KEY_FILENAME = "vircadia-cert.key"; + const QString CRT_FILENAME = "vircadia-cert.crt"; + const QString CA_CRT_FILENAME = "vircadia-cert-ca.crt"; qCDebug(networking_webrtc) << "WebSocket WSS key file:" << dsDirPath + KEY_FILENAME; qCDebug(networking_webrtc) << "WebSocket WSS cert file:" << dsDirPath + CRT_FILENAME; qCDebug(networking_webrtc) << "WebSocket WSS CA cert file:" << dsDirPath + CA_CRT_FILENAME; From afd79931523722f86d7390b0947ee7afdea2e926 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 6 Nov 2021 22:31:52 +1300 Subject: [PATCH 09/13] Disable WebRTC debug --- libraries/networking/src/webrtc/WebRTCDataChannels.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/networking/src/webrtc/WebRTCDataChannels.cpp b/libraries/networking/src/webrtc/WebRTCDataChannels.cpp index 128d48f42a..ad67004d58 100644 --- a/libraries/networking/src/webrtc/WebRTCDataChannels.cpp +++ b/libraries/networking/src/webrtc/WebRTCDataChannels.cpp @@ -28,7 +28,7 @@ const std::list ICE_SERVER_URIS = { }; const int MAX_WEBRTC_BUFFER_SIZE = 16777216; // 16MB -#define WEBRTC_DEBUG +// #define WEBRTC_DEBUG using namespace webrtc; From a2ac43289c1c5abf9bdcebd1aa9cc5cc39fbd24a Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 9 Nov 2021 12:12:55 +1300 Subject: [PATCH 10/13] Use avatar position as orb position when head position not available --- interface/src/avatar/OtherAvatar.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/OtherAvatar.cpp b/interface/src/avatar/OtherAvatar.cpp index b6a2ea3ed9..fe0e83dfa0 100755 --- a/interface/src/avatar/OtherAvatar.cpp +++ b/interface/src/avatar/OtherAvatar.cpp @@ -64,7 +64,11 @@ void OtherAvatar::removeOrb() { void OtherAvatar::updateOrbPosition() { if (!_otherAvatarOrbMeshPlaceholderID.isNull()) { EntityItemProperties properties; - properties.setPosition(getHead()->getPosition()); + glm::vec3 headPosition; + if (!_skeletonModel->getHeadPosition(headPosition)) { + headPosition = getWorldPosition(); + } + properties.setPosition(headPosition); DependencyManager::get()->editEntity(_otherAvatarOrbMeshPlaceholderID, properties); } } From fb79d57fefa299d807203eafedd3eae6bdb73aff Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 20 Nov 2021 11:06:05 +1300 Subject: [PATCH 11/13] Improve WebRTC debug --- .../src/webrtc/WebRTCDataChannels.cpp | 64 +++++++++++++++++-- .../src/webrtc/WebRTCDataChannels.h | 8 +++ 2 files changed, 65 insertions(+), 7 deletions(-) diff --git a/libraries/networking/src/webrtc/WebRTCDataChannels.cpp b/libraries/networking/src/webrtc/WebRTCDataChannels.cpp index ad67004d58..6ed9761c63 100644 --- a/libraries/networking/src/webrtc/WebRTCDataChannels.cpp +++ b/libraries/networking/src/webrtc/WebRTCDataChannels.cpp @@ -71,7 +71,7 @@ WDCPeerConnectionObserver::WDCPeerConnectionObserver(WDCConnection* parent) : void WDCPeerConnectionObserver::OnSignalingChange(PeerConnectionInterface::SignalingState newState) { #ifdef WEBRTC_DEBUG - QStringList states{ + QStringList states { "Stable", "HaveLocalOffer", "HaveLocalPrAnswer", @@ -79,7 +79,7 @@ void WDCPeerConnectionObserver::OnSignalingChange(PeerConnectionInterface::Signa "HaveRemotePrAnswer", "Closed" }; - qCDebug(networking_webrtc) << "WDCPeerConnectionObserver::OnSignalingChange()" << newState << states[newState]; + qCDebug(networking_webrtc) << "WDCPeerConnectionObserver::OnSignalingChange() :" << newState << states[newState]; #endif } @@ -91,7 +91,12 @@ void WDCPeerConnectionObserver::OnRenegotiationNeeded() { void WDCPeerConnectionObserver::OnIceGatheringChange(PeerConnectionInterface::IceGatheringState newState) { #ifdef WEBRTC_DEBUG - qCDebug(networking_webrtc) << "WDCPeerConnectionObserver::OnIceGatheringChange()" << newState; + QStringList states { + "New", + "Gathering", + "Complete" + }; + qCDebug(networking_webrtc) << "WDCPeerConnectionObserver::OnIceGatheringChange() :" << newState << states[newState]; #endif } @@ -102,6 +107,39 @@ void WDCPeerConnectionObserver::OnIceCandidate(const IceCandidateInterface* cand _parent->sendIceCandidate(candidate); } +void WDCPeerConnectionObserver::OnIceConnectionChange(PeerConnectionInterface::IceConnectionState newState) { +#ifdef WEBRTC_DEBUG + QStringList states { + "New", + "Checking", + "Connected", + "Completed", + "Failed", + "Disconnected", + "Closed", + "Max" + }; + qCDebug(networking_webrtc) << "WDCPeerConnectionObserver::OnIceConnectionChange() :" << newState << states[newState]; +#endif +} + +void WDCPeerConnectionObserver::OnStandardizedIceConnectionChange(PeerConnectionInterface::IceConnectionState newState) { +#ifdef WEBRTC_DEBUG + QStringList states { + "New", + "Checking", + "Connected", + "Completed", + "Failed", + "Disconnected", + "Closed", + "Max" + }; + qCDebug(networking_webrtc) << "WDCPeerConnectionObserver::OnStandardizedIceConnectionChange() :" << newState + << states[newState]; +#endif +} + void WDCPeerConnectionObserver::OnDataChannel(rtc::scoped_refptr dataChannel) { #ifdef WEBRTC_DEBUG qCDebug(networking_webrtc) << "WDCPeerConnectionObserver::OnDataChannel()"; @@ -111,7 +149,16 @@ void WDCPeerConnectionObserver::OnDataChannel(rtc::scoped_refptronPeerConnectionStateChanged(newState); } @@ -267,7 +314,7 @@ void WDCConnection::sendIceCandidate(const IceCandidateInterface* candidate) { void WDCConnection::onPeerConnectionStateChanged(PeerConnectionInterface::PeerConnectionState state) { #ifdef WEBRTC_DEBUG - const char* STATES[] = { + QStringList states { "New", "Connecting", "Connected", @@ -275,7 +322,7 @@ void WDCConnection::onPeerConnectionStateChanged(PeerConnectionInterface::PeerCo "Failed", "Closed" }; - qCDebug(networking_webrtc) << "WDCConnection::onPeerConnectionStateChanged() :" << (int)state << STATES[(int)state]; + qCDebug(networking_webrtc) << "WDCConnection::onPeerConnectionStateChanged() :" << (int)state << states[(int)state]; #endif } @@ -372,7 +419,7 @@ bool WDCConnection::sendDataMessage(const DataBuffer& buffer) { void WDCConnection::closePeerConnection() { #ifdef WEBRTC_DEBUG - qCDebug(networking_webrtc) << "WDCConnection::closePeerConnection()"; + qCDebug(networking_webrtc) << "WDCConnection::closePeerConnection() :" << (int)_peerConnection->peer_connection_state(); #endif _peerConnection->Close(); _peerConnection = nullptr; @@ -430,6 +477,9 @@ WebRTCDataChannels::~WebRTCDataChannels() { } void WebRTCDataChannels::reset() { +#ifdef WEBRTC_DEBUG + qCDebug(networking_webrtc) << "WebRTCDataChannels::reset() :" << _connectionsByID.count(); +#endif QHashIterator i(_connectionsByID); while (i.hasNext()) { i.next(); diff --git a/libraries/networking/src/webrtc/WebRTCDataChannels.h b/libraries/networking/src/webrtc/WebRTCDataChannels.h index fe8af77078..68bb439b61 100644 --- a/libraries/networking/src/webrtc/WebRTCDataChannels.h +++ b/libraries/networking/src/webrtc/WebRTCDataChannels.h @@ -88,6 +88,14 @@ public: /// @param candidate The new ICE candidate. void OnIceCandidate(const webrtc::IceCandidateInterface* candidate) override; + /// @brief Called when the legacy ICE connection state changes. + /// @param new_state The new ICE connection state. + virtual void OnIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState newState) override; + + /// @brief Called when the standards-compliant ICE connection state changes. + /// @param new_state The new ICE connection state. + virtual void OnStandardizedIceConnectionChange(webrtc::PeerConnectionInterface::IceConnectionState newState) override; + /// @brief Called when a remote peer opens a data channel. /// @param dataChannel The data channel. void OnDataChannel(rtc::scoped_refptr dataChannel) override; From cf57b506b5dae9ac7f3cbd1796311bbb25aacb1b Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 20 Nov 2021 12:13:30 +1300 Subject: [PATCH 12/13] Fix domain server crash --- libraries/networking/src/webrtc/WebRTCSignalingServer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/networking/src/webrtc/WebRTCSignalingServer.cpp b/libraries/networking/src/webrtc/WebRTCSignalingServer.cpp index f3837a874b..2c557ceaee 100644 --- a/libraries/networking/src/webrtc/WebRTCSignalingServer.cpp +++ b/libraries/networking/src/webrtc/WebRTCSignalingServer.cpp @@ -131,8 +131,9 @@ void WebRTCSignalingServer::webSocketDisconnected() { auto source = qobject_cast(sender()); if (source) { auto address = source->peerAddress().toString() + ":" + QString::number(source->peerPort()); - delete _webSockets.value(address); _webSockets.remove(address); + source->abort(); + source->deleteLater(); } } From 56d33b555eb87aebc6bde234141724ef216cfb39 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 20 Nov 2021 17:26:06 +1300 Subject: [PATCH 13/13] Fix assignment client crash --- .../src/webrtc/WebRTCDataChannels.cpp | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/libraries/networking/src/webrtc/WebRTCDataChannels.cpp b/libraries/networking/src/webrtc/WebRTCDataChannels.cpp index 6ed9761c63..44c1c5e82c 100644 --- a/libraries/networking/src/webrtc/WebRTCDataChannels.cpp +++ b/libraries/networking/src/webrtc/WebRTCDataChannels.cpp @@ -355,13 +355,11 @@ void WDCConnection::onDataChannelStateChanged() { << DataChannelInterface::DataStateString(state); #endif if (state == DataChannelInterface::kClosed) { - // Close data channel. + // Finish with the data channel. _dataChannel->UnregisterObserver(); + // Don't set _dataChannel = nullptr because it is a scoped_refptr. _dataChannelObserver = nullptr; - _dataChannel = nullptr; -#ifdef WEBRTC_DEBUG - qCDebug(networking_webrtc) << "Disposed of data channel"; -#endif + // Close peer connection. _parent->closePeerConnection(this); } @@ -396,17 +394,21 @@ qint64 WDCConnection::getBufferedAmount() const { #ifdef WEBRTC_DEBUG qCDebug(networking_webrtc) << "WDCConnection::getBufferedAmount()"; #endif - return _dataChannel ? _dataChannel->buffered_amount() : 0; + return _dataChannel && _dataChannel->state() != DataChannelInterface::kClosing + && _dataChannel->state() != DataChannelInterface::kClosed + ? _dataChannel->buffered_amount() : 0; } bool WDCConnection::sendDataMessage(const DataBuffer& buffer) { #ifdef WEBRTC_DEBUG qCDebug(networking_webrtc) << "WDCConnection::sendDataMessage()"; - if (!_dataChannel) { + if (!_dataChannel || _dataChannel->state() == DataChannelInterface::kClosing + || _dataChannel->state() == DataChannelInterface::kClosed) { qCDebug(networking_webrtc) << "No data channel to send on"; } #endif - if (!_dataChannel) { + if (!_dataChannel || _dataChannel->state() == DataChannelInterface::kClosing + || _dataChannel->state() == DataChannelInterface::kClosed) { // Data channel may have been closed while message to send was being prepared. return false; } else if (_dataChannel->buffered_amount() + buffer.size() > MAX_WEBRTC_BUFFER_SIZE) { @@ -422,7 +424,7 @@ void WDCConnection::closePeerConnection() { qCDebug(networking_webrtc) << "WDCConnection::closePeerConnection() :" << (int)_peerConnection->peer_connection_state(); #endif _peerConnection->Close(); - _peerConnection = nullptr; + // Don't set _peerConnection = nullptr because it is a scoped_refptr. _peerConnectionObserver = nullptr; #ifdef WEBRTC_DEBUG qCDebug(networking_webrtc) << "Disposed of peer connection";