1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/*
2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * DTLS implementation written by Nagendra Modadugu
3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * (nagendra@cs.stanford.edu) for the OpenSSL project 2005.
4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley */
5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* ====================================================================
6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright (c) 1999-2005 The OpenSSL Project.  All rights reserved.
7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Redistribution and use in source and binary forms, with or without
9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * modification, are permitted provided that the following conditions
10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * are met:
11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 1. Redistributions of source code must retain the above copyright
13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    notice, this list of conditions and the following disclaimer.
14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 2. Redistributions in binary form must reproduce the above copyright
16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    notice, this list of conditions and the following disclaimer in
17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    the documentation and/or other materials provided with the
18d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    distribution.
19d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
20d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3. All advertising materials mentioning features or use of this
21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    software must display the following acknowledgment:
22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    "This product includes software developed by the OpenSSL Project
23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
25d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    endorse or promote products derived from this software without
27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    prior written permission. For written permission, please contact
28d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    openssl-core@OpenSSL.org.
29d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
30d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 5. Products derived from this software may not be called "OpenSSL"
31d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    nor may "OpenSSL" appear in their names without prior written
32d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    permission of the OpenSSL Project.
33d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
34d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 6. Redistributions of any form whatsoever must retain the following
35d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    acknowledgment:
36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    "This product includes software developed by the OpenSSL Project
37d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OF THE POSSIBILITY OF SUCH DAMAGE.
51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ====================================================================
52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *
53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This product includes cryptographic software written by Eric Young
54d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * (eay@cryptsoft.com).  This product includes software written by Tim
55d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Hudson (tjh@cryptsoft.com). */
56d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
57b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root#include <openssl/ssl.h>
58d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
59c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin#include <assert.h>
60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <limits.h>
61e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include <string.h>
62d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
63b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root#include <openssl/err.h>
64b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root#include <openssl/mem.h>
654969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin#include <openssl/nid.h>
66b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
6769939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan#include "../crypto/internal.h"
68b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root#include "internal.h"
69b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
70e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
71b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloannamespace bssl {
7269939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan
73a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan// DTLS1_MTU_TIMEOUTS is the maximum number of timeouts to expire
74a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan// before starting to decrease the MTU.
75e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#define DTLS1_MTU_TIMEOUTS                     2
76e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
77a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan// DTLS1_MAX_TIMEOUTS is the maximum number of timeouts to expire
78a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan// before failing the DTLS handshake.
79e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#define DTLS1_MAX_TIMEOUTS                     12
80e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
8129c1d2cf8620ad14e06d8e7ff91db8f4de04d481Robert SloanDTLS1_STATE::DTLS1_STATE()
8229c1d2cf8620ad14e06d8e7ff91db8f4de04d481Robert Sloan    : has_change_cipher_spec(false),
8329c1d2cf8620ad14e06d8e7ff91db8f4de04d481Robert Sloan      outgoing_messages_complete(false),
8429c1d2cf8620ad14e06d8e7ff91db8f4de04d481Robert Sloan      flight_has_reply(false) {}
8529c1d2cf8620ad14e06d8e7ff91db8f4de04d481Robert Sloan
8629c1d2cf8620ad14e06d8e7ff91db8f4de04d481Robert SloanDTLS1_STATE::~DTLS1_STATE() {}
8729c1d2cf8620ad14e06d8e7ff91db8f4de04d481Robert Sloan
8836272964d1ab48276cf98c4cfad1130e5483e692Robert Sloanbool dtls1_new(SSL *ssl) {
894139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (!ssl3_new(ssl)) {
9036272964d1ab48276cf98c4cfad1130e5483e692Robert Sloan    return false;
91d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
9229c1d2cf8620ad14e06d8e7ff91db8f4de04d481Robert Sloan  UniquePtr<DTLS1_STATE> d1 = MakeUnique<DTLS1_STATE>();
9329c1d2cf8620ad14e06d8e7ff91db8f4de04d481Robert Sloan  if (!d1) {
944139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    ssl3_free(ssl);
9536272964d1ab48276cf98c4cfad1130e5483e692Robert Sloan    return false;
96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
97d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
9829c1d2cf8620ad14e06d8e7ff91db8f4de04d481Robert Sloan  ssl->d1 = d1.release();
99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
100a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan  // Set the version to the highest supported version.
101a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan  //
102a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan  // TODO(davidben): Move this field into |s3|, have it store the normalized
103a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan  // protocol version, and implement this pre-negotiation quirk in |SSL_version|
104a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan  // at the API boundary rather than in internal state.
1054139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->version = DTLS1_2_VERSION;
10636272964d1ab48276cf98c4cfad1130e5483e692Robert Sloan  return true;
107d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
108d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1094139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyvoid dtls1_free(SSL *ssl) {
1104139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl3_free(ssl);
111d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
11229c1d2cf8620ad14e06d8e7ff91db8f4de04d481Robert Sloan  if (ssl == NULL) {
113d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return;
114d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
11629c1d2cf8620ad14e06d8e7ff91db8f4de04d481Robert Sloan  Delete(ssl->d1);
1174139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->d1 = NULL;
118d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
119d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1204139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyvoid dtls1_start_timer(SSL *ssl) {
121a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan  // If timer is not set, initialize duration (by default, 1 second)
1224139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl->d1->next_timeout.tv_sec == 0 && ssl->d1->next_timeout.tv_usec == 0) {
123d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin    ssl->d1->timeout_duration_ms = ssl->initial_timeout_duration_ms;
124d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
125d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
126a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan  // Set timeout to current time
127c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin  ssl_get_current_time(ssl, &ssl->d1->next_timeout);
128d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
129a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan  // Add duration to current time
130d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin  ssl->d1->next_timeout.tv_sec += ssl->d1->timeout_duration_ms / 1000;
131d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin  ssl->d1->next_timeout.tv_usec += (ssl->d1->timeout_duration_ms % 1000) * 1000;
132d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin  if (ssl->d1->next_timeout.tv_usec >= 1000000) {
133d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin    ssl->d1->next_timeout.tv_sec++;
134d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin    ssl->d1->next_timeout.tv_usec -= 1000000;
135d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin  }
136d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
137d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
13836272964d1ab48276cf98c4cfad1130e5483e692Robert Sloanbool dtls1_is_timer_expired(SSL *ssl) {
139e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  struct timeval timeleft;
140d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
141a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan  // Get time left until timeout, return false if no timer running
1424139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (!DTLSv1_get_timeout(ssl, &timeleft)) {
14336272964d1ab48276cf98c4cfad1130e5483e692Robert Sloan    return false;
144d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
145d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
146a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan  // Return false if timer is not expired yet
147d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) {
14836272964d1ab48276cf98c4cfad1130e5483e692Robert Sloan    return false;
149d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
150d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
151a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan  // Timer expired, so return true
15236272964d1ab48276cf98c4cfad1130e5483e692Robert Sloan  return true;
153d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
154d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
155fe7cd2122ef131c19c9db15672594fd4f0232496Robert Sloanstatic void dtls1_double_timeout(SSL *ssl) {
156d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin  ssl->d1->timeout_duration_ms *= 2;
157d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin  if (ssl->d1->timeout_duration_ms > 60000) {
158d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin    ssl->d1->timeout_duration_ms = 60000;
159d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
160d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
161d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1624139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyvoid dtls1_stop_timer(SSL *ssl) {
1634139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->d1->num_timeouts = 0;
1647d422bcfd9ada9af993f3f332e789ff2d4928c3eRobert Sloan  OPENSSL_memset(&ssl->d1->next_timeout, 0, sizeof(ssl->d1->next_timeout));
165d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin  ssl->d1->timeout_duration_ms = ssl->initial_timeout_duration_ms;
166d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
167d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
16836272964d1ab48276cf98c4cfad1130e5483e692Robert Sloanbool dtls1_check_timeout_num(SSL *ssl) {
1694139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->d1->num_timeouts++;
170d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
171a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan  // Reduce MTU after 2 unsuccessful retransmissions
1724139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl->d1->num_timeouts > DTLS1_MTU_TIMEOUTS &&
1734139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley      !(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
174d316cba52b5aeac660e03068e65dd873669ce1dbDavid Benjamin    long mtu = BIO_ctrl(ssl->wbio, BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);
175d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (mtu >= 0 && mtu <= (1 << 30) && (unsigned)mtu >= dtls1_min_mtu()) {
1764139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley      ssl->d1->mtu = (unsigned)mtu;
177d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
178d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
179d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1804139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl->d1->num_timeouts > DTLS1_MAX_TIMEOUTS) {
181a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan    // fail the connection, enough alerts have been sent
182b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_READ_TIMEOUT_EXPIRED);
18336272964d1ab48276cf98c4cfad1130e5483e692Robert Sloan    return false;
184d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
185d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
18636272964d1ab48276cf98c4cfad1130e5483e692Robert Sloan  return true;
187d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
188d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
189b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan}  // namespace bssl
190b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan
191b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloanusing namespace bssl;
192b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan
193b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloanvoid DTLSv1_set_initial_timeout_duration(SSL *ssl, unsigned int duration_ms) {
194b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan  ssl->initial_timeout_duration_ms = duration_ms;
195b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan}
196b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan
197b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloanint DTLSv1_get_timeout(const SSL *ssl, struct timeval *out) {
198b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan  if (!SSL_is_dtls(ssl)) {
199b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan    return 0;
200b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan  }
201b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan
202a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan  // If no timeout is set, just return 0.
203b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan  if (ssl->d1->next_timeout.tv_sec == 0 && ssl->d1->next_timeout.tv_usec == 0) {
204b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan    return 0;
205b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan  }
206b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan
207b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan  struct OPENSSL_timeval timenow;
208b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan  ssl_get_current_time(ssl, &timenow);
209b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan
210a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan  // If timer already expired, set remaining time to 0.
211b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan  if (ssl->d1->next_timeout.tv_sec < timenow.tv_sec ||
212b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan      (ssl->d1->next_timeout.tv_sec == timenow.tv_sec &&
213b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan       ssl->d1->next_timeout.tv_usec <= timenow.tv_usec)) {
214b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan    OPENSSL_memset(out, 0, sizeof(*out));
215b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan    return 1;
216b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan  }
217b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan
218a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan  // Calculate time left until timer expires.
219b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan  struct OPENSSL_timeval ret;
220b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan  OPENSSL_memcpy(&ret, &ssl->d1->next_timeout, sizeof(ret));
221b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan  ret.tv_sec -= timenow.tv_sec;
222b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan  if (ret.tv_usec >= timenow.tv_usec) {
223b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan    ret.tv_usec -= timenow.tv_usec;
224b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan  } else {
225b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan    ret.tv_usec = 1000000 + ret.tv_usec - timenow.tv_usec;
226b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan    ret.tv_sec--;
227b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan  }
228b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan
229a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan  // If remaining time is less than 15 ms, set it to 0 to prevent issues
230a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan  // because of small divergences with socket timeouts.
231b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan  if (ret.tv_sec == 0 && ret.tv_usec < 15000) {
232b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan    OPENSSL_memset(&ret, 0, sizeof(ret));
233b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan  }
234b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan
235a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan  // Clamp the result in case of overflow.
236b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan  if (ret.tv_sec > INT_MAX) {
237b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan    assert(0);
238b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan    out->tv_sec = INT_MAX;
239b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan  } else {
240b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan    out->tv_sec = ret.tv_sec;
241b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan  }
242b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan
243b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan  out->tv_usec = ret.tv_usec;
244b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan  return 1;
245b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan}
246b6d070c5081ba0ca11545eb50870817d6d72d926Robert Sloan
247e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyint DTLSv1_handle_timeout(SSL *ssl) {
24869939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan  ssl_reset_error_state(ssl);
2494969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin
250c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin  if (!SSL_is_dtls(ssl)) {
251fe7cd2122ef131c19c9db15672594fd4f0232496Robert Sloan    OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
252e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return -1;
253e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  }
254e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
255a27a6a4be36c36d2915c2f58e0f58e918a098690Robert Sloan  // If no timer is expired, don't do anything.
256e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (!dtls1_is_timer_expired(ssl)) {
257d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
258d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
259d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
260fe7cd2122ef131c19c9db15672594fd4f0232496Robert Sloan  if (!dtls1_check_timeout_num(ssl)) {
261d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return -1;
262d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
263d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
264fe7cd2122ef131c19c9db15672594fd4f0232496Robert Sloan  dtls1_double_timeout(ssl);
265e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  dtls1_start_timer(ssl);
266c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin  return dtls1_retransmit_outgoing_messages(ssl);
267d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
268