diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2009-08-12 13:19:54 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2009-08-12 13:19:54 +0000 |
commit | b972fbaa8f96d3774d3543d96e232ae50131bb9e (patch) | |
tree | adec97af54b1e795805c006496dcd4b3c92131ef /ssl | |
parent | 77c7f17a5ecac2280b826b12b9dab0334317d34a (diff) |
PR: 1997
Submitted by: Robin Seggelmann <seggelmann@fh-muenster.de>
Approved by: steve@openssl.org
DTLS timeout handling fix.
Diffstat (limited to 'ssl')
-rw-r--r-- | ssl/d1_both.c | 29 | ||||
-rw-r--r-- | ssl/d1_lib.c | 53 | ||||
-rw-r--r-- | ssl/d1_pkt.c | 7 | ||||
-rw-r--r-- | ssl/ssl.h | 8 | ||||
-rw-r--r-- | ssl/ssl_locl.h | 3 |
5 files changed, 69 insertions, 31 deletions
diff --git a/ssl/d1_both.c b/ssl/d1_both.c index d11d6d5888..5bb0a4ff6c 100644 --- a/ssl/d1_both.c +++ b/ssl/d1_both.c @@ -890,9 +890,6 @@ unsigned long dtls1_output_cert_chain(SSL *s, X509 *x) int dtls1_read_failed(SSL *s, int code) { - DTLS1_STATE *state; - int send_alert = 0; - if ( code > 0) { fprintf( stderr, "invalid state reached %s:%d", __FILE__, __LINE__); @@ -912,24 +909,6 @@ int dtls1_read_failed(SSL *s, int code) return code; } - dtls1_double_timeout(s); - state = s->d1; - state->timeout.num_alerts++; - if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) - { - /* fail the connection, enough alerts have been sent */ - SSLerr(SSL_F_DTLS1_READ_FAILED,SSL_R_READ_TIMEOUT_EXPIRED); - return 0; - } - - state->timeout.read_timeouts++; - if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) - { - send_alert = 1; - state->timeout.read_timeouts = 1; - } - - #if 0 /* for now, each alert contains only one record number */ item = pqueue_peek(state->rcvd_records); if ( item ) @@ -940,12 +919,12 @@ int dtls1_read_failed(SSL *s, int code) #endif #if 0 /* no more alert sending, just retransmit the last set of messages */ - if ( send_alert) - ssl3_send_alert(s,SSL3_AL_WARNING, - DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); + if ( state->timeout.read_timeouts >= DTLS1_TMO_READ_COUNT) + ssl3_send_alert(s,SSL3_AL_WARNING, + DTLS1_AD_MISSING_HANDSHAKE_MESSAGE); #endif - return dtls1_retransmit_buffered_messages(s) ; + return dtls1_handle_timeout(s); } int diff --git a/ssl/d1_lib.c b/ssl/d1_lib.c index 6450c1de85..8039740555 100644 --- a/ssl/d1_lib.c +++ b/ssl/d1_lib.c @@ -188,6 +188,29 @@ void dtls1_clear(SSL *s) s->version=DTLS1_VERSION; } +long dtls1_ctrl(SSL *s, int cmd, long larg, void *parg) + { + int ret=0; + + switch (cmd) + { + case DTLS_CTRL_GET_TIMEOUT: + if (dtls1_get_timeout(s, (struct timeval*) parg) != NULL) + { + ret = 1; + } + break; + case DTLS_CTRL_HANDLE_TIMEOUT: + ret = dtls1_handle_timeout(s); + break; + + default: + ret = ssl3_ctrl(s, cmd, larg, parg); + break; + } + return(ret); + } + /* * As it's impossible to use stream ciphers in "datagram" mode, this * simple filter is designed to disengage them in DTLS. Unfortunately @@ -295,6 +318,36 @@ void dtls1_stop_timer(SSL *s) BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout)); } +int dtls1_handle_timeout(SSL *s) + { + DTLS1_STATE *state; + + /* if no timer is expired, don't do anything */ + if (!dtls1_is_timer_expired(s)) + { + return 0; + } + + dtls1_double_timeout(s); + state = s->d1; + state->timeout.num_alerts++; + if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT) + { + /* fail the connection, enough alerts have been sent */ + SSLerr(SSL_F_DTLS1_READ_FAILED,SSL_R_READ_TIMEOUT_EXPIRED); + return 0; + } + + state->timeout.read_timeouts++; + if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) + { + state->timeout.read_timeouts = 1; + } + + dtls1_start_timer(s); + return dtls1_retransmit_buffered_messages(s); + } + static void get_current_time(struct timeval *t) { #ifdef OPENSSL_SYS_WIN32 diff --git a/ssl/d1_pkt.c b/ssl/d1_pkt.c index d9a81140ea..0664636b52 100644 --- a/ssl/d1_pkt.c +++ b/ssl/d1_pkt.c @@ -773,11 +773,8 @@ start: } /* Check for timeout */ - if (dtls1_is_timer_expired(s)) - { - if (dtls1_read_failed(s, -1) > 0) - goto start; - } + if (dtls1_handle_timeout(s) > 0) + goto start; /* get new packet if necessary */ if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY)) @@ -1396,6 +1396,14 @@ DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) #define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72 #endif +#define DTLS_CTRL_GET_TIMEOUT 73 +#define DTLS_CTRL_HANDLE_TIMEOUT 74 + +#define DTLSv1_get_timeout(ssl, arg) \ + SSL_ctrl(ssl,DTLS_CTRL_GET_TIMEOUT,0, (void *)arg) +#define DTLSv1_handle_timeout(ssl) \ + SSL_ctrl(ssl,DTLS_CTRL_HANDLE_TIMEOUT,0, NULL) + #define SSL_session_reused(ssl) \ SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL) #define SSL_num_renegotiations(ssl) \ diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h index 2b362a48ea..74fc972908 100644 --- a/ssl/ssl_locl.h +++ b/ssl/ssl_locl.h @@ -759,7 +759,7 @@ const SSL_METHOD *func_name(void) \ dtls1_read_bytes, \ dtls1_write_app_data_bytes, \ dtls1_dispatch_alert, \ - ssl3_ctrl, \ + dtls1_ctrl, \ ssl3_ctx_ctrl, \ ssl3_get_cipher_by_char, \ ssl3_put_cipher_by_char, \ @@ -943,6 +943,7 @@ void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr); void dtls1_reset_seq_numbers(SSL *s, int rw); long dtls1_default_timeout(void); struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft); +int dtls1_handle_timeout(SSL *s); const SSL_CIPHER *dtls1_get_cipher(unsigned int u); void dtls1_start_timer(SSL *s); void dtls1_stop_timer(SSL *s); |