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