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