Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: update current remote description with fingerprint #1204

Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
feat: update current remote description with fingerprint
Adds a `currentRemoteDescription` field to `PeerConnection` which
can be updated independently of `remoteDescription`, the idea being
the `remoteDescription` is the offer received from the remote peer
and the `currentRemoteDescription` is what has actually been
negotiated with them.

The `currentRemoteDescription` is initialised when the
`remoteDescription` is set.

Currently the `checkFingerprint` method updates the certificate
fingerprint used by the connection to the remote peer but I guess
other modifications may be useful.

Exposes the `currentRemoteDescription` via a getter similar to
`remoteDescription`.
achingbrain committed Jun 7, 2024

Verified

This commit was signed with the committer’s verified signature.
achingbrain Alex Potsides
commit 96eb58bcc3071986e0a5dd26cbcef4c37954a66e
18 changes: 18 additions & 0 deletions DOC.md
Original file line number Diff line number Diff line change
@@ -278,6 +278,24 @@ Return value: the length of the string copied in buffer (including the terminati

If `buffer` is `NULL`, the description is not copied but the size is still returned.

#### rtcGetCurrentRemoteDescription

```
int rtcGetCurrentRemoteDescription(int pc, char *buffer, int size)
```

Retrieves the currently negotiated remote description in SDP format.

Arguments:

- `pc`: the Peer Connection identifier
- `buffer`: a user-supplied buffer to store the description
- `size`: the size of `buffer`

Return value: the length of the string copied in buffer (including the terminating null character) or a negative error code

If `buffer` is `NULL`, the description is not copied but the size is still returned.

#### rtcGetLocalDescriptionType

```
1 change: 1 addition & 0 deletions include/rtc/peerconnection.hpp
Original file line number Diff line number Diff line change
@@ -84,6 +84,7 @@ class RTC_CPP_EXPORT PeerConnection final : CheshireCat<impl::PeerConnection> {
bool hasMedia() const;
optional<Description> localDescription() const;
optional<Description> remoteDescription() const;
optional<Description> currentRemoteDescription() const;
size_t remoteMaxMessageSize() const;
optional<string> localAddress() const;
optional<string> remoteAddress() const;
1 change: 1 addition & 0 deletions include/rtc/rtc.h
Original file line number Diff line number Diff line change
@@ -216,6 +216,7 @@ RTC_C_EXPORT int rtcAddRemoteCandidate(int pc, const char *cand, const char *mid

RTC_C_EXPORT int rtcGetLocalDescription(int pc, char *buffer, int size);
RTC_C_EXPORT int rtcGetRemoteDescription(int pc, char *buffer, int size);
RTC_C_EXPORT int rtcGetCurrentRemoteDescription(int pc, char *buffer, int size);

RTC_C_EXPORT int rtcGetLocalDescriptionType(int pc, char *buffer, int size);
RTC_C_EXPORT int rtcGetRemoteDescriptionType(int pc, char *buffer, int size);
11 changes: 11 additions & 0 deletions src/capi.cpp
Original file line number Diff line number Diff line change
@@ -609,6 +609,17 @@ int rtcGetRemoteDescription(int pc, char *buffer, int size) {
});
}

int rtcGetCurrentRemoteDescription(int pc, char *buffer, int size) {
return wrap([&] {
auto peerConnection = getPeerConnection(pc);

if (auto desc = peerConnection->currentRemoteDescription())
return copyAndReturn(string(*desc), buffer, size);
else
return RTC_ERR_NOT_AVAIL;
});
}

int rtcGetLocalDescriptionType(int pc, char *buffer, int size) {
return wrap([&] {
auto peerConnection = getPeerConnection(pc);
43 changes: 37 additions & 6 deletions src/impl/peerconnection.cpp
Original file line number Diff line number Diff line change
@@ -118,6 +118,11 @@ optional<Description> PeerConnection::remoteDescription() const {
return mRemoteDescription;
}

optional<Description> PeerConnection::currentRemoteDescription() const {
std::lock_guard lock(mCurrentRemoteDescriptionMutex);
return mCurrentRemoteDescription;
}

size_t PeerConnection::remoteMaxMessageSize() const {
const size_t localMax = config.maxMessageSize.value_or(DEFAULT_LOCAL_MAX_MESSAGE_SIZE);

@@ -239,7 +244,7 @@ shared_ptr<DtlsTransport> PeerConnection::initDtlsTransport() {
throw std::logic_error("No underlying ICE transport for DTLS transport");

auto certificate = mCertificate.get();
auto verifierCallback = weak_bind(&PeerConnection::checkFingerprint, this, _1);
auto verifierCallback = weak_bind(&PeerConnection::checkFingerprint, this, _1, fingerprintAlgorithm);
auto dtlsStateChangeCallback =
[this, weak_this = weak_from_this()](DtlsTransport::State transportState) {
auto shared_this = weak_this.lock();
@@ -439,17 +444,21 @@ void PeerConnection::rollbackLocalDescription() {
}
}

bool PeerConnection::checkFingerprint(const std::string &fingerprint) const {
bool PeerConnection::checkFingerprint(const std::string &fingerprint, const CertificateFingerprint::Algorithm algorithm) {
std::lock_guard lock(mRemoteDescriptionMutex);
if (!mRemoteDescription || !mRemoteDescription->fingerprint())
return false;

if (config.disableFingerprintVerification)
return true;

auto expectedFingerprint = mRemoteDescription->fingerprint()->value;
if (expectedFingerprint == fingerprint) {
if (config.disableFingerprintVerification || expectedFingerprint == fingerprint) {
PLOG_VERBOSE << "Valid fingerprint \"" << fingerprint << "\"";

if (mCurrentRemoteDescription) {
std::lock_guard lock(mCurrentRemoteDescriptionMutex);
// update current remote description with incoming fingerprint
mCurrentRemoteDescription->setFingerprint(CertificateFingerprint{algorithm, fingerprint});
}

return true;
}

@@ -1078,6 +1087,20 @@ void PeerConnection::processLocalCandidate(Candidate candidate) {
&localCandidateCallback, std::move(candidate));
}

void PeerConnection::processCurrentRemoteDescription(Description description) {
{
// Set as current remote description
std::lock_guard lock(mCurrentRemoteDescriptionMutex);

std::vector<Candidate> existingCandidates;
if (mCurrentRemoteDescription)
existingCandidates = mCurrentRemoteDescription->extractCandidates();

mCurrentRemoteDescription.emplace(description);
mCurrentRemoteDescription->addCandidates(std::move(existingCandidates));
}
}

void PeerConnection::processRemoteDescription(Description description) {
// Update the SSRC cache for existing tracks
updateTrackSsrcCache(description);
@@ -1124,6 +1147,14 @@ void PeerConnection::processRemoteCandidate(Candidate candidate) {
candidate.resolve(Candidate::ResolveMode::Simple);
mRemoteDescription->addCandidate(candidate);
}
{
// Set as remote candidate on current remote description too
std::lock_guard lock(mCurrentRemoteDescriptionMutex);
if (mCurrentRemoteDescription->hasCandidate(candidate))
return; // already in description, ignore

mCurrentRemoteDescription->addCandidate(candidate);
}

if (candidate.isResolved()) {
iceTransport->addRemoteCandidate(std::move(candidate));
8 changes: 5 additions & 3 deletions src/impl/peerconnection.hpp
Original file line number Diff line number Diff line change
@@ -41,6 +41,7 @@ struct PeerConnection : std::enable_shared_from_this<PeerConnection> {

optional<Description> localDescription() const;
optional<Description> remoteDescription() const;
optional<Description> currentRemoteDescription() const;
size_t remoteMaxMessageSize() const;

shared_ptr<IceTransport> initIceTransport();
@@ -53,7 +54,7 @@ struct PeerConnection : std::enable_shared_from_this<PeerConnection> {

void endLocalCandidates();
void rollbackLocalDescription();
bool checkFingerprint(const std::string &fingerprint) const;
bool checkFingerprint(const std::string &fingerprint, const CertificateFingerprint::Algorithm algorithm);
void forwardMessage(message_ptr message);
void forwardMedia(message_ptr message);
void forwardBufferedAmount(uint16_t stream, size_t amount);
@@ -77,6 +78,7 @@ struct PeerConnection : std::enable_shared_from_this<PeerConnection> {
void processLocalDescription(Description description);
void processLocalCandidate(Candidate candidate);
void processRemoteDescription(Description description);
void processCurrentRemoteDescription(Description description);
void processRemoteCandidate(Candidate candidate);
string localBundleMid() const;

@@ -135,8 +137,8 @@ struct PeerConnection : std::enable_shared_from_this<PeerConnection> {

Processor mProcessor;
optional<Description> mLocalDescription, mRemoteDescription;
optional<Description> mCurrentLocalDescription;
mutable std::mutex mLocalDescriptionMutex, mRemoteDescriptionMutex;
optional<Description> mCurrentLocalDescription, mCurrentRemoteDescription;
mutable std::mutex mLocalDescriptionMutex, mRemoteDescriptionMutex, mCurrentRemoteDescriptionMutex;

shared_ptr<MediaHandler> mMediaHandler;

5 changes: 5 additions & 0 deletions src/peerconnection.cpp
Original file line number Diff line number Diff line change
@@ -69,6 +69,10 @@ optional<Description> PeerConnection::remoteDescription() const {
return impl()->remoteDescription();
}

optional<Description> PeerConnection::currentRemoteDescription() const {
return impl()->currentRemoteDescription();
}

size_t PeerConnection::remoteMaxMessageSize() const { return impl()->remoteMaxMessageSize(); }

bool PeerConnection::hasMedia() const {
@@ -243,6 +247,7 @@ void PeerConnection::setRemoteDescription(Description description) {
iceTransport->setRemoteDescription(description); // ICE transport might reject the description

impl()->processRemoteDescription(std::move(description));
impl()->processCurrentRemoteDescription(std::move(description));
impl()->changeSignalingState(newSignalingState);
signalingLock.unlock();