diff options
author | AnotherTest <ali.mpfard@gmail.com> | 2020-07-21 05:39:14 +0430 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-07-21 13:01:35 +0200 |
commit | 4065182811830391fc22fd443267de737c4d444e (patch) | |
tree | 5920b6b64b32389e48dcce91e84c04774ee12feb | |
parent | be5f42adea1a75db6e6fdf49e9e4c6c9992d7c6d (diff) | |
download | serenity-4065182811830391fc22fd443267de737c4d444e.zip |
LibTLS: Reschedule the timeout if we're too slow
Previously, we would not care if the handshake timer timed out because
the server was too slow, or because we were too slow, this caused
connections to fail when the system was under heavy load.
This patch fixes this behaviour (and closes #2843) by checking if the
timeout delay was within margin of error of the max timeout.
-rw-r--r-- | Libraries/LibTLS/Socket.cpp | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/Libraries/LibTLS/Socket.cpp b/Libraries/LibTLS/Socket.cpp index b5f4fcf3ca..3a114748d3 100644 --- a/Libraries/LibTLS/Socket.cpp +++ b/Libraries/LibTLS/Socket.cpp @@ -122,18 +122,28 @@ bool TLSv12::common_connect(const struct sockaddr* saddr, socklen_t length) deferred_invoke([&](auto&) { m_handshake_timeout_timer = Core::Timer::create_single_shot( m_max_wait_time_for_handshake_in_seconds * 1000, [&] { - // The server did not respond fast enough, - // time the connection out. - alert(AlertLevel::Critical, AlertDescription::UserCanceled); - m_context.connection_finished = true; - m_context.tls_buffer.clear(); - m_context.error_code = Error::TimedOut; - m_context.critical_error = (u8)Error::TimedOut; - check_connection_state(false); // Notify the client. + auto timeout_diff = Core::DateTime::now().timestamp() - m_context.handshake_initiation_timestamp; + // If the timeout duration was actually within the max wait time (with a margin of error), + // we're not operating slow, so the server timed out. + // otherwise, it's our fault that the negotitation is taking too long, so extend the timer :P + if (timeout_diff < m_max_wait_time_for_handshake_in_seconds + 1) { + // The server did not respond fast enough, + // time the connection out. + alert(AlertLevel::Critical, AlertDescription::UserCanceled); + m_context.connection_finished = true; + m_context.tls_buffer.clear(); + m_context.error_code = Error::TimedOut; + m_context.critical_error = (u8)Error::TimedOut; + check_connection_state(false); // Notify the client. + } else { + // Extend the timer, we are too slow. + m_handshake_timeout_timer->restart(m_max_wait_time_for_handshake_in_seconds * 1000); + } }, this); write_into_socket(); m_handshake_timeout_timer->start(); + m_context.handshake_initiation_timestamp = Core::DateTime::now().timestamp(); }); m_has_scheduled_write_flush = true; |