Move global libsrtp usage count into a singleton class
Avoids using webrtc::GlobalMutex. Since state is allocated on first use and never destroyed, we avoid an exit-time destructor when building with absl::Mutex. Bug: webrtc:11567 Change-Id: Ib9c6480ab0474e37a853460115b35d961b93009c Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/258080 Reviewed-by: Taylor Brandstetter <deadbeef@webrtc.org> Commit-Queue: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/main@{#36455}
This commit is contained in:
parent
901bf55ef7
commit
2d6c4d0712
@ -581,6 +581,7 @@ rtc_source_set("srtp_session") {
|
||||
"../rtc_base",
|
||||
"../rtc_base:checks",
|
||||
"../rtc_base:logging",
|
||||
"../rtc_base:macromagic",
|
||||
"../rtc_base:rtc_base_approved",
|
||||
"../rtc_base:stringutils",
|
||||
"../rtc_base/synchronization:mutex",
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#include "rtc_base/logging.h"
|
||||
#include "rtc_base/ssl_stream_adapter.h"
|
||||
#include "rtc_base/string_encode.h"
|
||||
#include "rtc_base/thread_annotations.h"
|
||||
#include "rtc_base/time_utils.h"
|
||||
#include "system_wrappers/include/metrics.h"
|
||||
#include "third_party/libsrtp/include/srtp.h"
|
||||
@ -34,6 +35,81 @@
|
||||
|
||||
namespace cricket {
|
||||
|
||||
namespace {
|
||||
class LibSrtpInitializer {
|
||||
public:
|
||||
// Returns singleton instance of this class. Instance created on first use,
|
||||
// and never destroyed.
|
||||
static LibSrtpInitializer& Get() {
|
||||
static LibSrtpInitializer* const instance = new LibSrtpInitializer();
|
||||
return *instance;
|
||||
}
|
||||
void ProhibitLibsrtpInitialization();
|
||||
|
||||
// These methods are responsible for initializing libsrtp (if the usage count
|
||||
// is incremented from 0 to 1) or deinitializing it (when decremented from 1
|
||||
// to 0).
|
||||
//
|
||||
// Returns true if successful (will always be successful if already inited).
|
||||
bool IncrementLibsrtpUsageCountAndMaybeInit(
|
||||
srtp_event_handler_func_t* handler);
|
||||
void DecrementLibsrtpUsageCountAndMaybeDeinit();
|
||||
|
||||
private:
|
||||
LibSrtpInitializer() = default;
|
||||
|
||||
webrtc::Mutex mutex_;
|
||||
int usage_count_ RTC_GUARDED_BY(mutex_) = 0;
|
||||
};
|
||||
|
||||
void LibSrtpInitializer::ProhibitLibsrtpInitialization() {
|
||||
webrtc::MutexLock lock(&mutex_);
|
||||
++usage_count_;
|
||||
}
|
||||
|
||||
bool LibSrtpInitializer::IncrementLibsrtpUsageCountAndMaybeInit(
|
||||
srtp_event_handler_func_t* handler) {
|
||||
webrtc::MutexLock lock(&mutex_);
|
||||
|
||||
RTC_DCHECK_GE(usage_count_, 0);
|
||||
if (usage_count_ == 0) {
|
||||
int err;
|
||||
err = srtp_init();
|
||||
if (err != srtp_err_status_ok) {
|
||||
RTC_LOG(LS_ERROR) << "Failed to init SRTP, err=" << err;
|
||||
return false;
|
||||
}
|
||||
|
||||
err = srtp_install_event_handler(handler);
|
||||
if (err != srtp_err_status_ok) {
|
||||
RTC_LOG(LS_ERROR) << "Failed to install SRTP event handler, err=" << err;
|
||||
return false;
|
||||
}
|
||||
|
||||
err = external_crypto_init();
|
||||
if (err != srtp_err_status_ok) {
|
||||
RTC_LOG(LS_ERROR) << "Failed to initialize fake auth, err=" << err;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
++usage_count_;
|
||||
return true;
|
||||
}
|
||||
|
||||
void LibSrtpInitializer::DecrementLibsrtpUsageCountAndMaybeDeinit() {
|
||||
webrtc::MutexLock lock(&mutex_);
|
||||
|
||||
RTC_DCHECK_GE(usage_count_, 1);
|
||||
if (--usage_count_ == 0) {
|
||||
int err = srtp_shutdown();
|
||||
if (err) {
|
||||
RTC_LOG(LS_ERROR) << "srtp_shutdown failed. err=" << err;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
using ::webrtc::ParseRtpSequenceNumber;
|
||||
|
||||
// One more than the maximum libsrtp error code. Required by
|
||||
@ -53,7 +129,7 @@ SrtpSession::~SrtpSession() {
|
||||
srtp_dealloc(session_);
|
||||
}
|
||||
if (inited_) {
|
||||
DecrementLibsrtpUsageCountAndMaybeDeinit();
|
||||
LibSrtpInitializer::Get().DecrementLibsrtpUsageCountAndMaybeDeinit();
|
||||
}
|
||||
}
|
||||
|
||||
@ -354,7 +430,8 @@ bool SrtpSession::SetKey(int type,
|
||||
|
||||
// This is the first time we need to actually interact with libsrtp, so
|
||||
// initialize it if needed.
|
||||
if (IncrementLibsrtpUsageCountAndMaybeInit()) {
|
||||
if (LibSrtpInitializer::Get().IncrementLibsrtpUsageCountAndMaybeInit(
|
||||
&SrtpSession::HandleEventThunk)) {
|
||||
inited_ = true;
|
||||
} else {
|
||||
return false;
|
||||
@ -377,54 +454,8 @@ bool SrtpSession::UpdateKey(int type,
|
||||
return DoSetKey(type, cs, key, len, extension_ids);
|
||||
}
|
||||
|
||||
ABSL_CONST_INIT int g_libsrtp_usage_count = 0;
|
||||
ABSL_CONST_INIT webrtc::GlobalMutex g_libsrtp_lock(absl::kConstInit);
|
||||
|
||||
void ProhibitLibsrtpInitialization() {
|
||||
webrtc::GlobalMutexLock ls(&g_libsrtp_lock);
|
||||
++g_libsrtp_usage_count;
|
||||
}
|
||||
|
||||
// static
|
||||
bool SrtpSession::IncrementLibsrtpUsageCountAndMaybeInit() {
|
||||
webrtc::GlobalMutexLock ls(&g_libsrtp_lock);
|
||||
|
||||
RTC_DCHECK_GE(g_libsrtp_usage_count, 0);
|
||||
if (g_libsrtp_usage_count == 0) {
|
||||
int err;
|
||||
err = srtp_init();
|
||||
if (err != srtp_err_status_ok) {
|
||||
RTC_LOG(LS_ERROR) << "Failed to init SRTP, err=" << err;
|
||||
return false;
|
||||
}
|
||||
|
||||
err = srtp_install_event_handler(&SrtpSession::HandleEventThunk);
|
||||
if (err != srtp_err_status_ok) {
|
||||
RTC_LOG(LS_ERROR) << "Failed to install SRTP event handler, err=" << err;
|
||||
return false;
|
||||
}
|
||||
|
||||
err = external_crypto_init();
|
||||
if (err != srtp_err_status_ok) {
|
||||
RTC_LOG(LS_ERROR) << "Failed to initialize fake auth, err=" << err;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
++g_libsrtp_usage_count;
|
||||
return true;
|
||||
}
|
||||
|
||||
// static
|
||||
void SrtpSession::DecrementLibsrtpUsageCountAndMaybeDeinit() {
|
||||
webrtc::GlobalMutexLock ls(&g_libsrtp_lock);
|
||||
|
||||
RTC_DCHECK_GE(g_libsrtp_usage_count, 1);
|
||||
if (--g_libsrtp_usage_count == 0) {
|
||||
int err = srtp_shutdown();
|
||||
if (err) {
|
||||
RTC_LOG(LS_ERROR) << "srtp_shutdown failed. err=" << err;
|
||||
}
|
||||
}
|
||||
LibSrtpInitializer::Get().ProhibitLibsrtpInitialization();
|
||||
}
|
||||
|
||||
void SrtpSession::HandleEvent(const srtp_event_data_t* ev) {
|
||||
|
||||
@ -120,14 +120,6 @@ class SrtpSession {
|
||||
// for debugging.
|
||||
void DumpPacket(const void* buf, int len, bool outbound);
|
||||
|
||||
// These methods are responsible for initializing libsrtp (if the usage count
|
||||
// is incremented from 0 to 1) or deinitializing it (when decremented from 1
|
||||
// to 0).
|
||||
//
|
||||
// Returns true if successful (will always be successful if already inited).
|
||||
static bool IncrementLibsrtpUsageCountAndMaybeInit();
|
||||
static void DecrementLibsrtpUsageCountAndMaybeDeinit();
|
||||
|
||||
void HandleEvent(const srtp_event_data_t* ev);
|
||||
static void HandleEventThunk(srtp_event_data_t* ev);
|
||||
|
||||
@ -142,7 +134,6 @@ class SrtpSession {
|
||||
int rtcp_auth_tag_len_ = 0;
|
||||
|
||||
bool inited_ = false;
|
||||
static webrtc::GlobalMutex lock_;
|
||||
int last_send_seq_num_ = -1;
|
||||
bool external_auth_active_ = false;
|
||||
bool external_auth_enabled_ = false;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user