diff --git a/trunk/src/app/srs_app_conn.cpp b/trunk/src/app/srs_app_conn.cpp index 7b88fe2505..4739410e7d 100644 --- a/trunk/src/app/srs_app_conn.cpp +++ b/trunk/src/app/srs_app_conn.cpp @@ -714,29 +714,20 @@ srs_error_t SrsSslConnection::read(void* plaintext, size_t nn_plaintext, ssize_t int r0 = SSL_read(ssl, plaintext, nn); int r1 = SSL_get_error(ssl, r0); int r2 = BIO_ctrl_pending(bio_in); int r3 = SSL_is_init_finished(ssl); - uint8_t* data = NULL; int size = BIO_get_mem_data(bio_out, &data); // Maybe renegotiation, need to write some data . // @see https://gist.github.com/darrenjs/4645f115d10aa4b5cebf57483ec82eca#file-ssl_server_nonblock-c-L281 - if (r0 == -1 && r1 == SSL_ERROR_WANT_READ && size > 0) { - srs_warn("https: renegotiation, r0=%d, r1=%d, size=%d", r0, r2, size); - - // TODO: FIXME: Maybe we should put the data in queue? - if ((err = transport->write(data, size, NULL)) != srs_success) { - return srs_error_wrap(err, "renegotiation: write data=%p, size=%d", data, size); - } - if ((r0 = BIO_reset(bio_out)) != 1) { - return srs_error_new(ERROR_HTTPS_READ, "BIO_reset r0=%d", r0); + if (r0 == -1 && r1 == SSL_ERROR_WANT_READ) { + if ((err = renegotiation(r0, r1, r2, r3)) != srs_success) { + return srs_error_wrap(err, "renegotiation"); } - - // Try to read again. - continue; + continue; // Try to read again. } if (r0 <= 0) { return srs_error_new(ERROR_HTTPS_READ, - "SSL_read r0=%d, r1=%d, r2=%d, r3=%d, padding=%d, osize=%d, size=%d", - r0, r1, r2, r3, nn_padding, size, nn); + "SSL_read r0=%d, r1=%d, r2=%d, r3=%d, padding=%d, size=%d", + r0, r1, r2, r3, nn_padding, nn); } srs_assert(r0 <= nn_plaintext); @@ -803,3 +794,27 @@ srs_error_t SrsSslConnection::writev(const iovec *iov, int iov_size, ssize_t* nw return err; } +srs_error_t SrsSslConnection::renegotiation(int r0, int r1, int r2, int r3) +{ + srs_error_t err = srs_success; + + while (true) { + uint8_t data[1024]; + int size = BIO_read(bio_out, data, sizeof(data)); + + // Actually no data to send, but its state changed. + if (size <= 0) { + return err; + } + + srs_warn("https: renegotiation, r0=%d, r1=%d, r2=%d, r3=%d, size=%d", r0, r1, r2, r3, size); + + // TODO: FIXME: Maybe we should put the data in queue? + if ((err = transport->write(data, size, NULL)) != srs_success) { + return srs_error_wrap(err, "renegotiation: write data=%p, size=%d", data, size); + } + } + + return err; +} + diff --git a/trunk/src/app/srs_app_conn.hpp b/trunk/src/app/srs_app_conn.hpp index ea2e30f7ed..4f5a9d7a00 100644 --- a/trunk/src/app/srs_app_conn.hpp +++ b/trunk/src/app/srs_app_conn.hpp @@ -191,6 +191,8 @@ class SrsSslConnection : virtual public ISrsProtocolReadWriter virtual srs_utime_t get_send_timeout(); virtual srs_error_t write(void* buf, size_t size, ssize_t* nwrite); virtual srs_error_t writev(const iovec *iov, int iov_size, ssize_t* nwrite); +private: + srs_error_t renegotiation(int r0, int r1, int r2, int r3); }; #endif diff --git a/trunk/src/core/srs_core_version4.hpp b/trunk/src/core/srs_core_version4.hpp index 2862ffda32..27e78470a7 100644 --- a/trunk/src/core/srs_core_version4.hpp +++ b/trunk/src/core/srs_core_version4.hpp @@ -24,6 +24,6 @@ #ifndef SRS_CORE_VERSION4_HPP #define SRS_CORE_VERSION4_HPP -#define SRS_VERSION4_REVISION 51 +#define SRS_VERSION4_REVISION 52 #endif