Submitted by: Robin Seggelmann <seggelmann@fh-muenster.de>

Fix DTLS timeout handling.
This commit is contained in:
Dr. Stephen Henson 2012-03-09 15:52:09 +00:00
parent 18ea747ce4
commit ad3d95222d
3 changed files with 30 additions and 26 deletions

View File

@ -381,6 +381,7 @@ void dtls1_double_timeout(SSL *s)
void dtls1_stop_timer(SSL *s) void dtls1_stop_timer(SSL *s)
{ {
/* Reset everything */ /* Reset everything */
memset(&(s->d1->timeout), 0, sizeof(struct dtls1_timeout_st));
memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); memset(&(s->d1->next_timeout), 0, sizeof(struct timeval));
s->d1->timeout_duration = 1; s->d1->timeout_duration = 1;
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout)); BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout));
@ -388,10 +389,28 @@ void dtls1_stop_timer(SSL *s)
dtls1_clear_record_buffer(s); dtls1_clear_record_buffer(s);
} }
int dtls1_check_timeout_num(SSL *s)
{
s->d1->timeout.num_alerts++;
/* Reduce MTU after 2 unsuccessful retransmissions */
if (s->d1->timeout.num_alerts > 2)
{
s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);
}
if (s->d1->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
{
/* fail the connection, enough alerts have been sent */
SSLerr(SSL_F_DTLS1_HANDLE_TIMEOUT,SSL_R_READ_TIMEOUT_EXPIRED);
return -1;
}
return 0;
}
int dtls1_handle_timeout(SSL *s) int dtls1_handle_timeout(SSL *s)
{ {
DTLS1_STATE *state;
/* if no timer is expired, don't do anything */ /* if no timer is expired, don't do anything */
if (!dtls1_is_timer_expired(s)) if (!dtls1_is_timer_expired(s))
{ {
@ -399,24 +418,14 @@ int dtls1_handle_timeout(SSL *s)
} }
dtls1_double_timeout(s); dtls1_double_timeout(s);
state = s->d1;
state->timeout.num_alerts++; if (dtls1_check_timeout_num(s) < 0)
if ( state->timeout.num_alerts > DTLS1_TMO_ALERT_COUNT)
{
/* fail the connection, enough alerts have been sent */
SSLerr(SSL_F_DTLS1_HANDLE_TIMEOUT,SSL_R_READ_TIMEOUT_EXPIRED);
return -1; return -1;
}
state->timeout.read_timeouts++; s->d1->timeout.read_timeouts++;
if ( state->timeout.read_timeouts > DTLS1_TMO_READ_COUNT) if (s->d1->timeout.read_timeouts > DTLS1_TMO_READ_COUNT)
{ {
state->timeout.read_timeouts = 1; s->d1->timeout.read_timeouts = 1;
}
if (state->timeout_duration > 2)
{
s->d1->mtu = BIO_ctrl(SSL_get_wbio(s), BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL);
} }
dtls1_start_timer(s); dtls1_start_timer(s);

View File

@ -179,7 +179,6 @@ static int dtls1_record_needs_buffering(SSL *s, SSL3_RECORD *rr,
static int dtls1_buffer_record(SSL *s, record_pqueue *q, static int dtls1_buffer_record(SSL *s, record_pqueue *q,
unsigned char *priority); unsigned char *priority);
static int dtls1_process_record(SSL *s); static int dtls1_process_record(SSL *s);
static void dtls1_clear_timeouts(SSL *s);
/* copy buffered record into SSL structure */ /* copy buffered record into SSL structure */
static int static int
@ -682,7 +681,6 @@ again:
goto again; /* get another record */ goto again; /* get another record */
} }
dtls1_clear_timeouts(s); /* done waiting */
return(1); return(1);
} }
@ -1152,6 +1150,9 @@ start:
*/ */
if (msg_hdr.type == SSL3_MT_FINISHED) if (msg_hdr.type == SSL3_MT_FINISHED)
{ {
if (dtls1_check_timeout_num(s) < 0)
return -1;
dtls1_retransmit_buffered_messages(s); dtls1_retransmit_buffered_messages(s);
rr->length = 0; rr->length = 0;
goto start; goto start;
@ -1765,10 +1766,3 @@ dtls1_reset_seq_numbers(SSL *s, int rw)
memset(seq, 0x00, seq_bytes); memset(seq, 0x00, seq_bytes);
} }
static void
dtls1_clear_timeouts(SSL *s)
{
memset(&(s->d1->timeout), 0x00, sizeof(struct dtls1_timeout_st));
}

View File

@ -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); void dtls1_reset_seq_numbers(SSL *s, int rw);
long dtls1_default_timeout(void); long dtls1_default_timeout(void);
struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft); struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft);
int dtls1_check_timeout_num(SSL *s);
int dtls1_handle_timeout(SSL *s); int dtls1_handle_timeout(SSL *s);
const SSL_CIPHER *dtls1_get_cipher(unsigned int u); const SSL_CIPHER *dtls1_get_cipher(unsigned int u);
void dtls1_start_timer(SSL *s); void dtls1_start_timer(SSL *s);