Use domain server-assigned WebRTC data channel ID in assignment clients

This commit is contained in:
David Rowe 2021-09-04 14:25:21 +12:00
parent 911dc2aff3
commit dddabecc84
5 changed files with 56 additions and 10 deletions

View file

@ -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<LimitedNodeList>()->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);
}
}

View file

@ -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<DataChannelInterface>
#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<uint16_t>::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);
}

View file

@ -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 <em>not</em> 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.

View file

@ -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

View file

@ -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.