From dd9a9b05d10c8facea1731df8a03a12ad87607c6 Mon Sep 17 00:00:00 2001 From: winlin Date: Thu, 13 Aug 2020 14:22:43 +0800 Subject: [PATCH] RTC: Do handshake although ssl done. --- trunk/src/app/srs_app_rtc_dtls.cpp | 46 +++++++++++++++--------------- trunk/src/app/srs_app_rtc_dtls.hpp | 7 +++-- 2 files changed, 28 insertions(+), 25 deletions(-) diff --git a/trunk/src/app/srs_app_rtc_dtls.cpp b/trunk/src/app/srs_app_rtc_dtls.cpp index ba3b8cf41..fb369d5d5 100644 --- a/trunk/src/app/srs_app_rtc_dtls.cpp +++ b/trunk/src/app/srs_app_rtc_dtls.cpp @@ -249,7 +249,7 @@ SrsDtls::SrsDtls(ISrsDtlsCallback* cb) dtls = NULL; callback = cb; - handshake_done = false; + handshake_done_for_us = false; role_ = SrsDtlsRoleServer; version_ = SrsDtlsVersionAuto; @@ -417,27 +417,31 @@ srs_error_t SrsDtls::do_on_dtls(char* data, int nb_data) } // Trace the detail of DTLS packet. - trace((uint8_t*)data, nb_data, true); + trace((uint8_t*)data, nb_data, true, SSL_ERROR_NONE); if ((r0 = BIO_write(bio_in, data, nb_data)) <= 0) { // TODO: 0 or -1 maybe block, use BIO_should_retry to check. return srs_error_new(ERROR_OpenSslBIOWrite, "BIO_write r0=%d", r0); } - if (!handshake_done) { - return do_handshake(); + // Always do handshake, even the handshake is done, because the last DTLS packet maybe dropped, + // so we thought the DTLS is done, but client need us to retransmit the last packet. + if ((err = do_handshake()) != srs_success) { + return srs_error_wrap(err, "do handshake"); } while (BIO_ctrl_pending(bio_in) > 0) { - char dtls_read_buf[8092]; - int nb = SSL_read(dtls, dtls_read_buf, sizeof(dtls_read_buf)); + char buf[8092]; + int nb = SSL_read(dtls, buf, sizeof(buf)); + if (!callback || nb <= 0) { continue; } + srs_trace("DTLS: read nb=%d, data=[%s]", nb, srs_string_dumps_hex(buf, nb, 32).c_str()); - if ((err = callback->on_dtls_application_data(dtls_read_buf, nb)) != srs_success) { + if ((err = callback->on_dtls_application_data(buf, nb)) != srs_success) { return srs_error_wrap(err, "on DTLS data, size=%u, data=[%s]", nb, - srs_string_dumps_hex(dtls_read_buf, nb, 32).c_str()); + srs_string_dumps_hex(buf, nb, 32).c_str()); } } @@ -450,13 +454,13 @@ srs_error_t SrsDtls::do_handshake() int ret = SSL_do_handshake(dtls); - unsigned char *out_bio_data; - int out_bio_len = BIO_get_mem_data(bio_out, &out_bio_data); + uint8_t* data = NULL; + int size = BIO_get_mem_data(bio_out, &data); int ssl_err = SSL_get_error(dtls, ret); switch(ssl_err) { case SSL_ERROR_NONE: { - handshake_done = true; + handshake_done_for_us = true; break; } @@ -474,14 +478,14 @@ srs_error_t SrsDtls::do_handshake() } // Trace the detail of DTLS packet. - trace((uint8_t*)out_bio_data, out_bio_len, false); + trace((uint8_t*)data, size, false, ssl_err); - if (out_bio_len > 0 && (err = callback->write_dtls_data(out_bio_data, out_bio_len)) != srs_success) { - return srs_error_wrap(err, "dtls send size=%u, data=[%s]", out_bio_len, - srs_string_dumps_hex((char*)out_bio_data, out_bio_len, 32).c_str()); + if (size > 0 && (err = callback->write_dtls_data(data, size)) != srs_success) { + return srs_error_wrap(err, "dtls send size=%u, data=[%s]", size, + srs_string_dumps_hex((char*)data, size, 32).c_str()); } - if (handshake_done) { + if (handshake_done_for_us) { if (((err = callback->on_dtls_handshake_done()) != srs_success)) { return srs_error_wrap(err, "dtls done"); } @@ -490,12 +494,8 @@ srs_error_t SrsDtls::do_handshake() return err; } -void SrsDtls::trace(uint8_t* data, int length, bool incoming) +void SrsDtls::trace(uint8_t* data, int length, bool incoming, int ssl_err) { - if (length <= 0) { - return; - } - uint8_t content_type = 0; if (length >= 1) { content_type = (uint8_t)data[0]; @@ -511,8 +511,8 @@ void SrsDtls::trace(uint8_t* data, int length, bool incoming) handshake_type = (uint8_t)data[13]; } - srs_trace("DTLS: %s done=%u, length=%u, content-type=%u, size=%u, handshake-type=%u", (incoming? "RECV":"SEND"), - handshake_done, length, content_type, size, handshake_type); + srs_trace("DTLS: %s done=%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); } const int SRTP_MASTER_KEY_KEY_LEN = 16; diff --git a/trunk/src/app/srs_app_rtc_dtls.hpp b/trunk/src/app/srs_app_rtc_dtls.hpp index 296fc6ce2..9aa8d1cef 100644 --- a/trunk/src/app/srs_app_rtc_dtls.hpp +++ b/trunk/src/app/srs_app_rtc_dtls.hpp @@ -101,7 +101,10 @@ private: BIO* bio_out; ISrsDtlsCallback* callback; - bool handshake_done; + + // Whether the handhshake is done, for us only. + // @remark For us only, means peer maybe not done, we also need to handle the DTLS packet. + bool handshake_done_for_us; // @remark: dtls_role_ default value is DTLS_SERVER. SrsDtlsRole role_; @@ -123,7 +126,7 @@ public: private: srs_error_t do_on_dtls(char* data, int nb_data); srs_error_t do_handshake(); - void trace(uint8_t* data, int length, bool incoming); + void trace(uint8_t* data, int length, bool incoming, int ssl_err); public: srs_error_t get_srtp_key(std::string& recv_key, std::string& send_key); };