summaryrefslogtreecommitdiffstats
path: root/ssl
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2009-08-12 13:19:54 +0000
committerDr. Stephen Henson <steve@openssl.org>2009-08-12 13:19:54 +0000
commitb972fbaa8f96d3774d3543d96e232ae50131bb9e (patch)
treeadec97af54b1e795805c006496dcd4b3c92131ef /ssl
parent77c7f17a5ecac2280b826b12b9dab0334317d34a (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.c29
-rw-r--r--ssl/d1_lib.c53
-rw-r--r--ssl/d1_pkt.c7
-rw-r--r--ssl/ssl.h8
-rw-r--r--ssl/ssl_locl.h3
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))
diff --git a/ssl/ssl.h b/ssl/ssl.h
index 7ed8226b24..117071c30a 100644
--- a/ssl/ssl.h
+++ b/ssl/ssl.h
@@ -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);