From c3e66434faccaff218fc423ad13a287957bbfead Mon Sep 17 00:00:00 2001 From: Paul-Louis Ageneau Date: Fri, 12 May 2023 12:03:01 +0200 Subject: [PATCH 1/5] Make WebSocket recv and peek simpler and consistent with DataChannel --- src/impl/websocket.cpp | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/impl/websocket.cpp b/src/impl/websocket.cpp index 9f91a5b33..1794a4c9b 100644 --- a/src/impl/websocket.cpp +++ b/src/impl/websocket.cpp @@ -146,23 +146,13 @@ bool WebSocket::isClosed() const { return state == State::Closed; } size_t WebSocket::maxMessageSize() const { return DEFAULT_MAX_MESSAGE_SIZE; } optional WebSocket::receive() { - while (auto next = mRecvQueue.pop()) { - message_ptr message = *next; - if (message->type != Message::Control) - return to_variant(std::move(*message)); - } - return nullopt; + auto next = mRecvQueue.pop(); + return next ? std::make_optional(to_variant(std::move(**next))) : nullopt; } optional WebSocket::peek() { - while (auto next = mRecvQueue.peek()) { - message_ptr message = *next; - if (message->type != Message::Control) - return to_variant(std::move(*message)); - - mRecvQueue.pop(); - } - return nullopt; + auto next = mRecvQueue.peek(); + return next ? std::make_optional(to_variant(std::move(**next))) : nullopt; } size_t WebSocket::availableAmount() const { return mRecvQueue.amount(); } From 680d1c4c2c7267ea1207241f7fa842e3125eafe6 Mon Sep 17 00:00:00 2001 From: Paul-Louis Ageneau Date: Fri, 12 May 2023 12:10:56 +0200 Subject: [PATCH 2/5] Clean up HttpProxyTransport --- src/impl/httpproxytransport.cpp | 25 +++++++++++-------------- src/impl/httpproxytransport.hpp | 6 +++--- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/impl/httpproxytransport.cpp b/src/impl/httpproxytransport.cpp index 1ad81020c..b5034b6fd 100644 --- a/src/impl/httpproxytransport.cpp +++ b/src/impl/httpproxytransport.cpp @@ -22,10 +22,9 @@ HttpProxyTransport::HttpProxyTransport(shared_ptr lower, std::stri std::string service, state_callback stateCallback) : Transport(lower, std::move(stateCallback)), mHostname(std::move(hostname)), mService(std::move(service)) { + PLOG_DEBUG << "Initializing HTTP proxy transport"; if (!lower->isActive()) - throw std::logic_error("Http proxy creation failed, expects lower transport to be active"); - - PLOG_DEBUG << "Initializing http Proxy transport"; + throw std::logic_error("HTTP proxy transport expects the lower transport to be active"); } HttpProxyTransport::~HttpProxyTransport() { unregisterIncoming(); } @@ -43,7 +42,7 @@ bool HttpProxyTransport::send(message_ptr message) { std::lock_guard lock(mSendMutex); if (state() != State::Connected) - throw std::runtime_error("Http proxy connection is not open"); + throw std::runtime_error("HTTP proxy connection is not open"); PLOG_VERBOSE << "Send size=" << message->size(); return outgoing(message); @@ -63,7 +62,7 @@ void HttpProxyTransport::incoming(message_ptr message) { if (state() == State::Connecting) { mBuffer.insert(mBuffer.end(), message->begin(), message->end()); if (size_t len = parseHttpResponse(mBuffer.data(), mBuffer.size())) { - PLOG_INFO << "Http proxy connection open"; + PLOG_INFO << "HTTP proxy connection open"; changeState(State::Connected); mBuffer.erase(mBuffer.begin(), mBuffer.begin() + len); @@ -83,27 +82,25 @@ void HttpProxyTransport::incoming(message_ptr message) { } if (state() == State::Connected) { - PLOG_INFO << "Http Proxy disconnected"; + PLOG_INFO << "HTTP proxy disconnected"; changeState(State::Disconnected); recv(nullptr); } else { - PLOG_ERROR << "Http Proxy failed"; + PLOG_ERROR << "HTTP proxy connection failed"; changeState(State::Failed); } } bool HttpProxyTransport::sendHttpRequest() { - PLOG_DEBUG << "Sending proxy http request"; + PLOG_DEBUG << "Sending HTTP request to proxy"; const string request = generateHttpRequest(); auto data = reinterpret_cast(request.data()); return outgoing(make_message(data, data + request.size())); } -std::string HttpProxyTransport::generateHttpRequest() { - std::string out = - "CONNECT " + mHostname + ":" + mService + " HTTP/1.1\r\nHost: " + mHostname + "\r\n\r\n"; - return out; +string HttpProxyTransport::generateHttpRequest() { + return "CONNECT " + mHostname + ":" + mService + " HTTP/1.1\r\nHost: " + mHostname + "\r\n\r\n"; } size_t HttpProxyTransport::parseHttpResponse(std::byte *buffer, size_t size) { @@ -113,7 +110,7 @@ size_t HttpProxyTransport::parseHttpResponse(std::byte *buffer, size_t size) { return 0; if (lines.empty()) - throw std::runtime_error("Invalid http request for proxy"); + throw std::runtime_error("Invalid response from HTTP proxy"); std::istringstream status(std::move(lines.front())); lines.pop_front(); @@ -123,7 +120,7 @@ size_t HttpProxyTransport::parseHttpResponse(std::byte *buffer, size_t size) { status >> protocol >> code; if (code != 200) - throw std::runtime_error("Unexpected response code " + to_string(code) + " for proxy"); + throw std::runtime_error("Unexpected response code " + to_string(code) + " from HTTP proxy"); return length; } diff --git a/src/impl/httpproxytransport.hpp b/src/impl/httpproxytransport.hpp index fd673c9fc..37769be7d 100644 --- a/src/impl/httpproxytransport.hpp +++ b/src/impl/httpproxytransport.hpp @@ -35,11 +35,11 @@ class HttpProxyTransport final : public Transport, private: void incoming(message_ptr message) override; bool sendHttpRequest(); - std::string generateHttpRequest(); + string generateHttpRequest(); size_t parseHttpResponse(std::byte *buffer, size_t size); - std::string mHostname; - std::string mService; + string mHostname; + string mService; binary mBuffer; std::mutex mSendMutex; }; From 868abb4b1bd91c002dca9bc4cac3d94181ee2107 Mon Sep 17 00:00:00 2001 From: Paul-Louis Ageneau Date: Fri, 12 May 2023 12:43:15 +0200 Subject: [PATCH 3/5] Removed useless HttpProxyTransport send mutex --- src/impl/httpproxytransport.cpp | 2 -- src/impl/httpproxytransport.hpp | 1 - 2 files changed, 3 deletions(-) diff --git a/src/impl/httpproxytransport.cpp b/src/impl/httpproxytransport.cpp index b5034b6fd..0374e0ab8 100644 --- a/src/impl/httpproxytransport.cpp +++ b/src/impl/httpproxytransport.cpp @@ -39,8 +39,6 @@ void HttpProxyTransport::start() { void HttpProxyTransport::stop() { unregisterIncoming(); } bool HttpProxyTransport::send(message_ptr message) { - std::lock_guard lock(mSendMutex); - if (state() != State::Connected) throw std::runtime_error("HTTP proxy connection is not open"); diff --git a/src/impl/httpproxytransport.hpp b/src/impl/httpproxytransport.hpp index 37769be7d..d99cf7c23 100644 --- a/src/impl/httpproxytransport.hpp +++ b/src/impl/httpproxytransport.hpp @@ -41,7 +41,6 @@ class HttpProxyTransport final : public Transport, string mHostname; string mService; binary mBuffer; - std::mutex mSendMutex; }; } // namespace rtc::impl From f622d7d2e2822791107a93d25923f059e9af87f4 Mon Sep 17 00:00:00 2001 From: Paul-Louis Ageneau Date: Fri, 12 May 2023 12:32:45 +0200 Subject: [PATCH 4/5] Clean up DtlsSrtpTransport --- src/impl/dtlssrtptransport.cpp | 108 ++++++++++++++++++--------------- src/impl/dtlssrtptransport.hpp | 14 +++-- 2 files changed, 66 insertions(+), 56 deletions(-) diff --git a/src/impl/dtlssrtptransport.cpp b/src/impl/dtlssrtptransport.cpp index c9b0c4176..f450bffdb 100644 --- a/src/impl/dtlssrtptransport.cpp +++ b/src/impl/dtlssrtptransport.cpp @@ -218,28 +218,18 @@ bool DtlsSrtpTransport::demuxMessage(message_ptr message) { } } -EncryptionParams DtlsSrtpTransport::getEncryptionParams(string_view suite) { - if (suite == "SRTP_AES128_CM_SHA1_80") - return {SRTP_AES_128_KEY_LEN, SRTP_SALT_LEN, srtp_profile_aes128_cm_sha1_80}; - if (suite == "SRTP_AES128_CM_SHA1_32") - return {SRTP_AES_128_KEY_LEN, SRTP_SALT_LEN, srtp_profile_aes128_cm_sha1_32}; - if (suite == "SRTP_AEAD_AES_128_GCM") - return {SRTP_AES_128_KEY_LEN, SRTP_AEAD_SALT_LEN, srtp_profile_aead_aes_128_gcm}; - if (suite == "SRTP_AEAD_AES_256_GCM") - return {SRTP_AES_256_KEY_LEN, SRTP_AEAD_SALT_LEN, srtp_profile_aead_aes_256_gcm}; - throw std::logic_error("Unexpected SRTP suite name: " + std::string(suite)); -} - void DtlsSrtpTransport::postHandshake() { if (mInitDone) return; - const unsigned char *clientKey, *clientSalt, *serverKey, *serverSalt; + #if USE_GNUTLS PLOG_INFO << "Deriving SRTP keying material (GnuTLS)"; - unsigned int keySize = SRTP_AES_128_KEY_LEN; - unsigned int saltSize = SRTP_SALT_LEN; - auto srtpProfile = srtp_profile_aes128_cm_sha1_80; - auto keySizeWithSalt = SRTP_AES_ICM_128_KEY_LEN_WSALT; + + const srtp_profile_t srtpProfile = srtp_profile_aes128_cm_sha1_80; + const size_t keySize = SRTP_AES_128_KEY_LEN; + const size_t saltSize = SRTP_SALT_LEN; + const size_t keySizeWithSalt = SRTP_AES_ICM_128_KEY_LEN_WSALT; + const size_t materialLen = keySizeWithSalt * 2; std::vector material(materialLen); gnutls_datum_t clientKeyDatum, clientSaltDatum, serverKeyDatum, serverSaltDatum; @@ -258,59 +248,61 @@ void DtlsSrtpTransport::postHandshake() { if (serverSaltDatum.size != saltSize) throw std::logic_error("Unexpected SRTP salt size: " + to_string(serverSaltDatum.size)); - clientKey = reinterpret_cast(clientKeyDatum.data); - clientSalt = reinterpret_cast(clientSaltDatum.data); + const unsigned char *clientKey = reinterpret_cast(clientKeyDatum.data); + const unsigned char *clientSalt = reinterpret_cast(clientSaltDatum.data); + const unsigned char *serverKey = reinterpret_cast(serverKeyDatum.data); + const unsigned char *serverSalt = reinterpret_cast(serverSaltDatum.data); - serverKey = reinterpret_cast(serverKeyDatum.data); - serverSalt = reinterpret_cast(serverSaltDatum.data); #elif USE_MBEDTLS PLOG_INFO << "Deriving SRTP keying material (Mbed TLS)"; - unsigned int keySize = SRTP_AES_128_KEY_LEN; - unsigned int saltSize = SRTP_SALT_LEN; - auto srtpProfile = srtp_profile_aes128_cm_sha1_80; - auto keySizeWithSalt = SRTP_AES_ICM_128_KEY_LEN_WSALT; - mbedtls_dtls_srtp_info srtpInfo; + mbedtls_dtls_srtp_info srtpInfo; mbedtls_ssl_get_dtls_srtp_negotiation_result(&mSsl, &srtpInfo); - if (srtpInfo.private_chosen_dtls_srtp_profile != MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80) { + if (srtpInfo.private_chosen_dtls_srtp_profile != MBEDTLS_TLS_SRTP_AES128_CM_HMAC_SHA1_80) throw std::runtime_error("Failed to get SRTP profile"); - } - const size_t materialLen = keySizeWithSalt * 2; - std::vector material(materialLen); + const srtp_profile_t srtpProfile = srtp_profile_aes128_cm_sha1_80; + const size_t keySize = SRTP_AES_128_KEY_LEN; + const size_t saltSize = SRTP_SALT_LEN; + const size_t keySizeWithSalt = SRTP_AES_ICM_128_KEY_LEN_WSALT; + + if (mTlsProfile == MBEDTLS_SSL_TLS_PRF_NONE) + throw std::logic_error("TLS PRF type is not set"); + // The extractor provides the client write master key, the server write master key, the client // write master salt and the server write master salt in that order. const string label = "EXTRACTOR-dtls_srtp"; - - if (mTlsProfile == MBEDTLS_SSL_TLS_PRF_NONE) { - throw std::logic_error("Failed to get SRTP profile"); - } + const size_t materialLen = keySizeWithSalt * 2; + std::vector material(materialLen); if (mbedtls_ssl_tls_prf(mTlsProfile, reinterpret_cast(mMasterSecret), 48, label.c_str(), reinterpret_cast(mRandBytes), 64, - material.data(), materialLen) != 0) { + material.data(), materialLen) != 0) throw std::runtime_error("Failed to derive SRTP keys"); - } // Order is client key, server key, client salt, and server salt - clientKey = material.data(); - serverKey = clientKey + keySize; - clientSalt = serverKey + keySize; - serverSalt = clientSalt + saltSize; -#else + const unsigned char *clientKey = material.data(); + const unsigned char *serverKey = clientKey + keySize; + const unsigned char *clientSalt = serverKey + keySize; + const unsigned char *serverSalt = clientSalt + saltSize; + +#else // OpenSSL PLOG_INFO << "Deriving SRTP keying material (OpenSSL)"; auto profile = SSL_get_selected_srtp_profile(mSsl); if (!profile) throw std::runtime_error("Failed to get SRTP profile: " + openssl::error_string(ERR_get_error())); - PLOG_DEBUG << "srtp profile used is: " << profile->name; - auto [keySize, saltSize, srtpProfile] = getEncryptionParams(profile->name); - auto keySizeWithSalt = keySize + saltSize; - const size_t materialLen = keySizeWithSalt * 2; - std::vector material(materialLen); + + PLOG_DEBUG << "SRTP profile is: " << profile->name; + + const auto [srtpProfile, keySize, saltSize] = getProfileParamsFromName(profile->name); + const size_t keySizeWithSalt = keySize + saltSize; + // The extractor provides the client write master key, the server write master key, the client // write master salt and the server write master salt in that order. const string label = "EXTRACTOR-dtls_srtp"; + const size_t materialLen = keySizeWithSalt * 2; + std::vector material(materialLen); // returns 1 on success, 0 or -1 on failure (OpenSSL API is a complete mess...) if (SSL_export_keying_material(mSsl, material.data(), materialLen, label.c_str(), label.size(), @@ -319,11 +311,12 @@ void DtlsSrtpTransport::postHandshake() { openssl::error_string(ERR_get_error())); // Order is client key, server key, client salt, and server salt - clientKey = material.data(); - serverKey = clientKey + keySize; - clientSalt = serverKey + keySize; - serverSalt = clientSalt + saltSize; + const unsigned char *clientKey = material.data(); + const unsigned char *serverKey = clientKey + keySize; + const unsigned char *clientSalt = serverKey + keySize; + const unsigned char *serverSalt = clientSalt + saltSize; #endif + mClientSessionKey.resize(keySizeWithSalt); mServerSessionKey.resize(keySizeWithSalt); std::memcpy(mClientSessionKey.data(), clientKey, keySize); @@ -362,6 +355,21 @@ void DtlsSrtpTransport::postHandshake() { mInitDone = true; } +#if !USE_GNUTLS && !USE_MBEDTLS +ProfileParams DtlsSrtpTransport::getProfileParamsFromName(string_view name) { + if (name == "SRTP_AES128_CM_SHA1_80") + return {srtp_profile_aes128_cm_sha1_80, SRTP_AES_128_KEY_LEN, SRTP_SALT_LEN}; + if (name == "SRTP_AES128_CM_SHA1_32") + return {srtp_profile_aes128_cm_sha1_32, SRTP_AES_128_KEY_LEN, SRTP_SALT_LEN}; + if (name == "SRTP_AEAD_AES_128_GCM") + return {srtp_profile_aead_aes_128_gcm, SRTP_AES_128_KEY_LEN, SRTP_AEAD_SALT_LEN}; + if (name == "SRTP_AEAD_AES_256_GCM") + return {srtp_profile_aead_aes_256_gcm, SRTP_AES_256_KEY_LEN, SRTP_AEAD_SALT_LEN}; + + throw std::logic_error("Unknown SRTP profile name: " + std::string(name)); +} +#endif + } // namespace rtc::impl #endif diff --git a/src/impl/dtlssrtptransport.hpp b/src/impl/dtlssrtptransport.hpp index 4b9a0b453..57f8765f3 100644 --- a/src/impl/dtlssrtptransport.hpp +++ b/src/impl/dtlssrtptransport.hpp @@ -24,10 +24,10 @@ namespace rtc::impl { -struct EncryptionParams { - unsigned int keySize; - unsigned int saltSize; +struct ProfileParams { srtp_profile_t srtpProfile; + size_t keySize; + size_t saltSize; }; class DtlsSrtpTransport final : public DtlsTransport { @@ -46,11 +46,13 @@ class DtlsSrtpTransport final : public DtlsTransport { void recvMedia(message_ptr message); bool demuxMessage(message_ptr message) override; void postHandshake() override; - EncryptionParams getEncryptionParams(string_view suite); - message_callback mSrtpRecvCallback; - srtp_t mSrtpIn, mSrtpOut; +#if !USE_GNUTLS && !USE_MBEDTLS + ProfileParams getProfileParamsFromName(string_view name); +#endif + message_callback mSrtpRecvCallback; + srtp_t mSrtpIn, mSrtpOut; std::atomic mInitDone = false; std::vector mClientSessionKey; std::vector mServerSessionKey; From 50e1156618cd24c03a54d564fc1b21149bd4fd6e Mon Sep 17 00:00:00 2001 From: Paul-Louis Ageneau Date: Fri, 12 May 2023 12:45:09 +0200 Subject: [PATCH 5/5] Removed deperecated methods --- include/rtc/rtcpsrreporter.hpp | 4 ---- include/rtc/rtppacketizationconfig.hpp | 9 --------- src/rtcpsrreporter.cpp | 4 ---- src/rtppacketizationconfig.cpp | 8 -------- 4 files changed, 25 deletions(-) diff --git a/include/rtc/rtcpsrreporter.hpp b/include/rtc/rtcpsrreporter.hpp index 0a768448f..ddd2cf85e 100644 --- a/include/rtc/rtcpsrreporter.hpp +++ b/include/rtc/rtcpsrreporter.hpp @@ -33,10 +33,6 @@ class RTC_CPP_EXPORT RtcpSrReporter final : public MediaHandlerElement { uint32_t lastReportedTimestamp() const; void setNeedsToReport(); - // deprecated, do not call - [[deprecated]] void startRecording(); - [[deprecated]] uint32_t previousReportedTimestamp() const { return lastReportedTimestamp(); } - private: uint32_t mPacketCount = 0; uint32_t mPayloadOctets = 0; diff --git a/include/rtc/rtppacketizationconfig.hpp b/include/rtc/rtppacketizationconfig.hpp index 6f43d9ff2..9160d64fa 100644 --- a/include/rtc/rtppacketizationconfig.hpp +++ b/include/rtc/rtppacketizationconfig.hpp @@ -82,15 +82,6 @@ class RTC_CPP_EXPORT RtpPacketizationConfig { /// Convert seconds to timestamp /// @param seconds Number of seconds uint32_t secondsToTimestamp(double seconds); - - // deprecated, do not use - double startTime = 0.; - enum class EpochStart : uint64_t { - T1970 = 2208988800, // number of seconds between 1970 and 1900 - T1900 = 0 - }; - [[deprecated]] void setStartTime(double startTime, EpochStart epochStart, - optional startTimestamp = std::nullopt); }; } // namespace rtc diff --git a/src/rtcpsrreporter.cpp b/src/rtcpsrreporter.cpp index 5a3482dfe..39678f349 100644 --- a/src/rtcpsrreporter.cpp +++ b/src/rtcpsrreporter.cpp @@ -83,10 +83,6 @@ void RtcpSrReporter::setNeedsToReport() { mNeedsToReport = true; } -void RtcpSrReporter::startRecording() { - // Dummy -} - uint32_t RtcpSrReporter::lastReportedTimestamp() const { return mLastReportedTimestamp; } diff --git a/src/rtppacketizationconfig.cpp b/src/rtppacketizationconfig.cpp index 767d6fabb..fd9ecbeed 100644 --- a/src/rtppacketizationconfig.cpp +++ b/src/rtppacketizationconfig.cpp @@ -50,14 +50,6 @@ uint32_t RtpPacketizationConfig::secondsToTimestamp(double seconds) { return RtpPacketizationConfig::getTimestampFromSeconds(seconds, clockRate); } -void RtpPacketizationConfig::setStartTime(double startTime, EpochStart epochStart, - optional startTimestamp) { - // Deprecated dummy function - this->startTime = startTime + double(static_cast(epochStart)); - if (startTimestamp.has_value()) - this->timestamp = this->startTimestamp = startTimestamp.value(); -} - } // namespace rtc #endif /* RTC_ENABLE_MEDIA */