From eb21eb3f386c183b25fe6a9fb812f76d268e639e Mon Sep 17 00:00:00 2001
From: David Rowe <david@ctrlaltstudio.com>
Date: Tue, 26 Oct 2021 21:06:23 +1300
Subject: [PATCH] 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<LimitedNodeList>();
 
     // 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<DomainServer>(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> _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;