1160814Ssimon/* ssl/d1_lib.c */ 2280304Sjkim/* 3160814Ssimon * DTLS implementation written by Nagendra Modadugu 4280304Sjkim * (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 14280304Sjkim * 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) 66280304Sjkim# include <sys/timeb.h> 67205128Ssimon#endif 68205128Ssimon 69205128Ssimonstatic void get_current_time(struct timeval *t); 70280304Sjkimconst char dtls1_version_str[] = "DTLSv1" OPENSSL_VERSION_PTEXT; 71205128Ssimonint dtls1_listen(SSL *s, struct sockaddr *client); 72160814Ssimon 73280304SjkimSSL3_ENC_METHOD DTLSv1_enc_data = { 74160814Ssimon dtls1_enc, 75280304Sjkim tls1_mac, 76280304Sjkim tls1_setup_key_block, 77280304Sjkim tls1_generate_master_secret, 78280304Sjkim tls1_change_cipher_state, 79280304Sjkim tls1_final_finish_mac, 80280304Sjkim TLS1_FINISH_MAC_LENGTH, 81280304Sjkim tls1_cert_verify_mac, 82280304Sjkim TLS_MD_CLIENT_FINISH_CONST, TLS_MD_CLIENT_FINISH_CONST_SIZE, 83280304Sjkim TLS_MD_SERVER_FINISH_CONST, TLS_MD_SERVER_FINISH_CONST_SIZE, 84280304Sjkim tls1_alert_code, 85280304Sjkim tls1_export_keying_material, 86280304Sjkim}; 87160814Ssimon 88160814Ssimonlong dtls1_default_timeout(void) 89280304Sjkim{ 90280304Sjkim /* 91280304Sjkim * 2 hours, the 24 hours mentioned in the DTLSv1 spec is way too long for 92280304Sjkim * http, the cache would over fill 93280304Sjkim */ 94280304Sjkim return (60 * 60 * 2); 95280304Sjkim} 96160814Ssimon 97160814Ssimonint dtls1_new(SSL *s) 98280304Sjkim{ 99280304Sjkim DTLS1_STATE *d1; 100160814Ssimon 101280304Sjkim if (!ssl3_new(s)) 102280304Sjkim return (0); 103280304Sjkim if ((d1 = OPENSSL_malloc(sizeof *d1)) == NULL) 104280304Sjkim return (0); 105280304Sjkim memset(d1, 0, sizeof *d1); 106160814Ssimon 107280304Sjkim /* d1->handshake_epoch=0; */ 108160814Ssimon 109280304Sjkim d1->unprocessed_rcds.q = pqueue_new(); 110280304Sjkim d1->processed_rcds.q = pqueue_new(); 111280304Sjkim d1->buffered_messages = pqueue_new(); 112280304Sjkim d1->sent_messages = pqueue_new(); 113280304Sjkim d1->buffered_app_data.q = pqueue_new(); 114160814Ssimon 115280304Sjkim if (s->server) { 116280304Sjkim d1->cookie_len = sizeof(s->d1->cookie); 117280304Sjkim } 118160814Ssimon 119280304Sjkim d1->link_mtu = 0; 120280304Sjkim d1->mtu = 0; 121276864Sjkim 122280304Sjkim if (!d1->unprocessed_rcds.q || !d1->processed_rcds.q 123280304Sjkim || !d1->buffered_messages || !d1->sent_messages 124280304Sjkim || !d1->buffered_app_data.q) { 125280304Sjkim if (d1->unprocessed_rcds.q) 126280304Sjkim pqueue_free(d1->unprocessed_rcds.q); 127280304Sjkim if (d1->processed_rcds.q) 128280304Sjkim pqueue_free(d1->processed_rcds.q); 129280304Sjkim if (d1->buffered_messages) 130280304Sjkim pqueue_free(d1->buffered_messages); 131280304Sjkim if (d1->sent_messages) 132280304Sjkim pqueue_free(d1->sent_messages); 133280304Sjkim if (d1->buffered_app_data.q) 134280304Sjkim pqueue_free(d1->buffered_app_data.q); 135280304Sjkim OPENSSL_free(d1); 136280304Sjkim return (0); 137280304Sjkim } 138160814Ssimon 139280304Sjkim s->d1 = d1; 140280304Sjkim s->method->ssl_clear(s); 141280304Sjkim return (1); 142280304Sjkim} 143160814Ssimon 144237657Sjkimstatic void dtls1_clear_queues(SSL *s) 145280304Sjkim{ 146160814Ssimon pitem *item = NULL; 147280304Sjkim DTLS1_RECORD_DATA *rdata; 148160814Ssimon 149280304Sjkim while ((item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) { 150280304Sjkim rdata = (DTLS1_RECORD_DATA *)item->data; 151280304Sjkim if (rdata->rbuf.buf) { 152280304Sjkim OPENSSL_free(rdata->rbuf.buf); 153280304Sjkim } 154160814Ssimon OPENSSL_free(item->data); 155160814Ssimon pitem_free(item); 156280304Sjkim } 157280304Sjkim 158280304Sjkim while ((item = pqueue_pop(s->d1->processed_rcds.q)) != NULL) { 159280304Sjkim rdata = (DTLS1_RECORD_DATA *)item->data; 160280304Sjkim if (rdata->rbuf.buf) { 161280304Sjkim OPENSSL_free(rdata->rbuf.buf); 162160814Ssimon } 163160814Ssimon OPENSSL_free(item->data); 164160814Ssimon pitem_free(item); 165280304Sjkim } 166160814Ssimon 167306196Sjkim while ((item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) { 168306196Sjkim rdata = (DTLS1_RECORD_DATA *)item->data; 169306196Sjkim if (rdata->rbuf.buf) { 170306196Sjkim OPENSSL_free(rdata->rbuf.buf); 171306196Sjkim } 172306196Sjkim OPENSSL_free(item->data); 173306196Sjkim pitem_free(item); 174306196Sjkim } 175306196Sjkim 176306196Sjkim dtls1_clear_received_buffer(s); 177306196Sjkim dtls1_clear_sent_buffer(s); 178306196Sjkim} 179306196Sjkim 180306196Sjkimvoid dtls1_clear_received_buffer(SSL *s) 181306196Sjkim{ 182306196Sjkim pitem *item = NULL; 183306196Sjkim hm_fragment *frag = NULL; 184306196Sjkim 185280304Sjkim while ((item = pqueue_pop(s->d1->buffered_messages)) != NULL) { 186160814Ssimon frag = (hm_fragment *)item->data; 187276864Sjkim dtls1_hm_fragment_free(frag); 188160814Ssimon pitem_free(item); 189280304Sjkim } 190306196Sjkim} 191160814Ssimon 192306196Sjkimvoid dtls1_clear_sent_buffer(SSL *s) 193306196Sjkim{ 194306196Sjkim pitem *item = NULL; 195306196Sjkim hm_fragment *frag = NULL; 196306196Sjkim 197280304Sjkim while ((item = pqueue_pop(s->d1->sent_messages)) != NULL) { 198160814Ssimon frag = (hm_fragment *)item->data; 199276864Sjkim dtls1_hm_fragment_free(frag); 200160814Ssimon pitem_free(item); 201280304Sjkim } 202280304Sjkim} 203160814Ssimon 204306196Sjkim 205237657Sjkimvoid dtls1_free(SSL *s) 206280304Sjkim{ 207280304Sjkim ssl3_free(s); 208237657Sjkim 209280304Sjkim 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); 214280304Sjkim pqueue_free(s->d1->sent_messages); 215280304Sjkim pqueue_free(s->d1->buffered_app_data.q); 216160814Ssimon 217280304Sjkim OPENSSL_free(s->d1); 218280304Sjkim s->d1 = NULL; 219280304Sjkim} 220160814Ssimon 221160814Ssimonvoid dtls1_clear(SSL *s) 222280304Sjkim{ 223237657Sjkim pqueue unprocessed_rcds; 224237657Sjkim pqueue processed_rcds; 225237657Sjkim pqueue buffered_messages; 226280304Sjkim pqueue sent_messages; 227280304Sjkim pqueue buffered_app_data; 228280304Sjkim unsigned int mtu; 229280304Sjkim unsigned int link_mtu; 230237657Sjkim 231280304Sjkim if (s->d1) { 232280304Sjkim unprocessed_rcds = s->d1->unprocessed_rcds.q; 233280304Sjkim processed_rcds = s->d1->processed_rcds.q; 234280304Sjkim buffered_messages = s->d1->buffered_messages; 235280304Sjkim sent_messages = s->d1->sent_messages; 236280304Sjkim buffered_app_data = s->d1->buffered_app_data.q; 237280304Sjkim mtu = s->d1->mtu; 238280304Sjkim link_mtu = s->d1->link_mtu; 239237657Sjkim 240280304Sjkim dtls1_clear_queues(s); 241237657Sjkim 242280304Sjkim memset(s->d1, 0, sizeof(*(s->d1))); 243237657Sjkim 244280304Sjkim if (s->server) { 245280304Sjkim s->d1->cookie_len = sizeof(s->d1->cookie); 246280304Sjkim } 247237657Sjkim 248280304Sjkim if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) { 249280304Sjkim s->d1->mtu = mtu; 250280304Sjkim s->d1->link_mtu = link_mtu; 251280304Sjkim } 252237657Sjkim 253280304Sjkim s->d1->unprocessed_rcds.q = unprocessed_rcds; 254280304Sjkim s->d1->processed_rcds.q = processed_rcds; 255280304Sjkim s->d1->buffered_messages = buffered_messages; 256280304Sjkim s->d1->sent_messages = sent_messages; 257280304Sjkim s->d1->buffered_app_data.q = buffered_app_data; 258280304Sjkim } 259237657Sjkim 260280304Sjkim ssl3_clear(s); 261280304Sjkim if (s->options & SSL_OP_CISCO_ANYCONNECT) 262280304Sjkim s->version = DTLS1_BAD_VER; 263280304Sjkim else 264280304Sjkim s->version = DTLS1_VERSION; 265280304Sjkim} 266194206Ssimon 267205128Ssimonlong dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) 268280304Sjkim{ 269280304Sjkim int ret = 0; 270205128Ssimon 271280304Sjkim switch (cmd) { 272280304Sjkim case DTLS_CTRL_GET_TIMEOUT: 273280304Sjkim if (dtls1_get_timeout(s, (struct timeval *)parg) != NULL) { 274280304Sjkim ret = 1; 275280304Sjkim } 276280304Sjkim break; 277280304Sjkim case DTLS_CTRL_HANDLE_TIMEOUT: 278280304Sjkim ret = dtls1_handle_timeout(s); 279280304Sjkim break; 280280304Sjkim case DTLS_CTRL_LISTEN: 281280304Sjkim ret = dtls1_listen(s, parg); 282280304Sjkim break; 283280304Sjkim case SSL_CTRL_CHECK_PROTO_VERSION: 284280304Sjkim /* 285280304Sjkim * For library-internal use; checks that the current protocol is the 286280304Sjkim * highest enabled version (according to s->ctx->method, as version 287280304Sjkim * negotiation may have changed s->method). 288280304Sjkim */ 289273149Sjkim#if DTLS_MAX_VERSION != DTLS1_VERSION 290280304Sjkim# error Code needs update for DTLS_method() support beyond DTLS1_VERSION. 291273149Sjkim#endif 292280304Sjkim /* 293280304Sjkim * Just one protocol version is supported so far; fail closed if the 294280304Sjkim * version is not as expected. 295280304Sjkim */ 296280304Sjkim return s->version == DTLS_MAX_VERSION; 297280304Sjkim case DTLS_CTRL_SET_LINK_MTU: 298280304Sjkim if (larg < (long)dtls1_link_min_mtu()) 299280304Sjkim return 0; 300280304Sjkim s->d1->link_mtu = larg; 301280304Sjkim return 1; 302280304Sjkim case DTLS_CTRL_GET_LINK_MIN_MTU: 303280304Sjkim return (long)dtls1_link_min_mtu(); 304280304Sjkim case SSL_CTRL_SET_MTU: 305280304Sjkim /* 306280304Sjkim * We may not have a BIO set yet so can't call dtls1_min_mtu() 307280304Sjkim * We'll have to make do with dtls1_link_min_mtu() and max overhead 308280304Sjkim */ 309280304Sjkim if (larg < (long)dtls1_link_min_mtu() - DTLS1_MAX_MTU_OVERHEAD) 310280304Sjkim return 0; 311280304Sjkim s->d1->mtu = larg; 312280304Sjkim return larg; 313280304Sjkim default: 314280304Sjkim ret = ssl3_ctrl(s, cmd, larg, parg); 315280304Sjkim break; 316280304Sjkim } 317280304Sjkim return (ret); 318280304Sjkim} 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) 328280304Sjkim{ 329280304Sjkim const SSL_CIPHER *ciph = ssl3_get_cipher(u); 330194206Ssimon 331280304Sjkim if (ciph != NULL) { 332280304Sjkim if (ciph->algorithm_enc == SSL_RC4) 333280304Sjkim return NULL; 334280304Sjkim } 335194206Ssimon 336280304Sjkim return ciph; 337280304Sjkim} 338205128Ssimon 339205128Ssimonvoid dtls1_start_timer(SSL *s) 340280304Sjkim{ 341238405Sjkim#ifndef OPENSSL_NO_SCTP 342280304Sjkim /* Disable timer for SCTP */ 343280304Sjkim if (BIO_dgram_is_sctp(SSL_get_wbio(s))) { 344280304Sjkim memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); 345280304Sjkim return; 346280304Sjkim } 347238405Sjkim#endif 348238405Sjkim 349280304Sjkim /* If timer is not set, initialize duration with 1 second */ 350280304Sjkim if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { 351280304Sjkim s->d1->timeout_duration = 1; 352280304Sjkim } 353205128Ssimon 354280304Sjkim /* Set timeout to current time */ 355280304Sjkim get_current_time(&(s->d1->next_timeout)); 356205128Ssimon 357280304Sjkim /* Add duration to current time */ 358280304Sjkim s->d1->next_timeout.tv_sec += s->d1->timeout_duration; 359280304Sjkim BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, 360280304Sjkim &(s->d1->next_timeout)); 361280304Sjkim} 362205128Ssimon 363280304Sjkimstruct timeval *dtls1_get_timeout(SSL *s, struct timeval *timeleft) 364280304Sjkim{ 365280304Sjkim struct timeval timenow; 366205128Ssimon 367280304Sjkim /* If no timeout is set, just return NULL */ 368280304Sjkim if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { 369280304Sjkim return NULL; 370280304Sjkim } 371205128Ssimon 372280304Sjkim /* Get current time */ 373280304Sjkim get_current_time(&timenow); 374205128Ssimon 375280304Sjkim /* If timer already expired, set remaining time to 0 */ 376280304Sjkim if (s->d1->next_timeout.tv_sec < timenow.tv_sec || 377280304Sjkim (s->d1->next_timeout.tv_sec == timenow.tv_sec && 378280304Sjkim s->d1->next_timeout.tv_usec <= timenow.tv_usec)) { 379280304Sjkim memset(timeleft, 0, sizeof(struct timeval)); 380280304Sjkim return timeleft; 381280304Sjkim } 382205128Ssimon 383280304Sjkim /* Calculate time left until timer expires */ 384280304Sjkim memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval)); 385280304Sjkim timeleft->tv_sec -= timenow.tv_sec; 386280304Sjkim timeleft->tv_usec -= timenow.tv_usec; 387280304Sjkim if (timeleft->tv_usec < 0) { 388280304Sjkim timeleft->tv_sec--; 389280304Sjkim timeleft->tv_usec += 1000000; 390280304Sjkim } 391215697Ssimon 392280304Sjkim /* 393280304Sjkim * If remaining time is less than 15 ms, set it to 0 to prevent issues 394280304Sjkim * because of small devergences with socket timeouts. 395280304Sjkim */ 396280304Sjkim if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) { 397280304Sjkim memset(timeleft, 0, sizeof(struct timeval)); 398280304Sjkim } 399205128Ssimon 400280304Sjkim return timeleft; 401280304Sjkim} 402280304Sjkim 403205128Ssimonint dtls1_is_timer_expired(SSL *s) 404280304Sjkim{ 405280304Sjkim struct timeval timeleft; 406205128Ssimon 407280304Sjkim /* Get time left until timeout, return false if no timer running */ 408280304Sjkim if (dtls1_get_timeout(s, &timeleft) == NULL) { 409280304Sjkim return 0; 410280304Sjkim } 411205128Ssimon 412280304Sjkim /* Return false if timer is not expired yet */ 413280304Sjkim if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) { 414280304Sjkim return 0; 415280304Sjkim } 416205128Ssimon 417280304Sjkim /* Timer expired, so return true */ 418280304Sjkim return 1; 419280304Sjkim} 420205128Ssimon 421205128Ssimonvoid dtls1_double_timeout(SSL *s) 422280304Sjkim{ 423280304Sjkim s->d1->timeout_duration *= 2; 424280304Sjkim if (s->d1->timeout_duration > 60) 425280304Sjkim s->d1->timeout_duration = 60; 426280304Sjkim dtls1_start_timer(s); 427280304Sjkim} 428205128Ssimon 429205128Ssimonvoid dtls1_stop_timer(SSL *s) 430280304Sjkim{ 431280304Sjkim /* Reset everything */ 432280304Sjkim memset(&(s->d1->timeout), 0, sizeof(struct dtls1_timeout_st)); 433280304Sjkim memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); 434280304Sjkim s->d1->timeout_duration = 1; 435280304Sjkim BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, 436280304Sjkim &(s->d1->next_timeout)); 437280304Sjkim /* Clear retransmission buffer */ 438306196Sjkim dtls1_clear_sent_buffer(s); 439280304Sjkim} 440205128Ssimon 441237657Sjkimint dtls1_check_timeout_num(SSL *s) 442280304Sjkim{ 443280304Sjkim unsigned int mtu; 444276864Sjkim 445280304Sjkim s->d1->timeout.num_alerts++; 446205128Ssimon 447280304Sjkim /* Reduce MTU after 2 unsuccessful retransmissions */ 448280304Sjkim if (s->d1->timeout.num_alerts > 2 449280304Sjkim && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) { 450280304Sjkim mtu = 451280304Sjkim BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, 452280304Sjkim NULL); 453280304Sjkim if (mtu < s->d1->mtu) 454280304Sjkim s->d1->mtu = mtu; 455280304Sjkim } 456205128Ssimon 457280304Sjkim if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) { 458280304Sjkim /* fail the connection, enough alerts have been sent */ 459280304Sjkim SSLerr(SSL_F_DTLS1_CHECK_TIMEOUT_NUM, SSL_R_READ_TIMEOUT_EXPIRED); 460280304Sjkim return -1; 461280304Sjkim } 462237657Sjkim 463280304Sjkim return 0; 464280304Sjkim} 465237657Sjkim 466237657Sjkimint dtls1_handle_timeout(SSL *s) 467280304Sjkim{ 468280304Sjkim /* if no timer is expired, don't do anything */ 469280304Sjkim if (!dtls1_is_timer_expired(s)) { 470280304Sjkim return 0; 471280304Sjkim } 472205128Ssimon 473280304Sjkim dtls1_double_timeout(s); 474237657Sjkim 475280304Sjkim if (dtls1_check_timeout_num(s) < 0) 476280304Sjkim return -1; 477237657Sjkim 478280304Sjkim s->d1->timeout.read_timeouts++; 479280304Sjkim if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) { 480280304Sjkim s->d1->timeout.read_timeouts = 1; 481280304Sjkim } 482238405Sjkim#ifndef OPENSSL_NO_HEARTBEATS 483280304Sjkim if (s->tlsext_hb_pending) { 484280304Sjkim s->tlsext_hb_pending = 0; 485280304Sjkim return dtls1_heartbeat(s); 486280304Sjkim } 487238405Sjkim#endif 488238405Sjkim 489280304Sjkim dtls1_start_timer(s); 490280304Sjkim return dtls1_retransmit_buffered_messages(s); 491280304Sjkim} 492205128Ssimon 493205128Ssimonstatic void get_current_time(struct timeval *t) 494205128Ssimon{ 495205128Ssimon#ifdef OPENSSL_SYS_WIN32 496280304Sjkim struct _timeb tb; 497280304Sjkim _ftime(&tb); 498280304Sjkim t->tv_sec = (long)tb.time; 499280304Sjkim t->tv_usec = (long)tb.millitm * 1000; 500205128Ssimon#elif defined(OPENSSL_SYS_VMS) 501280304Sjkim struct timeb tb; 502280304Sjkim ftime(&tb); 503280304Sjkim t->tv_sec = (long)tb.time; 504280304Sjkim t->tv_usec = (long)tb.millitm * 1000; 505205128Ssimon#else 506280304Sjkim gettimeofday(t, NULL); 507205128Ssimon#endif 508205128Ssimon} 509205128Ssimon 510205128Ssimonint dtls1_listen(SSL *s, struct sockaddr *client) 511280304Sjkim{ 512280304Sjkim int ret; 513205128Ssimon 514284285Sjkim /* Ensure there is no state left over from a previous invocation */ 515284285Sjkim SSL_clear(s); 516284285Sjkim 517280304Sjkim SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE); 518280304Sjkim s->d1->listen = 1; 519205128Ssimon 520280304Sjkim ret = SSL_accept(s); 521280304Sjkim if (ret <= 0) 522280304Sjkim return ret; 523280304Sjkim 524280304Sjkim (void)BIO_dgram_get_peer(SSL_get_rbio(s), client); 525280304Sjkim return 1; 526280304Sjkim} 527