Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (C) 2009-2012 Free Software Foundation, Inc. |
3 | | * |
4 | | * Author: Jonathan Bastien-Filiatrault |
5 | | * |
6 | | * This file is part of GNUTLS. |
7 | | * |
8 | | * The GNUTLS library is free software; you can redistribute it and/or |
9 | | * modify it under the terms of the GNU Lesser General Public License |
10 | | * as published by the Free Software Foundation; either version 2.1 of |
11 | | * the License, or (at your option) any later version. |
12 | | * |
13 | | * This library is distributed in the hope that it will be useful, but |
14 | | * WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
16 | | * Lesser General Public License for more details. |
17 | | * |
18 | | * You should have received a copy of the GNU Lesser General Public License |
19 | | * along with this program. If not, see <https://www.gnu.org/licenses/> |
20 | | * |
21 | | */ |
22 | | |
23 | | #ifndef GNUTLS_LIB_DTLS_H |
24 | | # define GNUTLS_LIB_DTLS_H |
25 | | |
26 | | # include <config.h> |
27 | | # include "gnutls_int.h" |
28 | | # include <buffers.h> |
29 | | # include <mbuffers.h> |
30 | | # include <constate.h> |
31 | | |
32 | | int _dtls_transmit(gnutls_session_t session); |
33 | | int _dtls_record_check(struct record_parameters_st *rp, uint64_t seq_num); |
34 | | void _dtls_reset_hsk_state(gnutls_session_t session); |
35 | | void _dtls_reset_window(struct record_parameters_st *rp); |
36 | | |
37 | | # define MAX_DTLS_TIMEOUT 60000 |
38 | | |
39 | | # define RETURN_DTLS_EAGAIN_OR_TIMEOUT(session, r) { \ |
40 | | struct timespec _now; \ |
41 | | unsigned int _diff; \ |
42 | | gnutls_gettime(&_now); \ |
43 | | \ |
44 | | _diff = timespec_sub_ms(&_now, &session->internals.handshake_start_time); \ |
45 | | if (_diff > session->internals.handshake_timeout_ms) \ |
46 | | { \ |
47 | | _gnutls_dtls_log("Session timeout: %u ms\n", _diff); \ |
48 | | return gnutls_assert_val(GNUTLS_E_TIMEDOUT); \ |
49 | | } \ |
50 | | else \ |
51 | | { \ |
52 | | int _rr; \ |
53 | | if (r != GNUTLS_E_INTERRUPTED) _rr = GNUTLS_E_AGAIN; \ |
54 | | else _rr = r; \ |
55 | | if (!(session->internals.flags & GNUTLS_NONBLOCK)) \ |
56 | | millisleep(50); \ |
57 | | return gnutls_assert_val(_rr); \ |
58 | | } \ |
59 | | } |
60 | | |
61 | | int _dtls_wait_and_retransmit(gnutls_session_t session); |
62 | | |
63 | | /* returns true or false depending on whether we need to |
64 | | * handle asynchronously handshake data. |
65 | | */ |
66 | | inline static int _dtls_is_async(gnutls_session_t session) |
67 | 0 | { |
68 | 0 | if ((session->security_parameters.entity == GNUTLS_SERVER |
69 | 0 | && !session->internals.resumed) |
70 | 0 | || (session->security_parameters.entity == GNUTLS_CLIENT |
71 | 0 | && session->internals.resumed)) |
72 | 0 | return 1; |
73 | 0 | else |
74 | 0 | return 0; |
75 | 0 | } Unexecuted instantiation: heartbeat.c:_dtls_is_async Unexecuted instantiation: session_ticket.c:_dtls_is_async |
76 | | |
77 | | inline static void _dtls_async_timer_init(gnutls_session_t session) |
78 | 0 | { |
79 | 0 | if (_dtls_is_async(session)) { |
80 | 0 | _gnutls_dtls_log |
81 | 0 | ("DTLS[%p]: Initializing timer for handshake state.\n", |
82 | 0 | session); |
83 | 0 | session->internals.dtls.async_term = |
84 | 0 | gnutls_time(0) + MAX_DTLS_TIMEOUT / 1000; |
85 | 0 | } else { |
86 | 0 | _dtls_reset_hsk_state(session); |
87 | 0 | _gnutls_handshake_io_buffer_clear(session); |
88 | 0 | _gnutls_epoch_gc(session); |
89 | 0 | session->internals.dtls.async_term = 0; |
90 | 0 | } |
91 | 0 | } Unexecuted instantiation: heartbeat.c:_dtls_async_timer_init Unexecuted instantiation: session_ticket.c:_dtls_async_timer_init |
92 | | |
93 | | void _dtls_async_timer_delete(gnutls_session_t session); |
94 | | |
95 | | /* Checks whether it is time to terminate the timer |
96 | | */ |
97 | | inline static void _dtls_async_timer_check(gnutls_session_t session) |
98 | 0 | { |
99 | 0 | if (!IS_DTLS(session)) |
100 | 0 | return; |
101 | 0 |
|
102 | 0 | if (session->internals.dtls.async_term != 0) { |
103 | 0 | time_t _now = time(0); |
104 | 0 |
|
105 | 0 | /* check if we need to expire the queued handshake data */ |
106 | 0 | if (_now > session->internals.dtls.async_term) { |
107 | 0 | _dtls_async_timer_delete(session); |
108 | 0 | } |
109 | 0 | } |
110 | 0 | } Unexecuted instantiation: heartbeat.c:_dtls_async_timer_check Unexecuted instantiation: session_ticket.c:_dtls_async_timer_check |
111 | | |
112 | | unsigned _gnutls_record_overhead(const version_entry_st * ver, |
113 | | const cipher_entry_st * cipher, |
114 | | const mac_entry_st * mac, unsigned max); |
115 | | |
116 | | /* Returns non-zero if the async timer is active */ |
117 | | inline static int _dtls_async_timer_active(gnutls_session_t session) |
118 | 0 | { |
119 | 0 | if (!IS_DTLS(session)) |
120 | 0 | return 0; |
121 | 0 |
|
122 | 0 | return session->internals.dtls.async_term; |
123 | 0 | } Unexecuted instantiation: heartbeat.c:_dtls_async_timer_active Unexecuted instantiation: session_ticket.c:_dtls_async_timer_active |
124 | | |
125 | | /* This function is to be called from record layer once |
126 | | * a handshake replay is detected. It will make sure |
127 | | * it transmits only once per few seconds. Otherwise |
128 | | * it is the same as _dtls_transmit(). |
129 | | */ |
130 | | inline static int _dtls_retransmit(gnutls_session_t session) |
131 | 0 | { |
132 | 0 | return _dtls_transmit(session); |
133 | 0 | } Unexecuted instantiation: heartbeat.c:_dtls_retransmit Unexecuted instantiation: session_ticket.c:_dtls_retransmit |
134 | | |
135 | | #endif /* GNUTLS_LIB_DTLS_H */ |