/* * Copyright 2017 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree.
*/
bool SrtpTransport::SendRtpPacket(rtc::CopyOnWriteBuffer* packet, const rtc::PacketOptions& options, int flags) { if (!IsSrtpActive()) {
RTC_LOG(LS_ERROR)
<< "Failed to send the packet because SRTP transport is inactive."; returnfalse;
}
rtc::PacketOptions updated_options = options;
TRACE_EVENT0("webrtc", "SRTP Encode"); bool res;
uint8_t* data = packet->MutableData(); int len = rtc::checked_cast<int>(packet->size()); // If ENABLE_EXTERNAL_AUTH flag is on then packet authentication is not done // inside libsrtp for a RTP packet. A external HMAC module will be writing // a fake HMAC value. This is ONLY done for a RTP packet. // Socket layer will update rtp sendtime extension header if present in // packet with current time before updating the HMAC. #if !defined(ENABLE_EXTERNAL_AUTH)
res = ProtectRtp(data, len, static_cast<int>(packet->capacity()), &len); #else if (!IsExternalAuthActive()) {
res = ProtectRtp(data, len, static_cast<int>(packet->capacity()), &len);
} else {
updated_options.packet_time_params.rtp_sendtime_extension_id =
rtp_abs_sendtime_extn_id_;
res = ProtectRtp(data, len, static_cast<int>(packet->capacity()), &len,
&updated_options.packet_time_params.srtp_packet_index); // If protection succeeds, let's get auth params from srtp. if (res) {
uint8_t* auth_key = nullptr; int key_len = 0;
res = GetRtpAuthParams(
&auth_key, &key_len,
&updated_options.packet_time_params.srtp_auth_tag_len); if (res) {
updated_options.packet_time_params.srtp_auth_key.resize(key_len);
updated_options.packet_time_params.srtp_auth_key.assign(
auth_key, auth_key + key_len);
}
}
} #endif if (!res) {
uint16_t seq_num = ParseRtpSequenceNumber(*packet);
uint32_t ssrc = ParseRtpSsrc(*packet);
RTC_LOG(LS_ERROR) << "Failed to protect RTP packet: size=" << len
<< ", seqnum=" << seq_num << ", SSRC=" << ssrc; returnfalse;
}
// Update the length of the packet now that we've added the auth tag.
packet->SetSize(len); return SendPacket(/*rtcp=*/false, packet, updated_options, flags);
}
bool SrtpTransport::SendRtcpPacket(rtc::CopyOnWriteBuffer* packet, const rtc::PacketOptions& options, int flags) { if (!IsSrtpActive()) {
RTC_LOG(LS_ERROR)
<< "Failed to send the packet because SRTP transport is inactive."; returnfalse;
}
TRACE_EVENT0("webrtc", "SRTP Encode");
uint8_t* data = packet->MutableData(); int len = rtc::checked_cast<int>(packet->size()); if (!ProtectRtcp(data, len, static_cast<int>(packet->capacity()), &len)) { int type = -1;
cricket::GetRtcpType(data, len, &type);
RTC_LOG(LS_ERROR) << "Failed to protect RTCP packet: size=" << len
<< ", type=" << type; returnfalse;
} // Update the length of the packet now that we've added the auth tag.
packet->SetSize(len);
void SrtpTransport::OnRtpPacketReceived(const rtc::ReceivedPacket& packet) {
TRACE_EVENT0("webrtc", "SrtpTransport::OnRtpPacketReceived"); if (!IsSrtpActive()) {
RTC_LOG(LS_WARNING)
<< "Inactive SRTP transport received an RTP packet. Drop it."; return;
}
rtc::CopyOnWriteBuffer payload(packet.payload()); char* data = payload.MutableData<char>(); int len = rtc::checked_cast<int>(payload.size()); if (!UnprotectRtp(data, len, &len)) { // Limit the error logging to avoid excessive logs when there are lots of // bad packets. constint kFailureLogThrottleCount = 100; if (decryption_failure_count_ % kFailureLogThrottleCount == 0) {
RTC_LOG(LS_ERROR) << "Failed to unprotect RTP packet: size=" << len
<< ", seqnum=" << ParseRtpSequenceNumber(payload)
<< ", SSRC=" << ParseRtpSsrc(payload)
<< ", previous failure count: "
<< decryption_failure_count_;
}
++decryption_failure_count_; return;
}
payload.SetSize(len);
DemuxPacket(std::move(payload),
packet.arrival_time().value_or(Timestamp::MinusInfinity()),
packet.ecn());
}
void SrtpTransport::OnRtcpPacketReceived(const rtc::ReceivedPacket& packet) {
TRACE_EVENT0("webrtc", "SrtpTransport::OnRtcpPacketReceived"); if (!IsSrtpActive()) {
RTC_LOG(LS_WARNING)
<< "Inactive SRTP transport received an RTCP packet. Drop it."; return;
}
rtc::CopyOnWriteBuffer payload(packet.payload()); char* data = payload.MutableData<char>(); int len = rtc::checked_cast<int>(payload.size()); if (!UnprotectRtcp(data, len, &len)) { int type = -1;
cricket::GetRtcpType(data, len, &type);
RTC_LOG(LS_ERROR) << "Failed to unprotect RTCP packet: size=" << len
<< ", type=" << type; return;
}
payload.SetSize(len);
SendRtcpPacketReceived(
&payload, packet.arrival_time() ? packet.arrival_time()->us() : -1);
}
void SrtpTransport::OnNetworkRouteChanged(
std::optional<rtc::NetworkRoute> network_route) { // Only append the SRTP overhead when there is a selected network route. if (network_route) { int srtp_overhead = 0; if (IsSrtpActive()) {
GetSrtpOverhead(&srtp_overhead);
}
network_route->packet_overhead += srtp_overhead;
}
SendNetworkRouteChanged(network_route);
}
bool SrtpTransport::SetRtpParams(int send_crypto_suite, const rtc::ZeroOnFreeBuffer<uint8_t>& send_key, const std::vector<int>& send_extension_ids, int recv_crypto_suite, const rtc::ZeroOnFreeBuffer<uint8_t>& recv_key, const std::vector<int>& recv_extension_ids) { // If parameters are being set for the first time, we should create new SRTP // sessions and call "SetSend/SetReceive". Otherwise we should call // "UpdateSend"/"UpdateReceive" on the existing sessions, which will // internally call "srtp_update". bool new_sessions = false; if (!send_session_) {
RTC_DCHECK(!recv_session_);
CreateSrtpSessions();
new_sessions = true;
} bool ret = new_sessions
? send_session_->SetSend(send_crypto_suite, send_key,
send_extension_ids)
: send_session_->UpdateSend(send_crypto_suite, send_key,
send_extension_ids); if (!ret) {
ResetParams(); returnfalse;
}
ret = new_sessions ? recv_session_->SetReceive(recv_crypto_suite, recv_key,
recv_extension_ids)
: recv_session_->UpdateReceive(recv_crypto_suite, recv_key,
recv_extension_ids); if (!ret) {
ResetParams(); returnfalse;
}
bool SrtpTransport::SetRtcpParams( int send_crypto_suite, const rtc::ZeroOnFreeBuffer<uint8_t>& send_key, const std::vector<int>& send_extension_ids, int recv_crypto_suite, const rtc::ZeroOnFreeBuffer<uint8_t>& recv_key, const std::vector<int>& recv_extension_ids) { // This can only be called once, but can be safely called after // SetRtpParams if (send_rtcp_session_ || recv_rtcp_session_) {
RTC_LOG(LS_ERROR) << "Tried to set SRTCP Params when filter already active"; returnfalse;
}
send_rtcp_session_.reset(new cricket::SrtpSession(field_trials_)); if (!send_rtcp_session_->SetSend(send_crypto_suite, send_key,
send_extension_ids)) { returnfalse;
}
recv_rtcp_session_.reset(new cricket::SrtpSession(field_trials_)); if (!recv_rtcp_session_->SetReceive(recv_crypto_suite, recv_key,
recv_extension_ids)) { returnfalse;
}
void SrtpTransport::MaybeUpdateWritableState() { bool writable = IsWritable(/*rtcp=*/true) && IsWritable(/*rtcp=*/false); // Only fire the signal if the writable state changes. if (writable_ != writable) {
writable_ = writable;
SendWritableState(writable_);
}
}
bool SrtpTransport::UnregisterRtpDemuxerSink(RtpPacketSinkInterface* sink) { if (recv_session_ &&
field_trials_.IsEnabled("WebRTC-SrtpRemoveReceiveStream")) { // Remove the SSRCs explicitly registered with the demuxer // (via SDP negotiation) from the SRTP session. for (constauto ssrc : GetSsrcsForSink(sink)) { if (!recv_session_->RemoveSsrcFromSession(ssrc)) {
RTC_LOG(LS_WARNING)
<< "Could not remove SSRC " << ssrc << " from SRTP session.";
}
}
} return RtpTransport::UnregisterRtpDemuxerSink(sink);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.