Skip to content

Commit

Permalink
datachannel, refactor: add patch for WebRTC Direct.
Browse files Browse the repository at this point in the history
  • Loading branch information
xicilion committed Jun 21, 2024
1 parent 10aa147 commit 6b49216
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 10 deletions.
8 changes: 7 additions & 1 deletion datachannel/include/rtc/peerconnection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ struct RTC_CPP_EXPORT DataChannelInit {
string protocol = "";
};

struct RTC_CPP_EXPORT LocalDescriptionInit {
optional<string> iceUfrag;
optional<string> icePwd;
};

class RTC_CPP_EXPORT PeerConnection final : CheshireCat<impl::PeerConnection> {
public:
enum class State : int {
Expand Down Expand Up @@ -90,7 +95,7 @@ class RTC_CPP_EXPORT PeerConnection final : CheshireCat<impl::PeerConnection> {
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);

Expand All @@ -112,6 +117,7 @@ class RTC_CPP_EXPORT PeerConnection final : CheshireCat<impl::PeerConnection> {
void onSignalingStateChange(std::function<void(SignalingState state)> callback);

void resetCallbacks();
CertificateFingerprint remoteFingerprint();

// Stats
void clearStats();
Expand Down
10 changes: 10 additions & 0 deletions datachannel/src/impl/icetransport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,10 @@ IceTransport::IceTransport(const Configuration &config, candidate_callback candi
}
}

void IceTransport::setIceAttributes([[maybe_unused]] string uFrag, [[maybe_unused]] string pwd) {
PLOG_WARNING << "Setting custom ICE attributes is not supported with libnice, please use libjuice";
}

IceTransport::~IceTransport() {
PLOG_DEBUG << "Destroying ICE transport";
mAgent.reset();
Expand Down Expand Up @@ -608,6 +612,12 @@ IceTransport::IceTransport(const Configuration &config, candidate_callback candi
RecvCallback, this);
}

void IceTransport::setIceAttributes(string uFrag, string pwd) {
if (juice_set_local_ice_attributes(mAgent.get(), uFrag.c_str(), pwd.c_str()) < 0) {
throw std::invalid_argument("Invalid ICE attributes");
}
}

IceTransport::~IceTransport() {
PLOG_DEBUG << "Destroying ICE transport";
nice_agent_attach_recv(mNiceAgent.get(), mStreamId, 1, g_main_loop_get_context(MainLoop.get()),
Expand Down
1 change: 1 addition & 0 deletions datachannel/src/impl/icetransport.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ class IceTransport : public Transport {
void setRemoteDescription(const Description &description);
bool addRemoteCandidate(const Candidate &candidate);
void gatherLocalCandidates(string mid);
void setIceAttributes(string uFrag, string pwd);

optional<string> getLocalAddress() const;
optional<string> getRemoteAddress() const;
Expand Down
22 changes: 14 additions & 8 deletions datachannel/src/impl/peerconnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,8 @@ shared_ptr<DtlsTransport> PeerConnection::initDtlsTransport() {
fingerprintAlgorithm = remote->fingerprint()->algorithm;
}

mRemoteFingerprintAlgorithm = fingerprintAlgorithm;

auto lower = std::atomic_load(&mIceTransport);
if (!lower)
throw std::logic_error("No underlying ICE transport for DTLS transport");
Expand Down Expand Up @@ -434,19 +436,16 @@ bool PeerConnection::checkFingerprint(const std::string &fingerprint) {
if (!mRemoteDescription || !mRemoteDescription->fingerprint())
return false;

if (config.disableFingerprintVerification) {
CertificateFingerprint fp;

fp.algorithm = mRemoteDescription->fingerprint()->algorithm;
fp.value = fingerprint;
mRemoteDescription->setFingerprint(fp);

if (config.disableFingerprintVerification) {
PLOG_VERBOSE << "Skipping fingerprint validation";
mRemoteFingerprint = fingerprint;
return true;
}

auto expectedFingerprint = mRemoteDescription->fingerprint()->value;
if (expectedFingerprint == fingerprint) {
if (expectedFingerprint == fingerprint) {
PLOG_VERBOSE << "Valid fingerprint \"" << fingerprint << "\"";
mRemoteFingerprint = fingerprint;
return true;
}

Expand Down Expand Up @@ -1298,6 +1297,13 @@ void PeerConnection::resetCallbacks() {
trackCallback = nullptr;
}

CertificateFingerprint PeerConnection::remoteFingerprint() {
if (mRemoteFingerprint)
return {CertificateFingerprint{mRemoteFingerprintAlgorithm, *mRemoteFingerprint}};
else
return {};
}

void PeerConnection::updateTrackSsrcCache(const Description &description) {
std::unique_lock lock(mTracksMutex); // for safely writing to mTracksBySsrc

Expand Down
4 changes: 4 additions & 0 deletions datachannel/src/impl/peerconnection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ struct PeerConnection : std::enable_shared_from_this<PeerConnection> {
bool changeSignalingState(SignalingState newState);

void resetCallbacks();
CertificateFingerprint remoteFingerprint();

// Helper method for asynchronous callback invocation
template <typename... Args> void trigger(synchronized_callback<Args...> *cb, Args... args) {
Expand Down Expand Up @@ -157,6 +158,9 @@ struct PeerConnection : std::enable_shared_from_this<PeerConnection> {

Queue<shared_ptr<DataChannel>> mPendingDataChannels;
Queue<shared_ptr<Track>> mPendingTracks;

CertificateFingerprint::Algorithm mRemoteFingerprintAlgorithm = CertificateFingerprint::Algorithm::Sha256;
optional<string> mRemoteFingerprint;
};

} // namespace rtc::impl
Expand Down
11 changes: 10 additions & 1 deletion datachannel/src/peerconnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -140,6 +140,11 @@ void PeerConnection::setLocalDescription(Description::Type type) {
if (!iceTransport)
return; // closed

if (init.iceUfrag && init.icePwd) {
PLOG_DEBUG << "Using custom ICE attributes, ufrag=\"" << init.iceUfrag.value() << "\", pwd=\"" << init.icePwd.value() << "\"";
iceTransport->setIceAttributes(init.iceUfrag.value(), init.icePwd.value());
}

Description local = iceTransport->getLocalDescription(type);
impl()->processLocalDescription(std::move(local));

Expand Down Expand Up @@ -354,6 +359,10 @@ optional<std::chrono::milliseconds> PeerConnection::rtt() {
return sctpTransport ? sctpTransport->rtt() : nullopt;
}

CertificateFingerprint PeerConnection::remoteFingerprint() {
return impl()->remoteFingerprint();
}

std::ostream &operator<<(std::ostream &out, PeerConnection::State state) {
using State = PeerConnection::State;
const char *str;
Expand Down

0 comments on commit 6b49216

Please sign in to comment.