From 4b5ecb02911ca3b91e6834f95900c83efebc5264 Mon Sep 17 00:00:00 2001 From: achingbrain Date: Sun, 9 Jun 2024 10:26:31 +0100 Subject: [PATCH] feat: pass custom ICE ufrag and pwd as local description init Adds an optional second argument to `rtc::PeerConnection::setLocalDescription` that can contain an ICE ufrag and pwd that if passed will be used in place of the randomly generated versions. Refs: #1166 Refs: https://github.com/paullouisageneau/libdatachannel/pull/1201#discussion_r1633621803 --- include/rtc/peerconnection.hpp | 8 +++++++- src/impl/icetransport.cpp | 4 ++++ src/impl/icetransport.hpp | 1 + src/peerconnection.cpp | 7 ++++++- 4 files changed, 18 insertions(+), 2 deletions(-) diff --git a/include/rtc/peerconnection.hpp b/include/rtc/peerconnection.hpp index 9e49f80e1..ae8a36dcd 100644 --- a/include/rtc/peerconnection.hpp +++ b/include/rtc/peerconnection.hpp @@ -35,6 +35,12 @@ struct RTC_CPP_EXPORT DataChannelInit { string protocol = ""; }; +struct RTC_CPP_EXPORT LocalDescriptionInit { + Description::Type type = Description::Type::Unspec; + optional iceUfrag; + optional icePwd; +} + class RTC_CPP_EXPORT PeerConnection final : CheshireCat { public: enum class State : int { @@ -90,7 +96,7 @@ class RTC_CPP_EXPORT PeerConnection final : CheshireCat { uint16_t maxDataChannelId() const; bool getSelectedCandidatePair(Candidate *local, Candidate *remote); - void setLocalDescription(Description::Type type = Description::Type::Unspec); + void setLocalDescription(Description::Type type = Description::Type::Unspec, LocalDescriptionInit init = {}); void setRemoteDescription(Description description); void addRemoteCandidate(Candidate candidate); void gatherLocalCandidates(std::vector additionalIceServers = {}); diff --git a/src/impl/icetransport.cpp b/src/impl/icetransport.cpp index a27a2ed32..cf9e0e855 100644 --- a/src/impl/icetransport.cpp +++ b/src/impl/icetransport.cpp @@ -140,6 +140,10 @@ IceTransport::IceTransport(const Configuration &config, candidate_callback candi addIceServer(server); } +void IceTransport::setUfragAndPwd(string uFrag, string pwd) { + juice_set_local_ice_attributes(mAgent.get(), uFrag.c_str(), pwd.c_str()); +} + void IceTransport::addIceServer(IceServer server) { if (server.hostname.empty()) return; diff --git a/src/impl/icetransport.hpp b/src/impl/icetransport.hpp index 4133bcc2f..0ff325f41 100644 --- a/src/impl/icetransport.hpp +++ b/src/impl/icetransport.hpp @@ -51,6 +51,7 @@ class IceTransport : public Transport { void setRemoteDescription(const Description &description); bool addRemoteCandidate(const Candidate &candidate); void gatherLocalCandidates(string mid, std::vector additionalIceServers = {}); + void setUfragAndPwd(string uFrag, string pwd); optional getLocalAddress() const; optional getRemoteAddress() const; diff --git a/src/peerconnection.cpp b/src/peerconnection.cpp index 0e146834b..17f67aa16 100644 --- a/src/peerconnection.cpp +++ b/src/peerconnection.cpp @@ -76,7 +76,7 @@ bool PeerConnection::hasMedia() const { return local && local->hasAudioOrVideo(); } -void PeerConnection::setLocalDescription(Description::Type type) { +void PeerConnection::setLocalDescription(Description::Type type, LocalDescriptionInit init) { std::unique_lock signalingLock(impl()->signalingMutex); PLOG_VERBOSE << "Setting local description, type=" << Description::typeToString(type); @@ -140,6 +140,11 @@ void PeerConnection::setLocalDescription(Description::Type type) { if (!iceTransport) return; // closed + if (init.iceUfrag && init.icePwd) { + PLOG_DEBUG << "Using custom ufrag/pwd"; + iceTransport->setUfragAndPwd(init.iceUfrag.value(), init.iceUfrag.value()); + } + Description local = iceTransport->getLocalDescription(type); impl()->processLocalDescription(std::move(local));