zrtp: Fix race condition in performing DH

This commit is contained in:
Joni Räsänen 2022-08-23 16:25:57 +03:00
parent f66d78aa09
commit 8b05132deb
4 changed files with 45 additions and 18 deletions

View File

@ -125,8 +125,11 @@ typedef enum RTP_FLAGS {
enum RTP_CTX_ENABLE_FLAGS {
RCE_NO_FLAGS = 0,
/* Obsolete */
// Obsolete flags
RCE_SYSTEM_CALL_DISPATCHER = 0,
RCE_NO_H26X_INTRA_DELAY = 0,
RCE_NO_H26X_SCL = 0,
RCE_H26X_NO_DEPENDENCY_ENFORCEMENT = 0,
/** Use SRTP for this connection */
RCE_SRTP = 1,
@ -151,21 +154,12 @@ enum RTP_CTX_ENABLE_FLAGS {
* with RCE_SRTP_KMNGMNT_ZRTP */
RCE_SRTP_KMNGMNT_USER = 1 << 2,
/** Obsolete */
RCE_NO_H26X_INTRA_DELAY = 0,
/** Obsolete */
RCE_NO_H26X_SCL = 0,
/** By default, the RTP packet payload does not include the start code prefixes.
* Use this flag to prepend the 4-byte start code (0x00000001) to each received
* H26x frame, so there is no difference with sender input. Recommended in
* most cases. */
RCE_H26X_PREPEND_SC = 1 << 3,
/** Obsolete */
RCE_H26X_NO_DEPENDENCY_ENFORCEMENT = 0,
/** Use this flag to discard inter frames that don't have their previous dependencies
arrived. Does not work if the dependencies are not in monotonic order. */
RCE_H26X_DEPENDENCY_ENFORCEMENT = 1 << 4,
@ -227,9 +221,12 @@ enum RTP_CTX_ENABLE_FLAGS {
/** Use 256-bit keys with SRTP */
RCE_SRTP_KEYSIZE_256 = 1 << 14,
RCE_LAST = 1 << 15,
RCE_ZRTP_MULTISTREAM_NO_DH = 1 << 16,
RCE_LAST = 1 << 17,
};
/**
* \enum RTP_CTX_CONFIGURATION_FLAGS
*

View File

@ -261,7 +261,9 @@ rtp_error_t uvgrtp::media_stream::init(std::shared_ptr<uvgrtp::zrtp> zrtp)
rtp_ = std::shared_ptr<uvgrtp::rtp> (new uvgrtp::rtp(fmt_));
if ((ret = zrtp->init(rtp_->get_ssrc(), socket_, addr_out_)) != RTP_OK) {
bool perform_dh = !(rce_flags_ & RCE_ZRTP_MULTISTREAM_NO_DH);
if ((ret = zrtp->init(rtp_->get_ssrc(), socket_, addr_out_, perform_dh)) != RTP_OK) {
UVG_LOG_WARN("Failed to initialize ZRTP for media stream!");
return free_resources(ret);
}

View File

@ -616,13 +616,41 @@ rtp_error_t uvgrtp::zrtp::initiator_finalize_session()
return RTP_TIMEOUT;
}
rtp_error_t uvgrtp::zrtp::init(uint32_t ssrc, std::shared_ptr<uvgrtp::socket> socket, sockaddr_in& addr)
rtp_error_t uvgrtp::zrtp::init(uint32_t ssrc, std::shared_ptr<uvgrtp::socket> socket, sockaddr_in& addr, bool perform_dh)
{
std::lock_guard<std::mutex> lock(zrtp_mtx_);
rtp_error_t ret = RTP_OK;
if (!initialized_)
return init_dhm(ssrc, socket, addr);
return init_msm(ssrc, socket, addr);
if (perform_dh)
{
zrtp_mtx_.lock();
if (initialized_)
{
UVG_LOG_WARN("ZRTP multistream mode not used. Please use RCE_ZRTP_MULTISTREAM_NO_DH flag " \
"to select which streams should not perform DH");
}
// perform Diffie-Helmann (DH)
ret = init_dhm(ssrc, socket, addr);
zrtp_mtx_.unlock();
}
else
{
if (!initialized_)
{
UVG_LOG_DEBUG("Sleeping a non-DH performing stream until DH has finished");
}
while (!initialized_)
{
std::this_thread::sleep_for(std::chrono::milliseconds(5));
}
// multistream mode
ret = init_msm(ssrc, socket, addr);
}
return ret;
}
rtp_error_t uvgrtp::zrtp::init_dhm(uint32_t ssrc, std::shared_ptr<uvgrtp::socket> socket, sockaddr_in& addr)

View File

@ -42,7 +42,7 @@ namespace uvgrtp {
*
* Return RTP_OK on success
* Return RTP_TIMEOUT if remote did not send messages in timely manner */
rtp_error_t init(uint32_t ssrc, std::shared_ptr<uvgrtp::socket> socket, sockaddr_in& addr);
rtp_error_t init(uint32_t ssrc, std::shared_ptr<uvgrtp::socket> socket, sockaddr_in& addr, bool perform_dh);
/* Get SRTP keys for the session that was just initialized
*