From ac856dc00b9a4344c444d036ab3595c017f78d7d Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Thu, 27 Dec 2012 14:39:25 +0200 Subject: Improvements in heartbeat handling. --- NEWS | 3 +++ lib/ext/heartbeat.c | 20 +++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 0fe0e9e7dc..d5ee736138 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,9 @@ Patterson and Nadhem Alfardan. ** libgnutls: gnutls_x509_crt_get_policy() allows for a list of zero policy qualifiers. +** libgnutls: Ignore heartbeat messages when received out-of-order, +instead of issuing an error. + ** libgnutls-guile: Fixed parallel compilation issue. ** gnutls-cli: It will try to connect to all possible returned addresses diff --git a/lib/ext/heartbeat.c b/lib/ext/heartbeat.c index 89d01202b7..9659c383d2 100644 --- a/lib/ext/heartbeat.c +++ b/lib/ext/heartbeat.c @@ -188,6 +188,12 @@ gnutls_heartbeat_ping (gnutls_session_t session, size_t data_size, if (!heartbeat_allow_send (session)) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + /* resume previous call if interrupted */ + if (session->internals.record_send_buffer.byte_length > 0 && + session->internals.record_send_buffer.head != NULL && + session->internals.record_send_buffer.head->type == GNUTLS_HEARTBEAT) + return _gnutls_io_write_flush (session); + switch(session->internals.hb_state) { case SHB_SEND1: @@ -287,6 +293,11 @@ gnutls_heartbeat_pong (gnutls_session_t session, unsigned int flags) { int ret; + if (session->internals.record_send_buffer.byte_length > 0 && + session->internals.record_send_buffer.head != NULL && + session->internals.record_send_buffer.head->type == GNUTLS_HEARTBEAT) + return _gnutls_io_write_flush (session); + if (session->internals.hb_remote_data.length == 0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); @@ -324,7 +335,7 @@ _gnutls_heartbeat_handle (gnutls_session_t session, mbuffer_st * bufel) hb_len = _gnutls_read_uint16 (msg + 1); if (hb_len > len - 3) - return gnutls_assert_val (GNUTLS_E_UNEXPECTED_PACKET); + return gnutls_assert_val (GNUTLS_E_UNEXPECTED_PACKET_LENGTH); switch (msg[0]) { @@ -352,10 +363,13 @@ _gnutls_heartbeat_handle (gnutls_session_t session, mbuffer_st * bufel) if (hb_len > 0 && memcmp (msg + 3, session->internals.hb_local_data.data, hb_len) != 0) { - _gnutls_record_log ("REC[%p]: HB: %s - received\n", session, + _gnutls_record_log ("REC[%p]: unexpected HB: %s - received\n", session, _gnutls_bin2hex (msg + 3, hb_len, pr, sizeof (pr), NULL)); - return gnutls_assert_val (GNUTLS_E_UNEXPECTED_PACKET); + if (IS_DTLS(session)) + return gnutls_assert_val( GNUTLS_E_AGAIN); /* ignore it */ + else + return gnutls_assert_val( GNUTLS_E_UNEXPECTED_PACKET); } _gnutls_buffer_reset (&session->internals.hb_local_data); -- cgit v1.2.1