From 877ff9c139b44faf5a9231e08b59de19d367ec90 Mon Sep 17 00:00:00 2001 From: NaySurGithub <96527285+NaySurGithub@users.noreply.github.com> Date: Thu, 12 Nov 2026 19:05:50 +0100 Subject: [PATCH] feat: keep the candidates and channels a peer signalled --- .../Network/NetherNet/NetherNetConnection.h | 10 ++++++ include/Network/NetherNet/NetherNetInstance.h | 1 + src/Network/NetherNet/NetherNetConnection.cpp | 31 +++++++++++++++++++ src/Network/NetherNet/NetherNetInstance.cpp | 16 ++++++++++ 4 files changed, 58 insertions(+) diff --git a/include/Network/NetherNet/NetherNetConnection.h b/include/Network/NetherNet/NetherNetConnection.h index 013017d..4e438f3 100644 --- a/include/Network/NetherNet/NetherNetConnection.h +++ b/include/Network/NetherNet/NetherNetConnection.h @@ -57,6 +57,14 @@ namespace nethernet { void setRemoteRequest(const std::string &request) { mRemoteRequest = request; } + // the candidates the peer signalled after its offer, as received, a line each + std::string getRemoteCandidates() const; + + void addRemoteCandidate(const std::string &candidate); + + // the channels the peer opened, in the order it opened them: label, stream and protocol, a line each + std::string getRemoteChannels() const; + bool attachChannel(const std::shared_ptr &channel); bool areChannelsReady() const; @@ -83,6 +91,8 @@ namespace nethernet { std::string mRemoteFingerprint; std::string mRemoteOffer; std::string mRemoteRequest; + std::string mRemoteCandidates; + std::string mRemoteChannels; std::shared_ptr mPeerConnection; mutable std::mutex mMutex; diff --git a/include/Network/NetherNet/NetherNetInstance.h b/include/Network/NetherNet/NetherNetInstance.h index 4c93168..09a6dca 100644 --- a/include/Network/NetherNet/NetherNetInstance.h +++ b/include/Network/NetherNet/NetherNetInstance.h @@ -151,6 +151,7 @@ class NetherNetInstance : public Connector { std::shared_ptr mOnlineSignaling; unsigned int mSignalSubscription = 0; std::unordered_map> mNegotiating; + std::unordered_map> mNegotiatingConnections; std::unordered_map> mBufferedCandidates; std::vector mNegotiationThreads; diff --git a/src/Network/NetherNet/NetherNetConnection.cpp b/src/Network/NetherNet/NetherNetConnection.cpp index cd52342..50a9b8b 100644 --- a/src/Network/NetherNet/NetherNetConnection.cpp +++ b/src/Network/NetherNet/NetherNetConnection.cpp @@ -21,6 +21,10 @@ namespace nethernet { * is slowed down by the transport instead of filling memory. */ const size_t MAX_INCOMING_PACKETS = 256; + + // what is kept of a peer's signalling for whoever inspects the connection + const size_t MAX_REMOTE_CANDIDATES = 8 * 1024; + const size_t MAX_REMOTE_CHANNELS = 1024; } Connection::Connection(const NetworkIdentifier &id, std::shared_ptr peerConnection) @@ -31,10 +35,37 @@ namespace nethernet { close(); } + std::string Connection::getRemoteCandidates() const { + std::lock_guard lock(mMutex); + return mRemoteCandidates; + } + + void Connection::addRemoteCandidate(const std::string &candidate) { + std::lock_guard lock(mMutex); + if (mRemoteCandidates.size() + candidate.size() + 1 > MAX_REMOTE_CANDIDATES) + return; + mRemoteCandidates += candidate; + mRemoteCandidates.push_back('\n'); + } + + std::string Connection::getRemoteChannels() const { + std::lock_guard lock(mMutex); + return mRemoteChannels; + } + bool Connection::attachChannel(const std::shared_ptr &channel) { const std::string label = channel->label(); const rtc::Reliability reliability = channel->reliability(); + { + const std::optional stream = channel->stream(); + const std::string line = label + " " + (stream.has_value() ? std::to_string(stream.value()) : "-") + " " + + channel->protocol() + "\n"; + std::lock_guard lock(mMutex); + if (mRemoteChannels.size() + line.size() <= MAX_REMOTE_CHANNELS) + mRemoteChannels += line; + } + ChannelReliability kind; if (label == RELIABLE_CHANNEL_LABEL) { diff --git a/src/Network/NetherNet/NetherNetInstance.cpp b/src/Network/NetherNet/NetherNetInstance.cpp index 4cd7ae9..8e9d881 100644 --- a/src/Network/NetherNet/NetherNetInstance.cpp +++ b/src/Network/NetherNet/NetherNetInstance.cpp @@ -233,6 +233,7 @@ void NetherNetInstance::_detachSignaling() { std::lock_guard lock(mMutex); mNegotiating.clear(); + mNegotiatingConnections.clear(); mBufferedCandidates.clear(); } @@ -286,6 +287,7 @@ void NetherNetInstance::_answerOffer(nethernet::Signal offer) { void NetherNetInstance::_addRemoteCandidate(const std::string &signalKey, const std::string &candidate) { std::shared_ptr peerConnection; + std::shared_ptr connection; { std::lock_guard lock(mMutex); @@ -296,8 +298,14 @@ void NetherNetInstance::_addRemoteCandidate(const std::string &signalKey, const mBufferedCandidates[signalKey].push_back(candidate); return; } + + const auto owner = mNegotiatingConnections.find(signalKey); + connection = owner != mNegotiatingConnections.end() ? owner->second.lock() : nullptr; } + if (connection != nullptr) + connection->addRemoteCandidate(candidate); + try { peerConnection->addRemoteCandidate(rtc::Candidate(nethernet::Description::stripCandidatePrefix(candidate), "0")); } catch (const std::exception &error) { @@ -467,6 +475,7 @@ bool NetherNetInstance::_negotiateOffer(const std::string &networkID, const std: { std::lock_guard lock(mMutex); mNegotiating[signalKey] = peerConnection; + mNegotiatingConnections[signalKey] = connection; const auto it = mBufferedCandidates.find(signalKey); if (it != mBufferedCandidates.end()) { buffered = std::move(it->second); @@ -621,6 +630,13 @@ void NetherNetInstance::runEvents() { ++it; } + for (auto it = mNegotiatingConnections.begin(); it != mNegotiatingConnections.end();) { + if (it->second.expired()) + it = mNegotiatingConnections.erase(it); + else + ++it; + } + for (auto it = mPeers.begin(); it != mPeers.end();) { if (it->second->isClosed()) { dropped.push_back(it->second);