@@ -50,7 +50,6 @@ unsigned int dtls_timer_cb(SSL* dtls, unsigned int previous_us)
5050 // limit the timeout in [50ms, 30s].
5151 timeout_us = srs_max (timeout_us, 50 * 1000 );
5252 timeout_us = srs_min (timeout_us, 30 * 1000 * 1000 );
53-
5453 srs_info (" DTLS: ARQ timer cb timeout=%ums, previous=%ums" , timeout_us/1000 , previous_us/1000 );
5554
5655 return timeout_us;
@@ -395,8 +394,9 @@ SrsDtlsImpl::SrsDtlsImpl(ISrsDtlsCallback* callback)
395394
396395 callback_ = callback;
397396 handshake_done_for_us = false ;
398-
399397 nn_arq_packets = 0 ;
398+ last_handshake_type = 0 ;
399+ last_content_type = 0 ;
400400
401401 version_ = SrsDtlsVersionAuto;
402402}
@@ -443,8 +443,18 @@ srs_error_t SrsDtlsImpl::write_dtls_data(void* data, int size)
443443 srs_string_dumps_hex ((char *)data, size, 32 ).c_str ());
444444 }
445445
446+ // change_cipher_spec(20), alert(21), handshake(22), application_data(23)
447+ // @see https://tools.ietf.org/html/rfc2246#section-6.2.1
448+ uint8_t content_type = size >= 1 ? ((uint8_t *)data)[0 ] : 0 ;
449+ uint8_t handshake_type = size >= 14 ? ((uint8_t *)data)[13 ] : 0 ;
450+ if (content_type && handshake_type && last_content_type == content_type && last_handshake_type == handshake_type) {
451+ nn_arq_packets++;
452+ }
453+ last_content_type = content_type;
454+ last_handshake_type = handshake_type;
455+
446456 // Logging when got SSL original data.
447- state_trace ((uint8_t *)data, size, false , 0 , 0 , false );
457+ state_trace ((uint8_t *)data, size, false , 0 );
448458
449459 return err;
450460}
@@ -574,13 +584,17 @@ srs_error_t SrsDtlsImpl::do_on_dtls(char* data, int nb_data)
574584 // TODO: 0 or -1 maybe block, use BIO_should_retry to check.
575585 return srs_error_new (ERROR_OpenSslBIOWrite, " BIO_write r0=%d" , r0);
576586 }
577- state_trace ((uint8_t *)data, nb_data, true , r0, SSL_ERROR_NONE, false );
587+ state_trace ((uint8_t *)data, nb_data, true , r0);
578588
579589 // If there is data available in bio_in, use SSL_read to allow SSL to process it.
580590 char buf[kRtpPacketSize ];
581591 r0 = SSL_read (dtls, buf, sizeof (buf));
582592 int r1 = SSL_get_error (dtls, r0); ERR_clear_error ();
583- if (r0 > 0 ) {
593+ if (r0 <= 0 ) {
594+ if (r1 != SSL_ERROR_WANT_READ && r1 != SSL_ERROR_WANT_WRITE && r1 != SSL_ERROR_ZERO_RETURN) {
595+ return srs_error_new (ERROR_RTC_DTLS, " DTLS: read r0=%d, r1=%d, done=%d" , r0, r1, handshake_done_for_us);
596+ }
597+ } else if (r0 > 0 ) {
584598 srs_trace (" DTLS: read r0=%d, r1=%d, padding=%d, done=%d, data=[%s]" ,
585599 r0, r1, BIO_ctrl_pending (bio_in), handshake_done_for_us, srs_string_dumps_hex (buf, r0, 32 ).c_str ());
586600
@@ -601,7 +615,7 @@ srs_error_t SrsDtlsImpl::do_on_dtls(char* data, int nb_data)
601615 return err;
602616}
603617
604- void SrsDtlsImpl::state_trace (uint8_t * data, int length, bool incoming, int r0, int r1, bool arq )
618+ void SrsDtlsImpl::state_trace (uint8_t * data, int length, bool incoming, int r0)
605619{
606620 // change_cipher_spec(20), alert(21), handshake(22), application_data(23)
607621 // @see https://tools.ietf.org/html/rfc2246#section-6.2.1
@@ -620,9 +634,9 @@ void SrsDtlsImpl::state_trace(uint8_t* data, int length, bool incoming, int r0,
620634 handshake_type = (uint8_t )data[13 ];
621635 }
622636
623- srs_trace (" DTLS: State %s %s, done=%u, arq=%u/%u , r0=%d, r1 =%d, len=%u, cnt=%u, size=%u, hs=%u" ,
624- (is_dtls_client ()? " Active" :" Passive" ), (incoming? " RECV" :" SEND" ), handshake_done_for_us, arq,
625- nn_arq_packets, r0, r1, length, content_type, size, handshake_type);
637+ srs_trace (" DTLS: State %s %s, done=%u, arq=%u, r0=%d, len=%u, cnt=%u, size=%u, hs=%u" ,
638+ (is_dtls_client ()? " Active" :" Passive" ), (incoming? " RECV" :" SEND" ), handshake_done_for_us,
639+ nn_arq_packets, r0, length, content_type, size, handshake_type);
626640}
627641
628642const int SRTP_MASTER_KEY_KEY_LEN = 16 ;
@@ -744,6 +758,7 @@ void SrsDtlsClientImpl::stop_arq()
744758 srs_freep (trd);
745759}
746760
761+ // The timeout is set by dtls_timer_cb.
747762srs_error_t SrsDtlsClientImpl::cycle ()
748763{
749764 srs_error_t err = srs_success;
@@ -778,6 +793,12 @@ srs_error_t SrsDtlsClientImpl::cycle()
778793
779794 // There is timeout to wait, so we should wait, because there is no packet in openssl.
780795 if (timeout > 0 ) {
796+ // Sleeping for an excessively long period of time may result in a significant slowdown
797+ // of the ARQ, even if the timeout is reset by the receipt of a packet. To ensure timely
798+ // response, it is recommended to decrease the timeout duration and increase the frequency
799+ // of checks.
800+ timeout = srs_min (timeout, 100 * SRS_UTIME_MILLISECONDS);
801+ srs_info (" DTLS: ARQ wait timeout=%dms, to=%dms, r0=%d" , srsu2msi (timeout), srsu2msi (to.tv_sec + to.tv_usec ), r0);
781802 srs_usleep (timeout);
782803 continue ;
783804 }
0 commit comments