d1_lib.c revision 276861
1160814Ssimon/* ssl/d1_lib.c */ 2160814Ssimon/* 3160814Ssimon * DTLS implementation written by Nagendra Modadugu 4160814Ssimon * (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 14160814Ssimon * 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) 66205128Ssimon#include <sys/timeb.h> 67205128Ssimon#endif 68205128Ssimon 69205128Ssimonstatic void get_current_time(struct timeval *t); 70167612Ssimonconst char dtls1_version_str[]="DTLSv1" OPENSSL_VERSION_PTEXT; 71205128Ssimonint dtls1_listen(SSL *s, struct sockaddr *client); 72160814Ssimon 73160814SsimonSSL3_ENC_METHOD DTLSv1_enc_data={ 74160814Ssimon dtls1_enc, 75160814Ssimon tls1_mac, 76160814Ssimon tls1_setup_key_block, 77160814Ssimon tls1_generate_master_secret, 78160814Ssimon tls1_change_cipher_state, 79160814Ssimon tls1_final_finish_mac, 80160814Ssimon TLS1_FINISH_MAC_LENGTH, 81160814Ssimon tls1_cert_verify_mac, 82160814Ssimon TLS_MD_CLIENT_FINISH_CONST,TLS_MD_CLIENT_FINISH_CONST_SIZE, 83160814Ssimon TLS_MD_SERVER_FINISH_CONST,TLS_MD_SERVER_FINISH_CONST_SIZE, 84160814Ssimon tls1_alert_code, 85238405Sjkim tls1_export_keying_material, 86160814Ssimon }; 87160814Ssimon 88160814Ssimonlong dtls1_default_timeout(void) 89160814Ssimon { 90160814Ssimon /* 2 hours, the 24 hours mentioned in the DTLSv1 spec 91160814Ssimon * is way too long for http, the cache would over fill */ 92160814Ssimon return(60*60*2); 93160814Ssimon } 94160814Ssimon 95160814Ssimonint dtls1_new(SSL *s) 96160814Ssimon { 97160814Ssimon DTLS1_STATE *d1; 98160814Ssimon 99160814Ssimon if (!ssl3_new(s)) return(0); 100160814Ssimon if ((d1=OPENSSL_malloc(sizeof *d1)) == NULL) return (0); 101160814Ssimon memset(d1,0, sizeof *d1); 102160814Ssimon 103160814Ssimon /* d1->handshake_epoch=0; */ 104160814Ssimon 105160814Ssimon d1->unprocessed_rcds.q=pqueue_new(); 106160814Ssimon d1->processed_rcds.q=pqueue_new(); 107160814Ssimon d1->buffered_messages = pqueue_new(); 108160814Ssimon d1->sent_messages=pqueue_new(); 109205128Ssimon d1->buffered_app_data.q=pqueue_new(); 110160814Ssimon 111160814Ssimon if ( s->server) 112160814Ssimon { 113160814Ssimon d1->cookie_len = sizeof(s->d1->cookie); 114160814Ssimon } 115160814Ssimon 116276861Sjkim d1->link_mtu = 0; 117276861Sjkim d1->mtu = 0; 118276861Sjkim 119160814Ssimon if( ! d1->unprocessed_rcds.q || ! d1->processed_rcds.q 120205128Ssimon || ! d1->buffered_messages || ! d1->sent_messages || ! d1->buffered_app_data.q) 121160814Ssimon { 122160814Ssimon if ( d1->unprocessed_rcds.q) pqueue_free(d1->unprocessed_rcds.q); 123160814Ssimon if ( d1->processed_rcds.q) pqueue_free(d1->processed_rcds.q); 124160814Ssimon if ( d1->buffered_messages) pqueue_free(d1->buffered_messages); 125160814Ssimon if ( d1->sent_messages) pqueue_free(d1->sent_messages); 126205128Ssimon if ( d1->buffered_app_data.q) pqueue_free(d1->buffered_app_data.q); 127160814Ssimon OPENSSL_free(d1); 128160814Ssimon return (0); 129160814Ssimon } 130160814Ssimon 131160814Ssimon s->d1=d1; 132160814Ssimon s->method->ssl_clear(s); 133160814Ssimon return(1); 134160814Ssimon } 135160814Ssimon 136237657Sjkimstatic void dtls1_clear_queues(SSL *s) 137160814Ssimon { 138160814Ssimon pitem *item = NULL; 139160814Ssimon hm_fragment *frag = NULL; 140237657Sjkim DTLS1_RECORD_DATA *rdata; 141160814Ssimon 142160814Ssimon while( (item = pqueue_pop(s->d1->unprocessed_rcds.q)) != NULL) 143160814Ssimon { 144237657Sjkim rdata = (DTLS1_RECORD_DATA *) item->data; 145237657Sjkim if (rdata->rbuf.buf) 146237657Sjkim { 147237657Sjkim OPENSSL_free(rdata->rbuf.buf); 148237657Sjkim } 149160814Ssimon OPENSSL_free(item->data); 150160814Ssimon pitem_free(item); 151160814Ssimon } 152160814Ssimon 153160814Ssimon while( (item = pqueue_pop(s->d1->processed_rcds.q)) != NULL) 154160814Ssimon { 155237657Sjkim rdata = (DTLS1_RECORD_DATA *) item->data; 156237657Sjkim if (rdata->rbuf.buf) 157237657Sjkim { 158237657Sjkim OPENSSL_free(rdata->rbuf.buf); 159237657Sjkim } 160160814Ssimon OPENSSL_free(item->data); 161160814Ssimon pitem_free(item); 162160814Ssimon } 163160814Ssimon 164160814Ssimon while( (item = pqueue_pop(s->d1->buffered_messages)) != NULL) 165160814Ssimon { 166160814Ssimon frag = (hm_fragment *)item->data; 167276861Sjkim dtls1_hm_fragment_free(frag); 168160814Ssimon pitem_free(item); 169160814Ssimon } 170160814Ssimon 171160814Ssimon while ( (item = pqueue_pop(s->d1->sent_messages)) != NULL) 172160814Ssimon { 173160814Ssimon frag = (hm_fragment *)item->data; 174276861Sjkim dtls1_hm_fragment_free(frag); 175160814Ssimon pitem_free(item); 176160814Ssimon } 177160814Ssimon 178205128Ssimon while ( (item = pqueue_pop(s->d1->buffered_app_data.q)) != NULL) 179237657Sjkim { 180267256Sjkim rdata = (DTLS1_RECORD_DATA *) item->data; 181267256Sjkim if (rdata->rbuf.buf) 182267256Sjkim { 183267256Sjkim OPENSSL_free(rdata->rbuf.buf); 184267256Sjkim } 185267256Sjkim OPENSSL_free(item->data); 186205128Ssimon pitem_free(item); 187237657Sjkim } 188205128Ssimon } 189237657Sjkim 190237657Sjkimvoid dtls1_free(SSL *s) 191237657Sjkim { 192237657Sjkim ssl3_free(s); 193237657Sjkim 194237657Sjkim dtls1_clear_queues(s); 195237657Sjkim 196237657Sjkim pqueue_free(s->d1->unprocessed_rcds.q); 197237657Sjkim pqueue_free(s->d1->processed_rcds.q); 198237657Sjkim pqueue_free(s->d1->buffered_messages); 199237657Sjkim pqueue_free(s->d1->sent_messages); 200205128Ssimon pqueue_free(s->d1->buffered_app_data.q); 201160814Ssimon 202160814Ssimon OPENSSL_free(s->d1); 203261037Sjkim s->d1 = NULL; 204160814Ssimon } 205160814Ssimon 206160814Ssimonvoid dtls1_clear(SSL *s) 207160814Ssimon { 208237657Sjkim pqueue unprocessed_rcds; 209237657Sjkim pqueue processed_rcds; 210237657Sjkim pqueue buffered_messages; 211237657Sjkim pqueue sent_messages; 212237657Sjkim pqueue buffered_app_data; 213237657Sjkim unsigned int mtu; 214276861Sjkim unsigned int link_mtu; 215237657Sjkim 216237657Sjkim if (s->d1) 217237657Sjkim { 218237657Sjkim unprocessed_rcds = s->d1->unprocessed_rcds.q; 219237657Sjkim processed_rcds = s->d1->processed_rcds.q; 220237657Sjkim buffered_messages = s->d1->buffered_messages; 221237657Sjkim sent_messages = s->d1->sent_messages; 222237657Sjkim buffered_app_data = s->d1->buffered_app_data.q; 223237657Sjkim mtu = s->d1->mtu; 224276861Sjkim link_mtu = s->d1->link_mtu; 225237657Sjkim 226237657Sjkim dtls1_clear_queues(s); 227237657Sjkim 228237657Sjkim memset(s->d1, 0, sizeof(*(s->d1))); 229237657Sjkim 230237657Sjkim if (s->server) 231237657Sjkim { 232237657Sjkim s->d1->cookie_len = sizeof(s->d1->cookie); 233237657Sjkim } 234237657Sjkim 235237657Sjkim if (SSL_get_options(s) & SSL_OP_NO_QUERY_MTU) 236237657Sjkim { 237237657Sjkim s->d1->mtu = mtu; 238276861Sjkim s->d1->link_mtu = link_mtu; 239237657Sjkim } 240237657Sjkim 241237657Sjkim s->d1->unprocessed_rcds.q = unprocessed_rcds; 242237657Sjkim s->d1->processed_rcds.q = processed_rcds; 243237657Sjkim s->d1->buffered_messages = buffered_messages; 244237657Sjkim s->d1->sent_messages = sent_messages; 245237657Sjkim s->d1->buffered_app_data.q = buffered_app_data; 246237657Sjkim } 247237657Sjkim 248160814Ssimon ssl3_clear(s); 249205128Ssimon if (s->options & SSL_OP_CISCO_ANYCONNECT) 250205128Ssimon s->version=DTLS1_BAD_VER; 251205128Ssimon else 252205128Ssimon s->version=DTLS1_VERSION; 253160814Ssimon } 254194206Ssimon 255205128Ssimonlong dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) 256205128Ssimon { 257205128Ssimon int ret=0; 258205128Ssimon 259205128Ssimon switch (cmd) 260205128Ssimon { 261205128Ssimon case DTLS_CTRL_GET_TIMEOUT: 262205128Ssimon if (dtls1_get_timeout(s, (struct timeval*) parg) != NULL) 263205128Ssimon { 264205128Ssimon ret = 1; 265205128Ssimon } 266205128Ssimon break; 267205128Ssimon case DTLS_CTRL_HANDLE_TIMEOUT: 268205128Ssimon ret = dtls1_handle_timeout(s); 269205128Ssimon break; 270205128Ssimon case DTLS_CTRL_LISTEN: 271205128Ssimon ret = dtls1_listen(s, parg); 272205128Ssimon break; 273273144Sjkim case SSL_CTRL_CHECK_PROTO_VERSION: 274273144Sjkim /* For library-internal use; checks that the current protocol 275273144Sjkim * is the highest enabled version (according to s->ctx->method, 276273144Sjkim * as version negotiation may have changed s->method). */ 277273144Sjkim#if DTLS_MAX_VERSION != DTLS1_VERSION 278273144Sjkim# error Code needs update for DTLS_method() support beyond DTLS1_VERSION. 279273144Sjkim#endif 280273144Sjkim /* Just one protocol version is supported so far; 281273144Sjkim * fail closed if the version is not as expected. */ 282273144Sjkim return s->version == DTLS_MAX_VERSION; 283276861Sjkim case DTLS_CTRL_SET_LINK_MTU: 284276861Sjkim if (larg < (long)dtls1_link_min_mtu()) 285276861Sjkim return 0; 286276861Sjkim s->d1->link_mtu = larg; 287276861Sjkim return 1; 288276861Sjkim case DTLS_CTRL_GET_LINK_MIN_MTU: 289276861Sjkim return (long)dtls1_link_min_mtu(); 290276861Sjkim case SSL_CTRL_SET_MTU: 291276861Sjkim /* 292276861Sjkim * We may not have a BIO set yet so can't call dtls1_min_mtu() 293276861Sjkim * We'll have to make do with dtls1_link_min_mtu() and max overhead 294276861Sjkim */ 295276861Sjkim if (larg < (long)dtls1_link_min_mtu() - DTLS1_MAX_MTU_OVERHEAD) 296276861Sjkim return 0; 297276861Sjkim s->d1->mtu = larg; 298276861Sjkim return larg; 299205128Ssimon default: 300205128Ssimon ret = ssl3_ctrl(s, cmd, larg, parg); 301205128Ssimon break; 302205128Ssimon } 303205128Ssimon return(ret); 304205128Ssimon } 305205128Ssimon 306194206Ssimon/* 307194206Ssimon * As it's impossible to use stream ciphers in "datagram" mode, this 308194206Ssimon * simple filter is designed to disengage them in DTLS. Unfortunately 309194206Ssimon * there is no universal way to identify stream SSL_CIPHER, so we have 310194206Ssimon * to explicitly list their SSL_* codes. Currently RC4 is the only one 311194206Ssimon * available, but if new ones emerge, they will have to be added... 312194206Ssimon */ 313238405Sjkimconst SSL_CIPHER *dtls1_get_cipher(unsigned int u) 314194206Ssimon { 315238405Sjkim const SSL_CIPHER *ciph = ssl3_get_cipher(u); 316194206Ssimon 317194206Ssimon if (ciph != NULL) 318194206Ssimon { 319238405Sjkim if (ciph->algorithm_enc == SSL_RC4) 320194206Ssimon return NULL; 321194206Ssimon } 322194206Ssimon 323194206Ssimon return ciph; 324194206Ssimon } 325205128Ssimon 326205128Ssimonvoid dtls1_start_timer(SSL *s) 327205128Ssimon { 328238405Sjkim#ifndef OPENSSL_NO_SCTP 329238405Sjkim /* Disable timer for SCTP */ 330238405Sjkim if (BIO_dgram_is_sctp(SSL_get_wbio(s))) 331238405Sjkim { 332238405Sjkim memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); 333238405Sjkim return; 334238405Sjkim } 335238405Sjkim#endif 336238405Sjkim 337205128Ssimon /* If timer is not set, initialize duration with 1 second */ 338205128Ssimon if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) 339205128Ssimon { 340205128Ssimon s->d1->timeout_duration = 1; 341205128Ssimon } 342205128Ssimon 343205128Ssimon /* Set timeout to current time */ 344205128Ssimon get_current_time(&(s->d1->next_timeout)); 345205128Ssimon 346205128Ssimon /* Add duration to current time */ 347205128Ssimon s->d1->next_timeout.tv_sec += s->d1->timeout_duration; 348205128Ssimon BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout)); 349205128Ssimon } 350205128Ssimon 351205128Ssimonstruct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft) 352205128Ssimon { 353205128Ssimon struct timeval timenow; 354205128Ssimon 355205128Ssimon /* If no timeout is set, just return NULL */ 356205128Ssimon if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) 357205128Ssimon { 358205128Ssimon return NULL; 359205128Ssimon } 360205128Ssimon 361205128Ssimon /* Get current time */ 362205128Ssimon get_current_time(&timenow); 363205128Ssimon 364205128Ssimon /* If timer already expired, set remaining time to 0 */ 365205128Ssimon if (s->d1->next_timeout.tv_sec < timenow.tv_sec || 366205128Ssimon (s->d1->next_timeout.tv_sec == timenow.tv_sec && 367205128Ssimon s->d1->next_timeout.tv_usec <= timenow.tv_usec)) 368205128Ssimon { 369205128Ssimon memset(timeleft, 0, sizeof(struct timeval)); 370205128Ssimon return timeleft; 371205128Ssimon } 372205128Ssimon 373205128Ssimon /* Calculate time left until timer expires */ 374205128Ssimon memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval)); 375205128Ssimon timeleft->tv_sec -= timenow.tv_sec; 376205128Ssimon timeleft->tv_usec -= timenow.tv_usec; 377205128Ssimon if (timeleft->tv_usec < 0) 378205128Ssimon { 379205128Ssimon timeleft->tv_sec--; 380205128Ssimon timeleft->tv_usec += 1000000; 381205128Ssimon } 382205128Ssimon 383215697Ssimon /* If remaining time is less than 15 ms, set it to 0 384215697Ssimon * to prevent issues because of small devergences with 385215697Ssimon * socket timeouts. 386215697Ssimon */ 387215697Ssimon if (timeleft->tv_sec == 0 && timeleft->tv_usec < 15000) 388215697Ssimon { 389215697Ssimon memset(timeleft, 0, sizeof(struct timeval)); 390215697Ssimon } 391215697Ssimon 392215697Ssimon 393205128Ssimon return timeleft; 394205128Ssimon } 395205128Ssimon 396205128Ssimonint dtls1_is_timer_expired(SSL *s) 397205128Ssimon { 398205128Ssimon struct timeval timeleft; 399205128Ssimon 400205128Ssimon /* Get time left until timeout, return false if no timer running */ 401205128Ssimon if (dtls1_get_timeout(s, &timeleft) == NULL) 402205128Ssimon { 403205128Ssimon return 0; 404205128Ssimon } 405205128Ssimon 406205128Ssimon /* Return false if timer is not expired yet */ 407205128Ssimon if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) 408205128Ssimon { 409205128Ssimon return 0; 410205128Ssimon } 411205128Ssimon 412205128Ssimon /* Timer expired, so return true */ 413205128Ssimon return 1; 414205128Ssimon } 415205128Ssimon 416205128Ssimonvoid dtls1_double_timeout(SSL *s) 417205128Ssimon { 418205128Ssimon s->d1->timeout_duration *= 2; 419205128Ssimon if (s->d1->timeout_duration > 60) 420205128Ssimon s->d1->timeout_duration = 60; 421205128Ssimon dtls1_start_timer(s); 422205128Ssimon } 423205128Ssimon 424205128Ssimonvoid dtls1_stop_timer(SSL *s) 425205128Ssimon { 426205128Ssimon /* Reset everything */ 427237657Sjkim memset(&(s->d1->timeout), 0, sizeof(struct dtls1_timeout_st)); 428205128Ssimon memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); 429205128Ssimon s->d1->timeout_duration = 1; 430205128Ssimon BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout)); 431237657Sjkim /* Clear retransmission buffer */ 432237657Sjkim dtls1_clear_record_buffer(s); 433205128Ssimon } 434205128Ssimon 435237657Sjkimint dtls1_check_timeout_num(SSL *s) 436205128Ssimon { 437276861Sjkim unsigned int mtu; 438276861Sjkim 439237657Sjkim s->d1->timeout.num_alerts++; 440205128Ssimon 441237657Sjkim /* Reduce MTU after 2 unsuccessful retransmissions */ 442276861Sjkim if (s->d1->timeout.num_alerts > 2 443276861Sjkim && !(SSL_get_options(s) & SSL_OP_NO_QUERY_MTU)) 444205128Ssimon { 445276861Sjkim mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL); 446276861Sjkim if(mtu < s->d1->mtu) 447276861Sjkim s->d1->mtu = mtu; 448205128Ssimon } 449205128Ssimon 450237657Sjkim if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) 451205128Ssimon { 452205128Ssimon /* fail the connection, enough alerts have been sent */ 453237657Sjkim SSLerr(SSL_F_DTLS1_CHECK_TIMEOUT_NUM,SSL_R_READ_TIMEOUT_EXPIRED); 454237657Sjkim return -1; 455237657Sjkim } 456237657Sjkim 457237657Sjkim return 0; 458237657Sjkim } 459237657Sjkim 460237657Sjkimint dtls1_handle_timeout(SSL *s) 461237657Sjkim { 462237657Sjkim /* if no timer is expired, don't do anything */ 463237657Sjkim if (!dtls1_is_timer_expired(s)) 464237657Sjkim { 465205128Ssimon return 0; 466205128Ssimon } 467205128Ssimon 468237657Sjkim dtls1_double_timeout(s); 469237657Sjkim 470237657Sjkim if (dtls1_check_timeout_num(s) < 0) 471237657Sjkim return -1; 472237657Sjkim 473237657Sjkim s->d1->timeout.read_timeouts++; 474237657Sjkim if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) 475205128Ssimon { 476237657Sjkim s->d1->timeout.read_timeouts = 1; 477205128Ssimon } 478205128Ssimon 479238405Sjkim#ifndef OPENSSL_NO_HEARTBEATS 480238405Sjkim if (s->tlsext_hb_pending) 481238405Sjkim { 482238405Sjkim s->tlsext_hb_pending = 0; 483238405Sjkim return dtls1_heartbeat(s); 484238405Sjkim } 485238405Sjkim#endif 486238405Sjkim 487205128Ssimon dtls1_start_timer(s); 488205128Ssimon return dtls1_retransmit_buffered_messages(s); 489205128Ssimon } 490205128Ssimon 491205128Ssimonstatic void get_current_time(struct timeval *t) 492205128Ssimon{ 493205128Ssimon#ifdef OPENSSL_SYS_WIN32 494205128Ssimon struct _timeb tb; 495205128Ssimon _ftime(&tb); 496205128Ssimon t->tv_sec = (long)tb.time; 497205128Ssimon t->tv_usec = (long)tb.millitm * 1000; 498205128Ssimon#elif defined(OPENSSL_SYS_VMS) 499205128Ssimon struct timeb tb; 500205128Ssimon ftime(&tb); 501205128Ssimon t->tv_sec = (long)tb.time; 502205128Ssimon t->tv_usec = (long)tb.millitm * 1000; 503205128Ssimon#else 504205128Ssimon gettimeofday(t, NULL); 505205128Ssimon#endif 506205128Ssimon} 507205128Ssimon 508205128Ssimonint dtls1_listen(SSL *s, struct sockaddr *client) 509205128Ssimon { 510205128Ssimon int ret; 511205128Ssimon 512205128Ssimon SSL_set_options(s, SSL_OP_COOKIE_EXCHANGE); 513205128Ssimon s->d1->listen = 1; 514205128Ssimon 515205128Ssimon ret = SSL_accept(s); 516205128Ssimon if (ret <= 0) return ret; 517205128Ssimon 518205128Ssimon (void) BIO_dgram_get_peer(SSL_get_rbio(s), client); 519205128Ssimon return 1; 520205128Ssimon } 521