diff options
Diffstat (limited to 'lib/dtls.h')
-rw-r--r-- | lib/dtls.h | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/lib/dtls.h b/lib/dtls.h new file mode 100644 index 0000000..7d9fb40 --- /dev/null +++ b/lib/dtls.h @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2009-2012 Free Software Foundation, Inc. + * + * Author: Jonathan Bastien-Filiatrault + * + * This file is part of GNUTLS. + * + * The GNUTLS library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License + * as published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <https://www.gnu.org/licenses/> + * + */ + +#ifndef GNUTLS_LIB_DTLS_H +#define GNUTLS_LIB_DTLS_H + +#include <config.h> +#include "gnutls_int.h" +#include <buffers.h> +#include <mbuffers.h> +#include <constate.h> + +int _dtls_transmit(gnutls_session_t session); +int _dtls_record_check(struct record_parameters_st *rp, uint64_t seq_num); +void _dtls_reset_hsk_state(gnutls_session_t session); +void _dtls_reset_window(struct record_parameters_st *rp); + +#define MAX_DTLS_TIMEOUT 60000 + + +#define RETURN_DTLS_EAGAIN_OR_TIMEOUT(session, r) { \ + struct timespec _now; \ + unsigned int _diff; \ + gnutls_gettime(&_now); \ + \ + _diff = timespec_sub_ms(&_now, &session->internals.handshake_start_time); \ + if (_diff > session->internals.handshake_timeout_ms) \ + { \ + _gnutls_dtls_log("Session timeout: %u ms\n", _diff); \ + return gnutls_assert_val(GNUTLS_E_TIMEDOUT); \ + } \ + else \ + { \ + int _rr; \ + if (r != GNUTLS_E_INTERRUPTED) _rr = GNUTLS_E_AGAIN; \ + else _rr = r; \ + if (!(session->internals.flags & GNUTLS_NONBLOCK)) \ + millisleep(50); \ + return gnutls_assert_val(_rr); \ + } \ + } + + +int _dtls_wait_and_retransmit(gnutls_session_t session); + +/* returns true or false depending on whether we need to + * handle asynchronously handshake data. + */ +inline static int _dtls_is_async(gnutls_session_t session) +{ + if ((session->security_parameters.entity == GNUTLS_SERVER + && !session->internals.resumed) + || (session->security_parameters.entity == GNUTLS_CLIENT + && session->internals.resumed)) + return 1; + else + return 0; +} + +inline static void _dtls_async_timer_init(gnutls_session_t session) +{ + if (_dtls_is_async(session)) { + _gnutls_dtls_log + ("DTLS[%p]: Initializing timer for handshake state.\n", + session); + session->internals.dtls.async_term = + gnutls_time(0) + MAX_DTLS_TIMEOUT / 1000; + } else { + _dtls_reset_hsk_state(session); + _gnutls_handshake_io_buffer_clear(session); + _gnutls_epoch_gc(session); + session->internals.dtls.async_term = 0; + } +} + +void _dtls_async_timer_delete(gnutls_session_t session); + +/* Checks whether it is time to terminate the timer + */ +inline static void _dtls_async_timer_check(gnutls_session_t session) +{ + if (!IS_DTLS(session)) + return; + + if (session->internals.dtls.async_term != 0) { + time_t _now = time(0); + + /* check if we need to expire the queued handshake data */ + if (_now > session->internals.dtls.async_term) { + _dtls_async_timer_delete(session); + } + } +} + +unsigned _gnutls_record_overhead(const version_entry_st *ver, + const cipher_entry_st *cipher, + const mac_entry_st *mac, + unsigned max); + +/* Returns non-zero if the async timer is active */ +inline static int _dtls_async_timer_active(gnutls_session_t session) +{ + if (!IS_DTLS(session)) + return 0; + + return session->internals.dtls.async_term; +} + +/* This function is to be called from record layer once + * a handshake replay is detected. It will make sure + * it transmits only once per few seconds. Otherwise + * it is the same as _dtls_transmit(). + */ +inline static int _dtls_retransmit(gnutls_session_t session) +{ + return _dtls_transmit(session); +} + +#endif /* GNUTLS_LIB_DTLS_H */ |