1160814Ssimon/* ssl/d1_lib.c */ 2296341Sdelphij/* 3160814Ssimon * DTLS implementation written by Nagendra Modadugu 4296341Sdelphij * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. 5160814Ssimon */ 6160814Ssimon/* ==================================================================== 7160814Ssimon * Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved. 8160814Ssimon * 9160814Ssimon * Redistribution and use in source and binary forms, with or without 10160814Ssimon * modification, are permitted provided that the following conditions 11160814Ssimon * are met: 12160814Ssimon * 13160814Ssimon * 1. Redistributions of source code must retain the above copyright 14296341Sdelphij * notice, this list of conditions and the following disclaimer. 15160814Ssimon * 16160814Ssimon * 2. Redistributions in binary form must reproduce the above copyright 17160814Ssimon * notice, this list of conditions and the following disclaimer in 18160814Ssimon * the documentation and/or other materials provided with the 19160814Ssimon * distribution. 20160814Ssimon * 21160814Ssimon * 3. All advertising materials mentioning features or use of this 22160814Ssimon * software must display the following acknowledgment: 23160814Ssimon * "This product includes software developed by the OpenSSL Project 24160814Ssimon * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" 25160814Ssimon * 26160814Ssimon * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 27160814Ssimon * endorse or promote products derived from this software without 28160814Ssimon * prior written permission. For written permission, please contact 29160814Ssimon * openssl-core@OpenSSL.org. 30160814Ssimon * 31160814Ssimon * 5. Products derived from this software may not be called "OpenSSL" 32160814Ssimon * nor may "OpenSSL" appear in their names without prior written 33160814Ssimon * permission of the OpenSSL Project. 34160814Ssimon * 35160814Ssimon * 6. Redistributions of any form whatsoever must retain the following 36160814Ssimon * acknowledgment: 37160814Ssimon * "This product includes software developed by the OpenSSL Project 38160814Ssimon * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" 39160814Ssimon * 40160814Ssimon * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 41160814Ssimon * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 42160814Ssimon * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 43160814Ssimon * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 44160814Ssimon * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 45160814Ssimon * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 46160814Ssimon * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 47160814Ssimon * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48160814Ssimon * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 49160814Ssimon * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 50160814Ssimon * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 51160814Ssimon * OF THE POSSIBILITY OF SUCH DAMAGE. 52160814Ssimon * ==================================================================== 53160814Ssimon * 54160814Ssimon * This product includes cryptographic software written by Eric Young 55160814Ssimon * (eay@cryptsoft.com). This product includes software written by Tim 56160814Ssimon * Hudson (tjh@cryptsoft.com). 57160814Ssimon * 58160814Ssimon */ 59160814Ssimon 60160814Ssimon#include <stdio.h> 61205128Ssimon#define USE_SOCKETS 62160814Ssimon#include <openssl/objects.h> 63160814Ssimon#include "ssl_locl.h" 64160814Ssimon 65205128Ssimon#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) 66296341Sdelphij# include <sys/timeb.h> 67205128Ssimon#endif 68205128Ssimon 69205128Ssimonstatic void get_current_time(struct timeval *t); 70296341Sdelphijconst char dtls1_version_str[] = "DTLSv1" OPENSSL_VERSION_PTEXT; 71205128Ssimonint dtls1_listen(SSL *s, struct sockaddr *client); 72160814Ssimon 73296341SdelphijSSL3_ENC_METHOD DTLSv1_enc_data = { 74160814Ssimon dtls1_enc, 75296341Sdelphij tls1_mac, 76296341Sdelphij tls1_setup_key_block, 77296341Sdelphij tls1_generate_master_secret, 78296341Sdelphij tls1_change_cipher_state, 79296341Sdelphij tls1_final_finish_mac, 80296341Sdelphij TLS1_FINISH_MAC_LENGTH, 81296341Sdelphij tls1_cert_verify_mac, 82296341Sdelphij TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, 83296341Sdelphij TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, 84296341Sdelphij tls1_alert_code, 85296341Sdelphij tls1_export_keying_material, 86296341Sdelphij}; 87160814Ssimon 88160814Ssimonlong dtls1_default_timeout(void) 89296341Sdelphij{ 90296341Sdelphij /* 91296341Sdelphij * 2 hours, the 24 hours mentioned in the DTLSv1 spec is way too long for 92296341Sdelphij * http, the cache would over fill 93296341Sdelphij */ 94296341Sdelphij return (60 * 60 * 2); 95296341Sdelphij} 96160814Ssimon 97160814Ssimonint dtls1_new(SSL *s) 98296341Sdelphij{ 99296341Sdelphij DTLS1_STATE *d1; 100160814Ssimon 101296341Sdelphij if (!ssl3_new(s)) 102296341Sdelphij return (0); 103296341Sdelphij if ((d1 = OPENSSL_malloc(sizeof *d1)) == NULL) 104296341Sdelphij return (0); 105296341Sdelphij memset(d1, 0, sizeof *d1); 106160814Ssimon 107296341Sdelphij /* d1->handshake_epoch=0; */ 108160814Ssimon 109296341Sdelphij d1->unprocessed_rcds.q = pqueue_new(); 110296341Sdelphij d1->processed_rcds.q = pqueue_new(); 111296341Sdelphij d1->buffered_messages = pqueue_new(); 112296341Sdelphij d1->sent_messages = pqueue_new(); 113296341Sdelphij d1->buffered_app_data.q = pqueue_new(); 114160814Ssimon 115296341Sdelphij if (s->server) { 116296341Sdelphij d1->cookie_len = sizeof(s->d1->cookie); 117296341Sdelphij } 118160814Ssimon 119296341Sdelphij d1->link_mtu = 0; 120296341Sdelphij d1->mtu = 0; 121279264Sdelphij 122296341Sdelphij if (!d1->unprocessed_rcds.q || !d1->processed_rcds.q 123296341Sdelphij || !d1->buffered_messages || !d1->sent_messages 124296341Sdelphij || !d1->buffered_app_data.q) { 125296341Sdelphij if (d1->unprocessed_rcds.q) 126296341Sdelphij pqueue_free(d1->unprocessed_rcds.q); 127296341Sdelphij if (d1->processed_rcds.q) 128296341Sdelphij pqueue_free(d1->processed_rcds.q); 129296341Sdelphij if (d1->buffered_messages) 130296341Sdelphij pqueue_free(d1->buffered_messages); 131296341Sdelphij if (d1->sent_messages) 132296341Sdelphij pqueue_free(d1->sent_messages); 133296341Sdelphij if (d1->buffered_app_data.q) 134296341Sdelphij pqueue_free(d1->buffered_app_data.q); 135296341Sdelphij OPENSSL_free(d1); 136296341Sdelphij return (0); 137296341Sdelphij } 138160814Ssimon 139296341Sdelphij s->d1 = d1; 140296341Sdelphij s->method->ssl_clear(s); 141296341Sdelphij return (1); 142296341Sdelphij} 143160814Ssimon 144237657Sjkimstatic void dtls1_clear_queues(SSL *s) 145296341Sdelphij{ 146160814Ssimon pitem *item = NULL; 147296341Sdelphij DTLS1_RECORD_DATA *rdata; 148160814Ssimon 149296341Sdelphij while ((item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) { 150296341Sdelphij rdata = (DTLS1_RECORD_DATA *)item->data; 151296341Sdelphij if (rdata->rbuf.buf) { 152296341Sdelphij OPENSSL_free(rdata->rbuf.buf); 153296341Sdelphij } 154160814Ssimon OPENSSL_free(item->data); 155160814Ssimon pitem_free(item); 156296341Sdelphij } 157296341Sdelphij 158296341Sdelphij while ((item = pqueue_pop(s->d1->processed_rcds.q)) != NULL) { 159296341Sdelphij rdata = (DTLS1_RECORD_DATA *)item->data; 160296341Sdelphij if (rdata->rbuf.buf) { 161296341Sdelphij OPENSSL_free(rdata->rbuf.buf); 162160814Ssimon } 163160814Ssimon OPENSSL_free(item->data); 164160814Ssimon pitem_free(item); 165296341Sdelphij } 166160814Ssimon 167306230Sdelphij while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) { 168306230Sdelphij rdata = (DTLS1_RECORD_DATA *)item->data; 169306230Sdelphij if (rdata->rbuf.buf) { 170306230Sdelphij OPENSSL_free(rdata->rbuf.buf); 171306230Sdelphij } 172306230Sdelphij OPENSSL_free(item->data); 173306230Sdelphij pitem_free(item); 174306230Sdelphij } 175306230Sdelphij 176306230Sdelphij dtls1_clear_received_buffer(s); 177306230Sdelphij dtls1_clear_sent_buffer(s); 178306230Sdelphij} 179306230Sdelphij 180306230Sdelphijvoid dtls1_clear_received_buffer(SSL *s) 181306230Sdelphij{ 182306230Sdelphij pitem *item = NULL; 183306230Sdelphij hm_fragment *frag = NULL; 184306230Sdelphij 185296341Sdelphij while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) { 186160814Ssimon frag = (hm_fragment *)item->data; 187279264Sdelphij dtls1_hm_fragment_free(frag); 188160814Ssimon pitem_free(item); 189296341Sdelphij } 190306230Sdelphij} 191160814Ssimon 192306230Sdelphijvoid dtls1_clear_sent_buffer(SSL *s) 193306230Sdelphij{ 194306230Sdelphij pitem *item = NULL; 195306230Sdelphij hm_fragment *frag = NULL; 196306230Sdelphij 197296341Sdelphij while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) { 198160814Ssimon frag = (hm_fragment *)item->data; 199279264Sdelphij dtls1_hm_fragment_free(frag); 200160814Ssimon pitem_free(item); 201296341Sdelphij } 202296341Sdelphij} 203160814Ssimon 204306230Sdelphij 205237657Sjkimvoid dtls1_free(SSL *s) 206296341Sdelphij{ 207296341Sdelphij ssl3_free(s); 208237657Sjkim 209296341Sdelphij dtls1_clear_queues(s); 210237657Sjkim 211237657Sjkim pqueue_free(s->d1->unprocessed_rcds.q); 212237657Sjkim pqueue_free(s->d1->processed_rcds.q); 213237657Sjkim pqueue_free(s->d1->buffered_messages); 214296341Sdelphij pqueue_free(s->d1->sent_messages); 215296341Sdelphij pqueue_free(s->d1->buffered_app_data.q); 216160814Ssimon 217296341Sdelphij OPENSSL_free(s->d1); 218296341Sdelphij s->d1 = NULL; 219296341Sdelphij} 220160814Ssimon 221160814Ssimonvoid dtls1_clear(SSL *s) 222296341Sdelphij{ 223237657Sjkim pqueue unprocessed_rcds; 224237657Sjkim pqueue processed_rcds; 225237657Sjkim pqueue buffered_messages; 226296341Sdelphij pqueue sent_messages; 227296341Sdelphij pqueue buffered_app_data; 228296341Sdelphij unsigned int mtu; 229296341Sdelphij unsigned int link_mtu; 230237657Sjkim 231296341Sdelphij if (s->d1) { 232296341Sdelphij unprocessed_rcds = s->d1->unprocessed_rcds.q; 233296341Sdelphij processed_rcds = s->d1->processed_rcds.q; 234296341Sdelphij buffered_messages = s->d1->buffered_messages; 235296341Sdelphij sent_messages = s->d1->sent_messages; 236296341Sdelphij buffered_app_data = s->d1->buffered_app_data.q; 237296341Sdelphij mtu = s->d1->mtu; 238296341Sdelphij link_mtu = s->d1->link_mtu; 239237657Sjkim 240296341Sdelphij dtls1_clear_queues(s); 241237657Sjkim 242296341Sdelphij memset(s->d1, 0, sizeof(*(s->d1))); 243237657Sjkim 244296341Sdelphij if (s->server) { 245296341Sdelphij s->d1->cookie_len = sizeof(s->d1->cookie); 246296341Sdelphij } 247237657Sjkim 248296341Sdelphij if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) { 249296341Sdelphij s->d1->mtu = mtu; 250296341Sdelphij s->d1->link_mtu = link_mtu; 251296341Sdelphij } 252237657Sjkim 253296341Sdelphij s->d1->unprocessed_rcds.q = unprocessed_rcds; 254296341Sdelphij s->d1->processed_rcds.q = processed_rcds; 255296341Sdelphij s->d1->buffered_messages = buffered_messages; 256296341Sdelphij s->d1->sent_messages = sent_messages; 257296341Sdelphij s->d1->buffered_app_data.q = buffered_app_data; 258296341Sdelphij } 259237657Sjkim 260296341Sdelphij ssl3_clear(s); 261296341Sdelphij if (s->options & SSL_OP_CISCO_ANYCONNECT) 262296341Sdelphij s->version = DTLS1_BAD_VER; 263296341Sdelphij else 264296341Sdelphij s->version = DTLS1_VERSION; 265296341Sdelphij} 266194206Ssimon 267205128Ssimonlong dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) 268296341Sdelphij{ 269296341Sdelphij int ret = 0; 270205128Ssimon 271296341Sdelphij switch (cmd) { 272296341Sdelphij case DTLS_CTRL_GET_TIMEOUT: 273296341Sdelphij if (dtls1_get_timeout(s, (struct timeval *)parg) != NULL) { 274296341Sdelphij ret = 1; 275296341Sdelphij } 276296341Sdelphij break; 277296341Sdelphij case DTLS_CTRL_HANDLE_TIMEOUT: 278296341Sdelphij ret = dtls1_handle_timeout(s); 279296341Sdelphij break; 280296341Sdelphij case DTLS_CTRL_LISTEN: 281296341Sdelphij ret = dtls1_listen(s, parg); 282296341Sdelphij break; 283296341Sdelphij case SSL_CTRL_CHECK_PROTO_VERSION: 284296341Sdelphij /* 285296341Sdelphij * For library-internal use; checks that the current protocol is the 286296341Sdelphij * highest enabled version (according to s->ctx->method, as version 287296341Sdelphij * negotiation may have changed s->method). 288296341Sdelphij */ 289273399Sdelphij#if DTLS_MAX_VERSION != DTLS1_VERSION 290296341Sdelphij# error Code needs update for DTLS_method() support beyond DTLS1_VERSION. 291273399Sdelphij#endif 292296341Sdelphij /* 293296341Sdelphij * Just one protocol version is supported so far; fail closed if the 294296341Sdelphij * version is not as expected. 295296341Sdelphij */ 296296341Sdelphij return s->version == DTLS_MAX_VERSION; 297296341Sdelphij case DTLS_CTRL_SET_LINK_MTU: 298296341Sdelphij if (larg < (long)dtls1_link_min_mtu()) 299296341Sdelphij return 0; 300296341Sdelphij s->d1->link_mtu = larg; 301296341Sdelphij return 1; 302296341Sdelphij case DTLS_CTRL_GET_LINK_MIN_MTU: 303296341Sdelphij return (long)dtls1_link_min_mtu(); 304296341Sdelphij case SSL_CTRL_SET_MTU: 305296341Sdelphij /* 306296341Sdelphij * We may not have a BIO set yet so can't call dtls1_min_mtu() 307296341Sdelphij * We'll have to make do with dtls1_link_min_mtu() and max overhead 308296341Sdelphij */ 309296341Sdelphij if (larg < (long)dtls1_link_min_mtu() - DTLS1_MAX_MTU_OVERHEAD) 310296341Sdelphij return 0; 311296341Sdelphij s->d1->mtu = larg; 312296341Sdelphij return larg; 313296341Sdelphij default: 314296341Sdelphij ret = ssl3_ctrl(s, cmd, larg, parg); 315296341Sdelphij break; 316296341Sdelphij } 317296341Sdelphij return (ret); 318296341Sdelphij} 319205128Ssimon 320194206Ssimon/* 321194206Ssimon * As it's impossible to use stream ciphers in "datagram" mode, this 322194206Ssimon * simple filter is designed to disengage them in DTLS. Unfortunately 323194206Ssimon * there is no universal way to identify stream SSL_CIPHER, so we have 324194206Ssimon * to explicitly list their SSL_* codes. Currently RC4 is the only one 325194206Ssimon * available, but if new ones emerge, they will have to be added... 326194206Ssimon */ 327238405Sjkimconst SSL_CIPHER *dtls1_get_cipher(unsigned int u) 328296341Sdelphij{ 329296341Sdelphij const SSL_CIPHER *ciph = ssl3_get_cipher(u); 330194206Ssimon 331296341Sdelphij if (ciph != NULL) { 332296341Sdelphij if (ciph->algorithm_enc == SSL_RC4) 333296341Sdelphij return NULL; 334296341Sdelphij } 335194206Ssimon 336296341Sdelphij return ciph; 337296341Sdelphij} 338205128Ssimon 339205128Ssimonvoid dtls1_start_timer(SSL *s) 340296341Sdelphij{ 341238405Sjkim#ifndef OPENSSL_NO_SCTP 342296341Sdelphij /* Disable timer for SCTP */ 343296341Sdelphij if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { 344296341Sdelphij memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); 345296341Sdelphij return; 346296341Sdelphij } 347238405Sjkim#endif 348238405Sjkim 349296341Sdelphij /* If timer is not set, initialize duration with 1 second */ 350296341Sdelphij if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { 351296341Sdelphij s->d1->timeout_duration = 1; 352296341Sdelphij } 353205128Ssimon 354296341Sdelphij /* Set timeout to current time */ 355296341Sdelphij get_current_time(&(s->d1->next_timeout)); 356205128Ssimon 357296341Sdelphij /* Add duration to current time */ 358296341Sdelphij s->d1->next_timeout.tv_sec += s->d1->timeout_duration; 359296341Sdelphij BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, 360296341Sdelphij &(s->d1->next_timeout)); 361296341Sdelphij} 362205128Ssimon 363296341Sdelphijstruct timeval *dtls1_get_timeout(SSL *s, struct timeval *timeleft) 364296341Sdelphij{ 365296341Sdelphij struct timeval timenow; 366205128Ssimon 367296341Sdelphij /* If no timeout is set, just return NULL */ 368296341Sdelphij if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { 369296341Sdelphij return NULL; 370296341Sdelphij } 371205128Ssimon 372296341Sdelphij /* Get current time */ 373296341Sdelphij get_current_time(&timenow); 374205128Ssimon 375296341Sdelphij /* If timer already expired, set remaining time to 0 */ 376296341Sdelphij if (s->d1->next_timeout.tv_sec < timenow.tv_sec || 377296341Sdelphij (s->d1->next_timeout.tv_sec == timenow.tv_sec && 378296341Sdelphij s->d1->next_timeout.tv_usec <= timenow.tv_usec)) { 379296341Sdelphij memset(timeleft, 0, sizeof(struct timeval)); 380296341Sdelphij return timeleft; 381296341Sdelphij } 382205128Ssimon 383296341Sdelphij /* Calculate time left until timer expires */ 384296341Sdelphij memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval)); 385296341Sdelphij timeleft->tv_sec -= timenow.tv_sec; 386296341Sdelphij timeleft->tv_usec -= timenow.tv_usec; 387296341Sdelphij if (timeleft->tv_usec < 0) { 388296341Sdelphij timeleft->tv_sec--; 389296341Sdelphij timeleft->tv_usec += 1000000; 390296341Sdelphij } 391215697Ssimon 392296341Sdelphij /* 393296341Sdelphij * If remaining time is less than 15 ms, set it to 0 to prevent issues 394296341Sdelphij * because of small devergences with socket timeouts. 395296341Sdelphij */ 396296341Sdelphij if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) { 397296341Sdelphij memset(timeleft, 0, sizeof(struct timeval)); 398296341Sdelphij } 399205128Ssimon 400296341Sdelphij return timeleft; 401296341Sdelphij} 402296341Sdelphij 403205128Ssimonint dtls1_is_timer_expired(SSL *s) 404296341Sdelphij{ 405296341Sdelphij struct timeval timeleft; 406205128Ssimon 407296341Sdelphij /* Get time left until timeout, return false if no timer running */ 408296341Sdelphij if (dtls1_get_timeout(s, &timeleft) == NULL) { 409296341Sdelphij return 0; 410296341Sdelphij } 411205128Ssimon 412296341Sdelphij /* Return false if timer is not expired yet */ 413296341Sdelphij if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) { 414296341Sdelphij return 0; 415296341Sdelphij } 416205128Ssimon 417296341Sdelphij /* Timer expired, so return true */ 418296341Sdelphij return 1; 419296341Sdelphij} 420205128Ssimon 421205128Ssimonvoid dtls1_double_timeout(SSL *s) 422296341Sdelphij{ 423296341Sdelphij s->d1->timeout_duration *= 2; 424296341Sdelphij if (s->d1->timeout_duration > 60) 425296341Sdelphij s->d1->timeout_duration = 60; 426296341Sdelphij dtls1_start_timer(s); 427296341Sdelphij} 428205128Ssimon 429205128Ssimonvoid dtls1_stop_timer(SSL *s) 430296341Sdelphij{ 431296341Sdelphij /* Reset everything */ 432296341Sdelphij memset(&(s->d1->timeout), 0, sizeof(struct dtls1_timeout_st)); 433296341Sdelphij memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); 434296341Sdelphij s->d1->timeout_duration = 1; 435296341Sdelphij BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, 436296341Sdelphij &(s->d1->next_timeout)); 437296341Sdelphij /* Clear retransmission buffer */ 438306230Sdelphij dtls1_clear_sent_buffer(s); 439296341Sdelphij} 440205128Ssimon 441237657Sjkimint dtls1_check_timeout_num(SSL *s) 442296341Sdelphij{ 443296341Sdelphij unsigned int mtu; 444279264Sdelphij 445296341Sdelphij s->d1->timeout.num_alerts++; 446205128Ssimon 447296341Sdelphij /* Reduce MTU after 2 unsuccessful retransmissions */ 448296341Sdelphij if (s->d1->timeout.num_alerts > 2 449296341Sdelphij && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { 450296341Sdelphij mtu = 451296341Sdelphij BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, 452296341Sdelphij NULL); 453296341Sdelphij if (mtu < s->d1->mtu) 454296341Sdelphij s->d1->mtu = mtu; 455296341Sdelphij } 456205128Ssimon 457296341Sdelphij if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) { 458296341Sdelphij /* fail the connection, enough alerts have been sent */ 459296341Sdelphij SSLerr(SSL_F_DTLS1_CHECK_TIMEOUT_NUM, SSL_R_READ_TIMEOUT_EXPIRED); 460296341Sdelphij return -1; 461296341Sdelphij } 462237657Sjkim 463296341Sdelphij return 0; 464296341Sdelphij} 465237657Sjkim 466237657Sjkimint dtls1_handle_timeout(SSL *s) 467296341Sdelphij{ 468296341Sdelphij /* if no timer is expired, don't do anything */ 469296341Sdelphij if (!dtls1_is_timer_expired(s)) { 470296341Sdelphij return 0; 471296341Sdelphij } 472205128Ssimon 473296341Sdelphij dtls1_double_timeout(s); 474237657Sjkim 475296341Sdelphij if (dtls1_check_timeout_num(s) < 0) 476296341Sdelphij return -1; 477237657Sjkim 478296341Sdelphij s->d1->timeout.read_timeouts++; 479296341Sdelphij if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) { 480296341Sdelphij s->d1->timeout.read_timeouts = 1; 481296341Sdelphij } 482238405Sjkim#ifndef OPENSSL_NO_HEARTBEATS 483296341Sdelphij if (s->tlsext_hb_pending) { 484296341Sdelphij s->tlsext_hb_pending = 0; 485296341Sdelphij return dtls1_heartbeat(s); 486296341Sdelphij } 487238405Sjkim#endif 488238405Sjkim 489296341Sdelphij dtls1_start_timer(s); 490296341Sdelphij return dtls1_retransmit_buffered_messages(s); 491296341Sdelphij} 492205128Ssimon 493205128Ssimonstatic void get_current_time(struct timeval *t) 494205128Ssimon{ 495205128Ssimon#ifdef OPENSSL_SYS_WIN32 496296341Sdelphij struct _timeb tb; 497296341Sdelphij _ftime(&tb); 498296341Sdelphij t->tv_sec = (long)tb.time; 499296341Sdelphij t->tv_usec = (long)tb.millitm * 1000; 500205128Ssimon#elif defined(OPENSSL_SYS_VMS) 501296341Sdelphij struct timeb tb; 502296341Sdelphij ftime(&tb); 503296341Sdelphij t->tv_sec = (long)tb.time; 504296341Sdelphij t->tv_usec = (long)tb.millitm * 1000; 505205128Ssimon#else 506296341Sdelphij gettimeofday(t, NULL); 507205128Ssimon#endif 508205128Ssimon} 509205128Ssimon 510205128Ssimonint dtls1_listen(SSL *s, struct sockaddr *client) 511296341Sdelphij{ 512296341Sdelphij int ret; 513205128Ssimon 514284295Sdelphij /* Ensure there is no state left over from a previous invocation */ 515284295Sdelphij SSL_clear(s); 516284295Sdelphij 517296341Sdelphij SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE); 518296341Sdelphij s->d1->listen = 1; 519205128Ssimon 520296341Sdelphij ret = SSL_accept(s); 521296341Sdelphij if (ret <= 0) 522296341Sdelphij return ret; 523296341Sdelphij 524296341Sdelphij (void)BIO_dgram_get_peer(SSL_get_rbio(s), client); 525296341Sdelphij return 1; 526296341Sdelphij} 527