mirror of
https://github.com/ossrs/srs.git
synced 2025-03-09 15:49:59 +00:00
RTC: Cache DTLS packet and fast retransmit it.
This commit is contained in:
parent
dd9a9b05d1
commit
a5cefbf092
2 changed files with 31 additions and 7 deletions
|
@ -33,6 +33,7 @@ using namespace std;
|
||||||
#include <srs_core_autofree.hpp>
|
#include <srs_core_autofree.hpp>
|
||||||
#include <srs_rtmp_stack.hpp>
|
#include <srs_rtmp_stack.hpp>
|
||||||
#include <srs_app_utility.hpp>
|
#include <srs_app_utility.hpp>
|
||||||
|
#include <srs_kernel_rtc_rtp.hpp>
|
||||||
|
|
||||||
#include <srtp2/srtp.h>
|
#include <srtp2/srtp.h>
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
|
@ -251,6 +252,9 @@ SrsDtls::SrsDtls(ISrsDtlsCallback* cb)
|
||||||
callback = cb;
|
callback = cb;
|
||||||
handshake_done_for_us = false;
|
handshake_done_for_us = false;
|
||||||
|
|
||||||
|
last_outgoing_packet_cache = new uint8_t[kRtpPacketSize];
|
||||||
|
nn_last_outgoing_packet = 0;
|
||||||
|
|
||||||
role_ = SrsDtlsRoleServer;
|
role_ = SrsDtlsRoleServer;
|
||||||
version_ = SrsDtlsVersionAuto;
|
version_ = SrsDtlsVersionAuto;
|
||||||
}
|
}
|
||||||
|
@ -267,6 +271,8 @@ SrsDtls::~SrsDtls()
|
||||||
SSL_free(dtls);
|
SSL_free(dtls);
|
||||||
dtls = NULL;
|
dtls = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
srs_freepa(last_outgoing_packet_cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_error_t SrsDtls::initialize(std::string role, std::string version)
|
srs_error_t SrsDtls::initialize(std::string role, std::string version)
|
||||||
|
@ -296,7 +302,7 @@ srs_error_t SrsDtls::initialize(std::string role, std::string version)
|
||||||
if (role == "active") {
|
if (role == "active") {
|
||||||
// Dtls setup active, as client role.
|
// Dtls setup active, as client role.
|
||||||
SSL_set_connect_state(dtls);
|
SSL_set_connect_state(dtls);
|
||||||
SSL_set_max_send_fragment(dtls, 1500);
|
SSL_set_max_send_fragment(dtls, kRtpPacketSize);
|
||||||
} else {
|
} else {
|
||||||
// Dtls setup passive, as server role.
|
// Dtls setup passive, as server role.
|
||||||
SSL_set_accept_state(dtls);
|
SSL_set_accept_state(dtls);
|
||||||
|
@ -417,7 +423,7 @@ srs_error_t SrsDtls::do_on_dtls(char* data, int nb_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trace the detail of DTLS packet.
|
// Trace the detail of DTLS packet.
|
||||||
trace((uint8_t*)data, nb_data, true, SSL_ERROR_NONE);
|
trace((uint8_t*)data, nb_data, true, SSL_ERROR_NONE, false);
|
||||||
|
|
||||||
if ((r0 = BIO_write(bio_in, data, nb_data)) <= 0) {
|
if ((r0 = BIO_write(bio_in, data, nb_data)) <= 0) {
|
||||||
// TODO: 0 or -1 maybe block, use BIO_should_retry to check.
|
// TODO: 0 or -1 maybe block, use BIO_should_retry to check.
|
||||||
|
@ -477,8 +483,22 @@ srs_error_t SrsDtls::do_handshake()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If outgoing packet is empty, we use the last cache.
|
||||||
|
bool cache = false;
|
||||||
|
if (size <= 0 && nn_last_outgoing_packet) {
|
||||||
|
size = nn_last_outgoing_packet;
|
||||||
|
data = last_outgoing_packet_cache;
|
||||||
|
cache = true;
|
||||||
|
}
|
||||||
|
|
||||||
// Trace the detail of DTLS packet.
|
// Trace the detail of DTLS packet.
|
||||||
trace((uint8_t*)data, size, false, ssl_err);
|
trace((uint8_t*)data, size, false, ssl_err, cache);
|
||||||
|
|
||||||
|
// Update the packet cache.
|
||||||
|
if (size > 0 && data != last_outgoing_packet_cache && size < kRtpPacketSize) {
|
||||||
|
memcpy(last_outgoing_packet_cache, data, size);
|
||||||
|
nn_last_outgoing_packet = size;
|
||||||
|
}
|
||||||
|
|
||||||
if (size > 0 && (err = callback->write_dtls_data(data, size)) != srs_success) {
|
if (size > 0 && (err = callback->write_dtls_data(data, size)) != srs_success) {
|
||||||
return srs_error_wrap(err, "dtls send size=%u, data=[%s]", size,
|
return srs_error_wrap(err, "dtls send size=%u, data=[%s]", size,
|
||||||
|
@ -494,7 +514,7 @@ srs_error_t SrsDtls::do_handshake()
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SrsDtls::trace(uint8_t* data, int length, bool incoming, int ssl_err)
|
void SrsDtls::trace(uint8_t* data, int length, bool incoming, int ssl_err, bool cache)
|
||||||
{
|
{
|
||||||
uint8_t content_type = 0;
|
uint8_t content_type = 0;
|
||||||
if (length >= 1) {
|
if (length >= 1) {
|
||||||
|
@ -511,8 +531,8 @@ void SrsDtls::trace(uint8_t* data, int length, bool incoming, int ssl_err)
|
||||||
handshake_type = (uint8_t)data[13];
|
handshake_type = (uint8_t)data[13];
|
||||||
}
|
}
|
||||||
|
|
||||||
srs_trace("DTLS: %s done=%u, ssl-err=%d, length=%u, content-type=%u, size=%u, handshake-type=%u", (incoming? "RECV":"SEND"),
|
srs_trace("DTLS: %s done=%u, cache=%u, ssl-err=%d, length=%u, content-type=%u, size=%u, handshake-type=%u", (incoming? "RECV":"SEND"),
|
||||||
handshake_done_for_us, ssl_err, length, content_type, size, handshake_type);
|
handshake_done_for_us, cache, ssl_err, length, content_type, size, handshake_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int SRTP_MASTER_KEY_KEY_LEN = 16;
|
const int SRTP_MASTER_KEY_KEY_LEN = 16;
|
||||||
|
|
|
@ -106,6 +106,10 @@ private:
|
||||||
// @remark For us only, means peer maybe not done, we also need to handle the DTLS packet.
|
// @remark For us only, means peer maybe not done, we also need to handle the DTLS packet.
|
||||||
bool handshake_done_for_us;
|
bool handshake_done_for_us;
|
||||||
|
|
||||||
|
// DTLS packet cache, only last out-going packet.
|
||||||
|
uint8_t* last_outgoing_packet_cache;
|
||||||
|
int nn_last_outgoing_packet;
|
||||||
|
|
||||||
// @remark: dtls_role_ default value is DTLS_SERVER.
|
// @remark: dtls_role_ default value is DTLS_SERVER.
|
||||||
SrsDtlsRole role_;
|
SrsDtlsRole role_;
|
||||||
// @remark: dtls_version_ default value is SrsDtlsVersionAuto.
|
// @remark: dtls_version_ default value is SrsDtlsVersionAuto.
|
||||||
|
@ -126,7 +130,7 @@ public:
|
||||||
private:
|
private:
|
||||||
srs_error_t do_on_dtls(char* data, int nb_data);
|
srs_error_t do_on_dtls(char* data, int nb_data);
|
||||||
srs_error_t do_handshake();
|
srs_error_t do_handshake();
|
||||||
void trace(uint8_t* data, int length, bool incoming, int ssl_err);
|
void trace(uint8_t* data, int length, bool incoming, int ssl_err, bool cache);
|
||||||
public:
|
public:
|
||||||
srs_error_t get_srtp_key(std::string& recv_key, std::string& send_key);
|
srs_error_t get_srtp_key(std::string& recv_key, std::string& send_key);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue