diff options
author | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2013-02-04 02:24:29 +0100 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@gnutls.org> | 2013-02-04 02:45:31 +0100 |
commit | c9a23055c5d457589d93c48adf0ea21e81b83463 (patch) | |
tree | d5402292ec52e0c78e42067684fcf98214f4f4e3 | |
parent | b58b14fcda025f42639225969bb387c34d476d40 (diff) | |
download | gnutls-c9a23055c5d457589d93c48adf0ea21e81b83463.tar.gz |
updated heartbeat code, and made it optional.
-rw-r--r-- | configure.ac | 1 | ||||
-rw-r--r-- | lib/ext/heartbeat.c | 158 | ||||
-rw-r--r-- | lib/ext/heartbeat.h | 2 | ||||
-rw-r--r-- | m4/hooks.m4 | 14 |
4 files changed, 93 insertions, 82 deletions
diff --git a/configure.ac b/configure.ac index 734436a9ee..10474427f5 100644 --- a/configure.ac +++ b/configure.ac @@ -642,6 +642,7 @@ if features are disabled) SRP support: $ac_enable_srp PSK support: $ac_enable_psk Anon auth support:$ac_enable_anon + Heartbeat support:$ac_enable_heartbeat ]) AC_MSG_NOTICE([Optional applications: diff --git a/lib/ext/heartbeat.c b/lib/ext/heartbeat.c index c8a0fbd326..494b25fc5c 100644 --- a/lib/ext/heartbeat.c +++ b/lib/ext/heartbeat.c @@ -1,7 +1,8 @@ /* * Copyright (C) 2012 Free Software Foundation, Inc. + * Copyright (C) 2013 Nikos Mavrogiannopoulos * - * Author: Olga Smolenchuk + * Author: Olga Smolenchuk, Nikos Mavrogiannopoulos * * This file is part of GnuTLS. * @@ -28,6 +29,7 @@ #include <gnutls_extensions.h> #include <random.h> +#ifdef ENABLE_HEARTBEAT /** * gnutls_heartbeat_enable: * @session: is a #gnutls_session_t structure. @@ -48,22 +50,6 @@ gnutls_heartbeat_enable (gnutls_session_t session, unsigned int type) epriv); } -/*- - * Convenience helper: - * - * Returns: - * textual policy description or NULL. - -*/ -static inline const char * -_gnutls_heartbeat (unsigned policy) -{ - if (policy & GNUTLS_HB_PEER_ALLOWED_TO_SEND) - return "PEER ALLOWED TO SEND"; - else if (policy & GNUTLS_HB_PEER_NOT_ALLOWED_TO_SEND) - return "PEER NOT ALLOWED TO SEND"; - return "Unknown policy"; -} - /** * gnutls_heartbeat_allowed: * @session: is a #gnutls_session_t structure. @@ -96,63 +82,40 @@ gnutls_heartbeat_allowed (gnutls_session_t session, unsigned int type) return 0; } -static int -heartbeat_allow_recv (gnutls_session_t session) -{ - return gnutls_heartbeat_allowed(session, GNUTLS_HB_PEER_ALLOWED_TO_SEND); -} - -static int -heartbeat_allow_send (gnutls_session_t session) -{ - return gnutls_heartbeat_allowed(session, GNUTLS_HB_LOCAL_ALLOWED_TO_SEND); -} - #define DEFAULT_PAYLOAD_SIZE 16 -/*- - * heartbeat_send_data: - * @session: is a #gnutls_session_t structure. - * @data: contains the data to send. - * @data_size: is the length of the data. - * @start_timer: true if the heartbeat timer is to be started. - * - * This function has the similar semantics with gnutls_record_send() The only - * difference is that it uses GNUTLS_HEARTBEAT content type. - * - * This function send either HeartBeat request or response message - * with proper padding. It set timeout and timestamp without check - it's up to - * caller to make sure no messages are already in-flight and handle timeout expiration. - * - * Returns: The number of bytes sent, or a negative error code. The - * number of bytes sent might be less than @data_size. The maximum - * number of bytes this function can send in a single call depends - * on the negotiated maximum record size. - -*/ +/* + * Sends heartbeat data. + */ static int heartbeat_send_data (gnutls_session_t session, const void *data, size_t data_size, uint8_t type) { - int ret; - gnutls_buffer_st response; - uint8_t payload[DEFAULT_PAYLOAD_SIZE]; - _gnutls_buffer_init (&response); + int ret, pos; + uint8_t * response; - ret = gnutls_rnd (GNUTLS_RND_NONCE, payload, DEFAULT_PAYLOAD_SIZE); - if (ret < 0) - return gnutls_assert_val(ret); - - BUFFER_APPEND (&response, &type, 1); - BUFFER_APPEND_PFX2 (&response, data, data_size); + response = gnutls_malloc(1+data_size+DEFAULT_PAYLOAD_SIZE); + if (response == NULL) + return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR); + + pos = 0; + response[pos++] = 1; + memcpy(&response[pos], data, data_size); + pos += data_size; - BUFFER_APPEND (&response, payload, DEFAULT_PAYLOAD_SIZE); - ret = _gnutls_send_int (session, GNUTLS_HEARTBEAT, -1, - EPOCH_WRITE_CURRENT, response.data, - response.length, MBUFFER_FLUSH); + ret = gnutls_rnd (GNUTLS_RND_NONCE, &response[pos], DEFAULT_PAYLOAD_SIZE); + if (ret < 0) + { + gnutls_assert(); + goto cleanup; + } + pos += DEFAULT_PAYLOAD_SIZE; - _gnutls_record_log ("REC[%p]: HB sent: %d\n", session, ret); + ret = _gnutls_send_int (session, GNUTLS_HEARTBEAT, -1, EPOCH_WRITE_CURRENT, + response, pos, MBUFFER_FLUSH); - _gnutls_buffer_clear (&response); +cleanup: + gnutls_free(response); return ret; } @@ -185,7 +148,7 @@ gnutls_heartbeat_ping (gnutls_session_t session, size_t data_size, if (data_size > MAX_HEARTBEAT_LENGTH) return gnutls_assert_val (GNUTLS_E_UNEXPECTED_PACKET_LENGTH); - if (!heartbeat_allow_send (session)) + if (gnutls_heartbeat_allowed(session, GNUTLS_HB_LOCAL_ALLOWED_TO_SEND)==0) return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); /* resume previous call if interrupted */ @@ -197,9 +160,6 @@ gnutls_heartbeat_ping (gnutls_session_t session, size_t data_size, switch(session->internals.hb_state) { case SHB_SEND1: - _gnutls_record_log - ("REC[%p]: sending HB_REQUEST with length: %zu to peer\n", session, data_size); - if (data_size > DEFAULT_PAYLOAD_SIZE) data_size -= DEFAULT_PAYLOAD_SIZE; else @@ -327,7 +287,7 @@ _gnutls_heartbeat_handle (gnutls_session_t session, mbuffer_st * bufel) uint8_t *msg = _mbuffer_get_udata_ptr (bufel); size_t hb_len, len = _mbuffer_get_udata_size (bufel); - if (!heartbeat_allow_recv (session)) + if (gnutls_heartbeat_allowed(session, GNUTLS_HB_PEER_ALLOWED_TO_SEND) == 0) return gnutls_assert_val (GNUTLS_E_UNEXPECTED_PACKET); if (len < 4) @@ -340,9 +300,6 @@ _gnutls_heartbeat_handle (gnutls_session_t session, mbuffer_st * bufel) switch (msg[0]) { case HEARTBEAT_REQUEST: - _gnutls_record_log - ("REC[%p]: received HEARTBEAT_REQUEST\n", session); - _gnutls_buffer_reset(&session->internals.hb_remote_data); ret = _gnutls_buffer_resize (&session->internals.hb_remote_data, hb_len); @@ -363,9 +320,6 @@ _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]: unexpected HB: %s - received\n", session, - _gnutls_bin2hex (msg + 3, hb_len, pr, - sizeof (pr), NULL)); if (IS_DTLS(session)) return gnutls_assert_val( GNUTLS_E_AGAIN); /* ignore it */ else @@ -504,27 +458,32 @@ _gnutls_heartbeat_send_params (gnutls_session_t session, } static int -_gnutls_heartbeat_pack (extension_priv_data_t _priv, gnutls_buffer_st * ps) +_gnutls_heartbeat_pack (extension_priv_data_t epriv, gnutls_buffer_st * ps) { int ret; - BUFFER_APPEND_NUM (ps, _priv.num); - return GNUTLS_E_SUCCESS; + + BUFFER_APPEND_NUM (ps, epriv.num); + + return 0; + } static int _gnutls_heartbeat_unpack (gnutls_buffer_st * ps, - extension_priv_data_t * _priv) + extension_priv_data_t * _priv) { - int ret; extension_priv_data_t epriv; + int ret; + BUFFER_POP_NUM (ps, epriv.num); + *_priv = epriv; + ret = 0; error: return ret; } - extension_entry_st ext_mod_heartbeat = { .name = "HEARTBEAT", .type = GNUTLS_EXTENSION_HEARTBEAT, @@ -536,3 +495,40 @@ extension_entry_st ext_mod_heartbeat = { .unpack_func = _gnutls_heartbeat_unpack, .deinit_func = NULL }; + +#else +void +gnutls_heartbeat_enable (gnutls_session_t session, unsigned int type) +{ +} + +int +gnutls_heartbeat_allowed (gnutls_session_t session, unsigned int type) +{ + return 0; +} + +int +gnutls_heartbeat_ping (gnutls_session_t session, size_t data_size, + unsigned int max_tries, unsigned int flags) +{ + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); +} + +int +gnutls_heartbeat_pong (gnutls_session_t session, unsigned int flags) +{ + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); +} + +unsigned int gnutls_heartbeat_get_timeout (gnutls_session_t session) +{ + return 0; +} + +void gnutls_heartbeat_set_timeouts (gnutls_session_t session, unsigned int retrans_timeout, + unsigned int total_timeout) +{ + return; +} +#endif diff --git a/lib/ext/heartbeat.h b/lib/ext/heartbeat.h index ee7a534ae6..9bf0317d63 100644 --- a/lib/ext/heartbeat.h +++ b/lib/ext/heartbeat.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2002-2012 Free Software Foundation, Inc. + * Copyright (C) 2012 Free Software Foundation, Inc. * * Author: Olga Smolenchuk * diff --git a/m4/hooks.m4 b/m4/hooks.m4 index dbe2f51524..ff588b453e 100644 --- a/m4/hooks.m4 +++ b/m4/hooks.m4 @@ -153,6 +153,20 @@ fi fi AM_CONDITIONAL(ENABLE_DTLS_SRTP, test "$ac_enable_srtp" != "no") + ac_enable_heartbeat=yes + AC_MSG_CHECKING([whether to disable DTLS-SRTP extension]) + AC_ARG_ENABLE(heartbeat-support, + AS_HELP_STRING([--enable-heartbeat-support], + [enable support for the heartbeat extension (LGPLv3)]), + ac_enable_heartbeat=$enableval,ac_enable_heartbeat=no) + if test x$ac_enable_heartbeat != xno; then + AC_MSG_RESULT(yes) + AC_DEFINE([ENABLE_HEARTBEAT], 1, [enable heartbeat support]) + else + AC_MSG_RESULT(no) + fi + AM_CONDITIONAL(ENABLE_HEARTBEAT, test "$ac_enable_heartbeat" != "no") + ac_enable_srp=yes AC_MSG_CHECKING([whether to disable SRP authentication support]) AC_ARG_ENABLE(srp-authentication, |