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
59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <limits.h>
60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <stdio.h>
61e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#include <string.h>
62d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
63b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root#include <openssl/err.h>
64b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root#include <openssl/mem.h>
65b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root#include <openssl/obj.h>
66b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
67b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root#include "internal.h"
68b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root
69d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#if defined(OPENSSL_WINDOWS)
70d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <sys/timeb.h>
71d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#else
72d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <sys/socket.h>
73d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <sys/time.h>
74d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#endif
75d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
76e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
77e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley/* DTLS1_MTU_TIMEOUTS is the maximum number of timeouts to expire
78e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * before starting to decrease the MTU. */
79e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#define DTLS1_MTU_TIMEOUTS                     2
80e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
81e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley/* DTLS1_MAX_TIMEOUTS is the maximum number of timeouts to expire
82e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley * before failing the DTLS handshake. */
83e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley#define DTLS1_MAX_TIMEOUTS                     12
84e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
85e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic void get_current_time(const SSL *ssl, struct timeval *out_clock);
86d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
874139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyint dtls1_new(SSL *ssl) {
88d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  DTLS1_STATE *d1;
89d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
904139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (!ssl3_new(ssl)) {
91d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
92d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
93d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  d1 = OPENSSL_malloc(sizeof *d1);
94d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (d1 == NULL) {
954139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    ssl3_free(ssl);
96d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
97d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
98d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  memset(d1, 0, sizeof *d1);
99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  d1->buffered_messages = pqueue_new();
101d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  d1->sent_messages = pqueue_new();
102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
103e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (!d1->buffered_messages || !d1->sent_messages) {
104e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    pqueue_free(d1->buffered_messages);
105e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    pqueue_free(d1->sent_messages);
106d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    OPENSSL_free(d1);
1074139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    ssl3_free(ssl);
108d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
109d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
110d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1114139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->d1 = d1;
112d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
113d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* Set the version to the highest version for DTLS. This controls the initial
1144139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley   * state of |ssl->enc_method| and what the API reports as the version prior to
115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * negotiation.
116d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   *
117d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * TODO(davidben): This is fragile and confusing. */
1184139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->version = DTLS1_2_VERSION;
119d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
120d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
121d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1224139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleystatic void dtls1_clear_queues(SSL *ssl) {
123d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  pitem *item = NULL;
124d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  hm_fragment *frag = NULL;
125d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1264139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  while ((item = pqueue_pop(ssl->d1->buffered_messages)) != NULL) {
127d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    frag = (hm_fragment *)item->data;
128d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    dtls1_hm_fragment_free(frag);
129d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    pitem_free(item);
130d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
131d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1324139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  while ((item = pqueue_pop(ssl->d1->sent_messages)) != NULL) {
133d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    frag = (hm_fragment *)item->data;
134d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    dtls1_hm_fragment_free(frag);
135d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    pitem_free(item);
136d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
137d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
138d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1394139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyvoid dtls1_free(SSL *ssl) {
1404139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl3_free(ssl);
141d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1424139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl == NULL || ssl->d1 == NULL) {
143d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return;
144d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
145d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1464139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  dtls1_clear_queues(ssl);
147d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1484139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  pqueue_free(ssl->d1->buffered_messages);
1494139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  pqueue_free(ssl->d1->sent_messages);
150d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1514139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  OPENSSL_free(ssl->d1);
1524139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->d1 = NULL;
153d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
154d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
155f4e427204234da139fd0585def4b4e22502e33f0Adam Langleyint dtls1_supports_cipher(const SSL_CIPHER *cipher) {
156b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  /* DTLS does not support stream ciphers. The NULL cipher is rejected because
157b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root   * it's not needed. */
158b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root  return cipher->algorithm_enc != SSL_RC4 && cipher->algorithm_enc != SSL_eNULL;
159d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
160d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
1614139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyvoid dtls1_start_timer(SSL *ssl) {
162d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* If timer is not set, initialize duration with 1 second */
1634139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl->d1->next_timeout.tv_sec == 0 && ssl->d1->next_timeout.tv_usec == 0) {
1644139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    ssl->d1->timeout_duration = 1;
165d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
166d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
167d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* Set timeout to current time */
1684139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  get_current_time(ssl, &ssl->d1->next_timeout);
169d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
170d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* Add duration to current time */
1714139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->d1->next_timeout.tv_sec += ssl->d1->timeout_duration;
1724139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  BIO_ctrl(SSL_get_rbio(ssl), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
1734139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley           &ssl->d1->next_timeout);
174d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
175d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
176e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyint DTLSv1_get_timeout(const SSL *ssl, struct timeval *out) {
177e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (!SSL_IS_DTLS(ssl)) {
178e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return 0;
179e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  }
180d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
181d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* If no timeout is set, just return NULL */
182e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (ssl->d1->next_timeout.tv_sec == 0 && ssl->d1->next_timeout.tv_usec == 0) {
183e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return 0;
184d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
185d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
186d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* Get current time */
187e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  struct timeval timenow;
188e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  get_current_time(ssl, &timenow);
189d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
190d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* If timer already expired, set remaining time to 0 */
191e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (ssl->d1->next_timeout.tv_sec < timenow.tv_sec ||
192e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley      (ssl->d1->next_timeout.tv_sec == timenow.tv_sec &&
193e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley       ssl->d1->next_timeout.tv_usec <= timenow.tv_usec)) {
194e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    memset(out, 0, sizeof(struct timeval));
195e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return 1;
196d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
197d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
198d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* Calculate time left until timer expires */
199e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  memcpy(out, &ssl->d1->next_timeout, sizeof(struct timeval));
200e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  out->tv_sec -= timenow.tv_sec;
201e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  out->tv_usec -= timenow.tv_usec;
202e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (out->tv_usec < 0) {
203e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    out->tv_sec--;
204e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    out->tv_usec += 1000000;
205d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
206d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
207d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* If remaining time is less than 15 ms, set it to 0 to prevent issues
208d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * because of small devergences with socket timeouts. */
209e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (out->tv_sec == 0 && out->tv_usec < 15000) {
210e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    memset(out, 0, sizeof(struct timeval));
211d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
212d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
213e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return 1;
214d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
215d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2164139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyint dtls1_is_timer_expired(SSL *ssl) {
217e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  struct timeval timeleft;
218d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
219d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* Get time left until timeout, return false if no timer running */
2204139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (!DTLSv1_get_timeout(ssl, &timeleft)) {
221d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
222d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
223d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
224d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* Return false if timer is not expired yet */
225d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) {
226d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
227d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
228d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
229d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* Timer expired, so return true */
230d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 1;
231d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
232d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2334139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyvoid dtls1_double_timeout(SSL *ssl) {
2344139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->d1->timeout_duration *= 2;
2354139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl->d1->timeout_duration > 60) {
2364139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    ssl->d1->timeout_duration = 60;
237d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
2384139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  dtls1_start_timer(ssl);
239d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
240d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2414139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyvoid dtls1_stop_timer(SSL *ssl) {
242d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* Reset everything */
2434139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->d1->num_timeouts = 0;
2444139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  memset(&ssl->d1->next_timeout, 0, sizeof(struct timeval));
2454139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->d1->timeout_duration = 1;
2464139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  BIO_ctrl(SSL_get_rbio(ssl), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
2474139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley           &ssl->d1->next_timeout);
248d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* Clear retransmission buffer */
2494139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  dtls1_clear_record_buffer(ssl);
250d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
251d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2524139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyint dtls1_check_timeout_num(SSL *ssl) {
2534139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->d1->num_timeouts++;
254d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
255d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* Reduce MTU after 2 unsuccessful retransmissions */
2564139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl->d1->num_timeouts > DTLS1_MTU_TIMEOUTS &&
2574139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley      !(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) {
2584139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley    long mtu = BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0,
259d9e397b599b13d642138480a28c14db7a136bf0Adam Langley                        NULL);
260d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    if (mtu >= 0 && mtu <= (1 << 30) && (unsigned)mtu >= dtls1_min_mtu()) {
2614139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley      ssl->d1->mtu = (unsigned)mtu;
262d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    }
263d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
264d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
2654139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  if (ssl->d1->num_timeouts > DTLS1_MAX_TIMEOUTS) {
266d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    /* fail the connection, enough alerts have been sent */
267b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root    OPENSSL_PUT_ERROR(SSL, SSL_R_READ_TIMEOUT_EXPIRED);
268d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return -1;
269d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
270d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
271d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  return 0;
272d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
273d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
274e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleyint DTLSv1_handle_timeout(SSL *ssl) {
275e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (!SSL_IS_DTLS(ssl)) {
276e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return -1;
277e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  }
278e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
279d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* if no timer is expired, don't do anything */
280e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (!dtls1_is_timer_expired(ssl)) {
281d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return 0;
282d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
283d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
284e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  dtls1_double_timeout(ssl);
285d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
286e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (dtls1_check_timeout_num(ssl) < 0) {
287d9e397b599b13d642138480a28c14db7a136bf0Adam Langley    return -1;
288d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  }
289d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
290e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  dtls1_start_timer(ssl);
291e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  return dtls1_retransmit_buffered_messages(ssl);
292d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
293d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
294e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langleystatic void get_current_time(const SSL *ssl, struct timeval *out_clock) {
295e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  if (ssl->ctx->current_time_cb != NULL) {
296e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    ssl->ctx->current_time_cb(ssl, out_clock);
297e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley    return;
298e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  }
299e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley
300d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#if defined(OPENSSL_WINDOWS)
301d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  struct _timeb time;
302d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  _ftime(&time);
303e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  out_clock->tv_sec = time.time;
304e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  out_clock->tv_usec = time.millitm * 1000;
305d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#else
306e9ada863a7b3e81f5d2b1e3bdd2305da902a87f5Adam Langley  gettimeofday(out_clock, NULL);
307d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#endif
308d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
309d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
3104139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyint dtls1_set_handshake_header(SSL *ssl, int htype, unsigned long len) {
3114139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  uint8_t *message = (uint8_t *)ssl->init_buf->data;
3124139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  const struct hm_header_st *msg_hdr = &ssl->d1->w_msg_hdr;
313d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  uint8_t serialised_header[DTLS1_HM_HEADER_LENGTH];
314d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  uint8_t *p = serialised_header;
315d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
3164139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->d1->handshake_write_seq = ssl->d1->next_handshake_write_seq;
3174139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->d1->next_handshake_write_seq++;
318d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
3194139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  dtls1_set_message_header(ssl, htype, len, ssl->d1->handshake_write_seq, 0,
3204139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley                           len);
3214139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->init_num = (int)len + DTLS1_HM_HEADER_LENGTH;
3224139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  ssl->init_off = 0;
323d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
324d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* Buffer the message to handle re-xmits */
3254139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  dtls1_buffer_message(ssl);
326d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
327d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  /* Add the new message to the handshake hash. Serialize the message
328d9e397b599b13d642138480a28c14db7a136bf0Adam Langley   * header as if it were a single fragment. */
329d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  *p++ = msg_hdr->type;
330d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  l2n3(msg_hdr->msg_len, p);
331d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  s2n(msg_hdr->seq, p);
332d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  l2n3(0, p);
333d9e397b599b13d642138480a28c14db7a136bf0Adam Langley  l2n3(msg_hdr->msg_len, p);
3344139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  return ssl3_update_handshake_hash(ssl, serialised_header,
335b8494591d1b1a143f3b192d845c238bbf3bc629dKenny Root                                    sizeof(serialised_header)) &&
3364139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley         ssl3_update_handshake_hash(ssl, message + DTLS1_HM_HEADER_LENGTH, len);
337d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
338d9e397b599b13d642138480a28c14db7a136bf0Adam Langley
3394139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langleyint dtls1_handshake_write(SSL *ssl) {
3404139edb02e59e7ad48e0a8f4c02e45923bc8a344Adam Langley  return dtls1_do_handshake_write(ssl, dtls1_use_current_epoch);
341d9e397b599b13d642138480a28c14db7a136bf0Adam Langley}
342