Skip to content

Commit

Permalink
Add proper synchronization and clean up after #1206
Browse files Browse the repository at this point in the history
  • Loading branch information
paullouisageneau committed Jun 14, 2024
1 parent b756b5a commit b6262ac
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 27 deletions.
44 changes: 23 additions & 21 deletions src/impl/peerconnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,24 +46,22 @@ static LogCounter

const string PemBeginCertificateTag = "-----BEGIN CERTIFICATE-----";

PeerConnection::PeerConnection(Configuration config_)
: config(std::move(config_)) {
PeerConnection::PeerConnection(Configuration config_) : config(std::move(config_)) {
PLOG_VERBOSE << "Creating PeerConnection";


if (config.certificatePemFile && config.keyPemFile) {
std::promise<certificate_ptr> cert;
cert.set_value(std::make_shared<Certificate>(
config.certificatePemFile->find(PemBeginCertificateTag) != string::npos
? Certificate::FromString(*config.certificatePemFile, *config.keyPemFile)
: Certificate::FromFile(*config.certificatePemFile, *config.keyPemFile,
config.keyPemPass.value_or(""))));
config.certificatePemFile->find(PemBeginCertificateTag) != string::npos
? Certificate::FromString(*config.certificatePemFile, *config.keyPemFile)
: Certificate::FromFile(*config.certificatePemFile, *config.keyPemFile,
config.keyPemPass.value_or(""))));
mCertificate = cert.get_future();
} else if (!config.certificatePemFile && !config.keyPemFile) {
mCertificate = make_certificate(config.certificateType);
} else {
throw std::invalid_argument(
"Either none or both certificate and key PEM files must be specified");
"Either none or both certificate and key PEM files must be specified");
}

if (config.portRangeEnd && config.portRangeBegin > config.portRangeEnd)
Expand Down Expand Up @@ -229,13 +227,15 @@ shared_ptr<DtlsTransport> PeerConnection::initDtlsTransport() {

PLOG_VERBOSE << "Starting DTLS transport";

auto fingerprintAlgorithm = CertificateFingerprint::Algorithm::Sha256;
if (auto remote = remoteDescription(); remote && remote->fingerprint()) {
fingerprintAlgorithm = remote->fingerprint()->algorithm;
CertificateFingerprint::Algorithm fingerprintAlgorithm;
{
std::lock_guard lock(mRemoteDescription);
if (mRemoteDescription && mRemoteDescription->fingerprint()) {
mRemoteFingerprintAlgorithm = mRemoteDescription->fingerprint()->algorithm;
}
fingerprintAlgorithm = mRemoteFingerprintAlgorithm;
}

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 @@ -443,23 +443,24 @@ void PeerConnection::rollbackLocalDescription() {

bool PeerConnection::checkFingerprint(const std::string &fingerprint) {
std::lock_guard lock(mRemoteDescriptionMutex);
if (!mRemoteDescription || !mRemoteDescription->fingerprint())
mRemoteFingerprint = fingerprint;

if (!mRemoteDescription || !mRemoteDescription->fingerprint() || mRemoteFingerprintAlgorithm != mRemoteDescription->fingerprint()->algorithm)
return false;

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

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

PLOG_ERROR << "Invalid fingerprint \"" << fingerprint << "\", expected \"" << expectedFingerprint << "\"";
PLOG_ERROR << "Invalid fingerprint \"" << fingerprint << "\", expected \""
<< expectedFingerprint << "\"";
return false;
}

Expand Down Expand Up @@ -555,7 +556,7 @@ void PeerConnection::forwardMedia([[maybe_unused]] message_ptr message) {
void PeerConnection::dispatchMedia([[maybe_unused]] message_ptr message) {
#if RTC_ENABLE_MEDIA
std::shared_lock lock(mTracksMutex); // read-only
if (mTrackLines.size()==1) {
if (mTrackLines.size() == 1) {
if (auto track = mTrackLines.front().lock())
track->incoming(message);
return;
Expand Down Expand Up @@ -742,7 +743,7 @@ void PeerConnection::iterateDataChannels(
{
std::shared_lock lock(mDataChannelsMutex); // read-only
locked.reserve(mDataChannels.size());
for(auto it = mDataChannels.begin(); it != mDataChannels.end(); ++it) {
for (auto it = mDataChannels.begin(); it != mDataChannels.end(); ++it) {
auto channel = it->second.lock();
if (channel && !channel->isClosed())
locked.push_back(std::move(channel));
Expand Down Expand Up @@ -811,7 +812,7 @@ void PeerConnection::iterateTracks(std::function<void(shared_ptr<Track> track)>
{
std::shared_lock lock(mTracksMutex); // read-only
locked.reserve(mTrackLines.size());
for(auto it = mTrackLines.begin(); it != mTrackLines.end(); ++it) {
for (auto it = mTrackLines.begin(); it != mTrackLines.end(); ++it) {
auto track = it->lock();
if (track && !track->isClosed())
locked.push_back(std::move(track));
Expand Down Expand Up @@ -1308,6 +1309,7 @@ void PeerConnection::resetCallbacks() {
}

CertificateFingerprint PeerConnection::remoteFingerprint() {
std::lock_guard lock(mRemoteDescriptionMutex);
if (mRemoteFingerprint)
return {CertificateFingerprint{mRemoteFingerprintAlgorithm, *mRemoteFingerprint}};
else
Expand Down
14 changes: 8 additions & 6 deletions 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
Expand Down Expand Up @@ -135,12 +136,16 @@ struct PeerConnection : std::enable_shared_from_this<PeerConnection> {
future_certificate_ptr mCertificate;

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

shared_ptr<MediaHandler> mMediaHandler;
optional<Description> mRemoteDescription;
CertificateFingerprint::Algorithm mRemoteFingerprintAlgorithm = CertificateFingerprint::Algorithm::Sha256;
optional<string> mRemoteFingerprint;
mutable std::mutex mRemoteDescriptionMutex;

shared_ptr<MediaHandler> mMediaHandler;
mutable std::shared_mutex mMediaHandlerMutex;

shared_ptr<IceTransport> mIceTransport;
Expand All @@ -158,9 +163,6 @@ 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

0 comments on commit b6262ac

Please sign in to comment.