diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index b844615c6d..93abd8c759 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -891,7 +891,16 @@ void DomainServer::routeWebRTCSignalingMessage(const QJsonObject& json) { if (json.value("to").toString() == NodeType::DomainServer) { emit webrtcSignalingMessageForDomainServer(json); } else { - sendWebRTCSignalingMessageToAssignmentClient(json); + // Insert the WebRTC data channel ID for the assignment client to use. + auto webrtcSocket = DependencyManager::get()->getWebRTCSocket(); + auto channelID = webrtcSocket->getDataChannelIDForWebSocket((quint16)json.value("from").toInt()); + if (channelID == 0 && json.value("echo").isUndefined()) { // Let echo messages through without a domain connection. + qCritical() << "WebRTC data channel ID not found for assignment client signaling!"; + return; + } + QJsonObject jsonModified = json; + jsonModified.insert("channel", QJsonValue(channelID)); + sendWebRTCSignalingMessageToAssignmentClient(jsonModified); } } diff --git a/libraries/networking/src/webrtc/WebRTCDataChannels.cpp b/libraries/networking/src/webrtc/WebRTCDataChannels.cpp index c2b7ac6f5b..fd7ae8a454 100644 --- a/libraries/networking/src/webrtc/WebRTCDataChannels.cpp +++ b/libraries/networking/src/webrtc/WebRTCDataChannels.cpp @@ -131,12 +131,13 @@ void WDCDataChannelObserver::OnMessage(const DataBuffer& buffer) { } -WDCConnection::WDCConnection(WebRTCDataChannels* parent, quint16 webSocketID) : +WDCConnection::WDCConnection(WebRTCDataChannels* parent, quint16 webSocketID, int dataChannelID) : _parent(parent), - _webSocketID(webSocketID) + _webSocketID(webSocketID), + _dataChannelID(dataChannelID) { #ifdef WEBRTC_DEBUG - qCDebug(networking_webrtc) << "WDCConnection::WDCConnection() :" << webSocketID; + qCDebug(networking_webrtc) << "WDCConnection::WDCConnection() :" << webSocketID << dataChannelID; #endif // Create observers. @@ -288,7 +289,6 @@ void WDCConnection::onDataChannelOpened(rtc::scoped_refptr #endif _dataChannel = dataChannel; - _dataChannelID = _parent->getNewDataChannelID(); // Not dataChannel->id() because it's only unique per peer connection. _dataChannel->RegisterObserver(_dataChannelObserver.get()); #ifdef WEBRTC_DEBUG @@ -432,9 +432,23 @@ void WebRTCDataChannels::reset() { quint16 WebRTCDataChannels::getNewDataChannelID() { static const int QUINT16_LIMIT = std::numeric_limits::max() + 1; _lastDataChannelID = std::max((_lastDataChannelID + 1) % QUINT16_LIMIT, 1); +#ifdef WEBRTC_DEBUG + qCDebug(networking_webrtc) << "WebRTCDataChannels::getNewDataChannelID() :" << _lastDataChannelID; +#endif return _lastDataChannelID; } +int WebRTCDataChannels::getDataChannelIDForWebSocket(quint16 webSocketID) const { +#ifdef WEBRTC_DEBUG + qCDebug(networking_webrtc) << "WebRTCDataChannels::getDataChannelIDForWebSocket() :" << webSocketID; +#endif + auto connection = _connectionsByWebSocket.value(webSocketID); + if (!connection) { + return 0; + } + return connection->getDataChannelID(); +} + void WebRTCDataChannels::onDataChannelOpened(WDCConnection* connection, quint16 dataChannelID) { #ifdef WEBRTC_DEBUG qCDebug(networking_webrtc) << "WebRTCDataChannels::onDataChannelOpened() :" << dataChannelID; @@ -444,7 +458,7 @@ void WebRTCDataChannels::onDataChannelOpened(WDCConnection* connection, quint16 void WebRTCDataChannels::onSignalingMessage(const QJsonObject& message) { #ifdef WEBRTC_DEBUG - qCDebug(networking_webrtc) << "WebRTCDataChannel::onSignalingMessage()" << message; + qCDebug(networking_webrtc) << "WebRTCDataChannel::onSignalingMessage()" << message << message.value("channel"); #endif // Validate message. @@ -452,8 +466,9 @@ void WebRTCDataChannels::onSignalingMessage(const QJsonObject& message) { auto data = message.value("data").isObject() ? message.value("data").toObject() : QJsonObject(); int from = message.value("from").isDouble() ? (quint16)(message.value("from").toInt()) : 0; auto to = NodeType::fromChar(message.value("to").toString().at(0)); + int channel = message.value("channel").isDouble() ? (int)(message.value("channel").toInt()) : 0; - if (from <= 0 || from > MAXUINT16 || to == NodeType::Unassigned + if (from <= 0 || from > MAXUINT16 || to == NodeType::Unassigned || channel < 0 || channel > MAXUINT16 || !data.contains("description") && !data.contains("candidate")) { qCWarning(networking_webrtc) << "Unexpected signaling message:" << QJsonDocument(message).toJson(QJsonDocument::Compact).left(MAX_DEBUG_DETAIL_LENGTH); @@ -468,7 +483,12 @@ void WebRTCDataChannels::onSignalingMessage(const QJsonObject& message) { if (_connectionsByWebSocket.contains(from)) { connection = _connectionsByWebSocket.value(from); } else { - connection = new WDCConnection(this, from); + // Assignment clients use the same data channel ID as the domain server, which is provided in the "channel" property. + // The domain server creates a new data channel ID. + if (channel == 0) { + channel = getNewDataChannelID(); + } + connection = new WDCConnection(this, from, channel); _connectionsByWebSocket.insert(from, connection); } diff --git a/libraries/networking/src/webrtc/WebRTCDataChannels.h b/libraries/networking/src/webrtc/WebRTCDataChannels.h index b1751093d5..2e2827122b 100644 --- a/libraries/networking/src/webrtc/WebRTCDataChannels.h +++ b/libraries/networking/src/webrtc/WebRTCDataChannels.h @@ -129,7 +129,8 @@ public: /// @brief Constructs a new WDCConnection and opens a WebRTC data connection. /// @param parent The parent WebRTCDataChannels object. /// @param webSocketID The signaling channel that initiated the opening of the WebRTC data channel. - WDCConnection(WebRTCDataChannels* parent, quint16 webSocketID); + /// @param dataChannelID - The WebRTC data channel ID to assign to this connection. + WDCConnection(WebRTCDataChannels* parent, quint16 webSocketID, int dataChannelID); /// @brief Gets the WebSocket ID. /// @return The ID of the WebSocket. @@ -241,12 +242,17 @@ public: /// @brief Immediately closes all connections and resets the socket. void reset(); - /// @brief Get a new data channel ID to uniquely identify a WDCConnection. + /// @brief Gets a new data channel ID to uniquely identify a WDCConnection. /// @details This ID is assigned by WebRTCDataChannels; it is not the WebRTC data channel ID because that is only /// unique within a peer connection. /// @return A new data channel ID. quint16 getNewDataChannelID(); + /// @brief Gets the data channel ID associated with a WebSocket. + /// @param webSocketID The WebSocket. + /// @return The data channel ID associated with the WebSocket if found, `0` if the WebSocket was not found. + int getDataChannelIDForWebSocket(quint16 webSocketID) const; + /// @brief Handles a WebRTC data channel opening. /// @param connection The WebRTC data channel connection. /// @param dataChannelID The WebRTC data channel ID. diff --git a/libraries/networking/src/webrtc/WebRTCSocket.cpp b/libraries/networking/src/webrtc/WebRTCSocket.cpp index 69b97ebf94..589d46a76e 100644 --- a/libraries/networking/src/webrtc/WebRTCSocket.cpp +++ b/libraries/networking/src/webrtc/WebRTCSocket.cpp @@ -153,4 +153,9 @@ void WebRTCSocket::onDataChannelReceivedMessage(int dataChannelID, const QByteAr emit readyRead(); } + +int WebRTCSocket::getDataChannelIDForWebSocket(quint16 webSocketID) const { + return _dataChannels.getDataChannelIDForWebSocket(webSocketID); +} + #endif // WEBRTC_DATA_CHANNELS diff --git a/libraries/networking/src/webrtc/WebRTCSocket.h b/libraries/networking/src/webrtc/WebRTCSocket.h index 8e429673e1..f0a6a99d0c 100644 --- a/libraries/networking/src/webrtc/WebRTCSocket.h +++ b/libraries/networking/src/webrtc/WebRTCSocket.h @@ -120,6 +120,12 @@ public: /// @return The description of the error that last occurred. QString errorString() const; + + /// @brief Gets the data channel ID associated with a WebSocket. + /// @param webSocketID + /// @return The data channel ID associated with the WebSocket if found, `0` if the WebSocket was not found. + int getDataChannelIDForWebSocket(quint16 webSocketID) const; + public slots: /// @brief Handles the WebRTC data channel receiving a message.