webrtc中的srtp加密模块

一:加密模块:

在webrtc中,通过开源的libSRTP进行RTP的数据加密;

 

webrtc为了方便,进行的封装;

实现了加密,解密;

 

src\pc\srtpsession.h;

// Class that wraps a libSRTP session.

class SrtpSession

 

 

SrtpTransport::SendRtpPacket

 

 

 

二:加密逻辑:

 

BaseChannel::BaseChannel(rtc::Thread* worker_thread,
                         rtc::Thread* network_thread,
                         rtc::Thread* signaling_thread,
                         std::unique_ptr media_channel,
                         const std::string& content_name,
                         bool rtcp_mux_required,
                         bool srtp_required)
    : worker_thread_(worker_thread),
      network_thread_(network_thread),
      signaling_thread_(signaling_thread),
      content_name_(content_name),
      rtcp_mux_required_(rtcp_mux_required),
      unencrypted_rtp_transport_(
          rtc::MakeUnique(rtcp_mux_required)),//创建未加密的unencrypted_rtp_transport_;
      srtp_required_(srtp_required),//是否启用srtp加密;
      media_channel_(std::move(media_channel)) {
  RTC_DCHECK_RUN_ON(worker_thread_);
  rtp_transport_ = unencrypted_rtp_transport_.get(); //赋值;
  ConnectToRtpTransport();

......

}

srtp_required: srtp加密是否启用;

 

 

//EnableSdes_n:这个函数仅启用Srtp;

void BaseChannel::EnableSdes_n() {
  if (sdes_transport_) {
    return;
  }
  // DtlsSrtpTransport and SrtpTransport shouldn't be enabled at the same
  // time.

  RTC_DCHECK(!dtls_srtp_transport_);
  RTC_DCHECK(unencrypted_rtp_transport_);
  sdes_transport_ = rtc::MakeUnique(
      std::move(unencrypted_rtp_transport_)); //创建srtp transport,未加密的transport作为构造参数;

  sdes_transport_接收到未加密的数据,加密,然后输出;
#if defined(ENABLE_EXTERNAL_AUTH)
  sdes_transport_->EnableExternalAuth();
#endif
  SetRtpTransport(sdes_transport_.get());
  RTC_LOG(LS_INFO) << "Wrapping RtpTransport in SrtpTransport.";
}

 

和上面的函数一样,EnableDtlsSrtp_n:这个启用 Dtls + Srtp;

void BaseChannel::EnableDtlsSrtp_n() 

{

  // DtlsSrtpTransport and SrtpTransport shouldn't be enabled at the same
  // time.

 

}

 

 

 

两个设置函数:

  void SetTransports(DtlsTransportInternal* rtp_dtls_transport,
                     DtlsTransportInternal* rtcp_dtls_transport); //设置加密transport;
  void SetTransports(rtc::PacketTransportInternal* rtp_packet_transport,
                     rtc::PacketTransportInternal* rtcp_packet_transport); //设置一般transport;

 

看一个源码:

 

void BaseChannel::SetTransports(DtlsTransportInternal* rtp_dtls_transport,
                                DtlsTransportInternal* rtcp_dtls_transport) {
  network_thread_->Invoke(
      RTC_FROM_HERE,
      Bind(&BaseChannel::SetTransports_n, this, rtp_dtls_transport,
           rtcp_dtls_transport, rtp_dtls_transport, rtcp_dtls_transport));
}

void BaseChannel::SetTransports(
    rtc::PacketTransportInternal* rtp_packet_transport,
    rtc::PacketTransportInternal* rtcp_packet_transport) {
  network_thread_->Invoke(
      RTC_FROM_HERE, Bind(&BaseChannel::SetTransports_n, this, nullptr, nullptr, //不加密的话,这两个参数设置为空,看SetTransports_n函数;
                          rtp_packet_transport, rtcp_packet_transport));
}

 

 

void BaseChannel::SetTransports_n(
    DtlsTransportInternal* rtp_dtls_transport,  //非加密,为空;
    DtlsTransportInternal* rtcp_dtls_transport, //非加密,为空;
    rtc::PacketTransportInternal* rtp_packet_transport,
    rtc::PacketTransportInternal* rtcp_packet_transport) {
  RTC_DCHECK(network_thread_->IsCurrent());
  // Validate some assertions about the input.
  RTC_DCHECK(rtp_packet_transport);
  RTC_DCHECK_EQ(NeedsRtcpTransport(), rtcp_packet_transport != nullptr);
  if (rtp_dtls_transport || rtcp_dtls_transport) {
    // DTLS/non-DTLS pointers should be to the same object.
    RTC_DCHECK(rtp_dtls_transport == rtp_packet_transport);
    RTC_DCHECK(rtcp_dtls_transport == rtcp_packet_transport);
    // Can't go from non-DTLS to DTLS.
    RTC_DCHECK(!rtp_transport_->rtp_packet_transport() || rtp_dtls_transport_);
  } else {
    // Can't go from DTLS to non-DTLS.
    RTC_DCHECK(!rtp_dtls_transport_);
  }
  // Transport names should be the same.
  if (rtp_dtls_transport && rtcp_dtls_transport) {
    RTC_DCHECK(rtp_dtls_transport->transport_name() ==
               rtcp_dtls_transport->transport_name());
  }

  if (rtp_packet_transport == rtp_transport_->rtp_packet_transport()) {
    // Nothing to do if transport isn't changing.
    return;
  }

  std::string debug_name;
  if (rtp_dtls_transport) {
    transport_name_ = rtp_dtls_transport->transport_name();
    debug_name = transport_name_;
  } else {
    debug_name = rtp_packet_transport->transport_name();
  }
  // If this BaseChannel doesn't require RTCP mux and we haven't fully
  // negotiated RTCP mux, we need an RTCP transport.
  if (rtcp_packet_transport) {
    RTC_LOG(LS_INFO) << "Setting RTCP Transport for " << content_name()
                     << " on " << debug_name << " transport "
                     << rtcp_packet_transport;
    SetTransport_n(/*rtcp=*/true, rtcp_dtls_transport, rtcp_packet_transport);
  }

  RTC_LOG(LS_INFO) << "Setting RTP Transport for " << content_name() << " on "
                   << debug_name << " transport " << rtp_packet_transport;
  SetTransport_n(/*rtcp=*/false, rtp_dtls_transport, rtp_packet_transport);

  // Set DtlsTransport/PacketTransport for RTP-level transport.
  if ((rtp_dtls_transport_ || rtcp_dtls_transport_) && dtls_srtp_transport_) {
    // When setting the transport with non-null |dtls_srtp_transport_|, we are
    // using DTLS-SRTP. This could happen for bundling. If the
    // |dtls_srtp_transport| is null, we cannot tell if it doing DTLS-SRTP or
    // SDES until the description is set. So don't call |EnableDtlsSrtp_n| here.
    dtls_srtp_transport_->SetDtlsTransports(rtp_dtls_transport,
                                            rtcp_dtls_transport);

  } else {
    rtp_transport_->SetRtpPacketTransport(rtp_packet_transport);
    rtp_transport_->SetRtcpPacketTransport(rtcp_packet_transport);

  }

  // Update aggregate writable/ready-to-send state between RTP and RTCP upon
  // setting new transport channels.
  UpdateWritableState_n();
}

void BaseChannel::SetTransports_n: 根据参数设置最后应用的transport;

 

 

 

你可能感兴趣的:(WebRTC)