SrtpChannelソースコード分析

 

// 初始化成员变量
SrtpChannel::SrtpChannel() {
  boost::mutex::scoped_lock lock(SrtpChannel::sessionMutex_);
  if (SrtpChannel::initialized != true) {
    int res = srtp_init();
    ELOG_DEBUG("Initialized SRTP library %d", res);
    SrtpChannel::initialized = true;
  }

  active_ = false;
  send_session_ = NULL;
  receive_session_ = NULL;
}

// 释放send_session_和receive_session_实例
SrtpChannel::~SrtpChannel() {
  active_ = false;
  if (send_session_ != NULL) {
    srtp_dealloc(send_session_);
    send_session_ = NULL;
  }
  if (receive_session_ != NULL) {
    srtp_dealloc(receive_session_);
    receive_session_ = NULL;
  }
}

// 通过key创建send_session_和receive_session_实例
bool SrtpChannel::setRtpParams(const std::string &sendingKey, const std::string &receivingKey) {
  ELOG_DEBUG("Configuring srtp local key %s remote key %s", sendingKey.c_str(), receivingKey.c_str());
  if (configureSrtpSession(&send_session_,    sendingKey,   SENDING) &&
      configureSrtpSession(&receive_session_, receivingKey, RECEIVING)) {
    active_ = true;
    return active_;
  }
  return false;
}

bool SrtpChannel::setRtcpParams(const std::string &sendingKey, const std::string &receivingKey) {
    return 0;
}

// srtp的加密过程
int SrtpChannel::protectRtp(char* buffer, int *len) {
  if (!active_) {
    return -1;
  }
  int val = srtp_protect(send_session_, buffer, len);
  if (val == 0) {
    return 0;
  } else {
    RtcpHeader* head = reinterpret_cast<RtcpHeader*>(buffer);
    RtpHeader* headrtp = reinterpret_cast<RtpHeader*>(buffer);

    if (val != 10) {  // Do not warn about reply errors
      ELOG_DEBUG("Error SrtpChannel::protectRtp %u packettype %d pt %d seqnum %u",
                 val, head->packettype, headrtp->payloadtype, headrtp->seqnum);
    }
    return -1;
  }
}

// srtp的解密过程
int SrtpChannel::unprotectRtp(char* buffer, int *len) {
  if (!active_) {
    return -1;
  }
  int val = srtp_unprotect(receive_session_, reinterpret_cast<char*>(buffer), len);
  if (val == 0) {
    return 0;
  } else {
    RtcpHeader* head = reinterpret_cast<RtcpHeader*>(buffer);
    RtpHeader* headrtp = reinterpret_cast<RtpHeader*>(buffer);
    if (val != 10) {  // Do not warn about reply errors
      ELOG_DEBUG("Error SrtpChannel::unprotectRtp %u packettype %d pt %d",
                 val, head->packettype, headrtp->payloadtype);
    }
    return -1;
  }
}

// srtcp的加密过程
int SrtpChannel::protectRtcp(char* buffer, int *len) {
  if (!active_) {
    return -1;
  }
  int val = srtp_protect_rtcp(send_session_, reinterpret_cast<char*>(buffer), len);
  if (val == 0) {
    return 0;
  } else {
    RtcpHeader* head = reinterpret_cast<RtcpHeader*>(buffer);
    if (val != 10) {  // Do not warn about reply errors
      ELOG_DEBUG("Error SrtpChannel::protectRtcp %upackettype %d ", val, head->packettype);
    }
    return -1;
  }
}

// srtcp的解密过程
int SrtpChannel::unprotectRtcp(char* buffer, int *len) {
  if (!active_) {
    return -1;
  }
  int val = srtp_unprotect_rtcp(receive_session_, buffer, len);
  if (val == 0) {
    return 0;
  } else {
    if (val != 10) {  // Do not warn about reply errors
      ELOG_DEBUG("Error SrtpChannel::unprotectRtcp %u", val);
    }
    return -1;
  }
}

// 通过传入的key,创建srtp session
bool SrtpChannel::configureSrtpSession(srtp_t *session, const std::string &key, enum TransmissionType type) {
  srtp_policy_t policy;
  memset(&policy, 0, sizeof(policy));
  srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtp);
  srtp_crypto_policy_set_aes_cm_128_hmac_sha1_80(&policy.rtcp);
  if (type == SENDING) {
    policy.ssrc.type = ssrc_any_outbound;
  } else {
    policy.ssrc.type = ssrc_any_inbound;
  }

  policy.ssrc.value = 0;
  policy.window_size = 1024;
  policy.allow_repeat_tx = 1;
  policy.next = NULL;
  // ELOG_DEBUG("auth_tag_len %d", policy.rtp.auth_tag_len);

  gsize len = 0;
  uint8_t *akey = reinterpret_cast<uint8_t*>(g_base64_decode(reinterpret_cast<const gchar*>(key.c_str()), &len));
  ELOG_DEBUG("set master key/salt to %s/", octet_string_hex_string(akey, 16).c_str());
  // allocate and initialize the SRTP session
  policy.key = akey;
  int res = srtp_create(session, &policy);
  if (res != 0) {
    ELOG_ERROR("Failed to create srtp session with %s, %d", octet_string_hex_string(akey, 16).c_str(), res);
  }
  g_free(akey); akey = NULL;
  return res != 0? false:true;
}

 

おすすめ

転載: blog.csdn.net/tong5956/article/details/108362750