PR: 1997
Submitted by: Robin Seggelmann <seggelmann@fh-muenster.de> Approved by: steve@openssl.org DTLS timeout handling fix.
This commit is contained in:
parent
e322b5d167
commit
a4bade7aac
@ -411,6 +411,7 @@ int MAIN(int argc, char **argv)
|
|||||||
BIO *sbio;
|
BIO *sbio;
|
||||||
char *inrand=NULL;
|
char *inrand=NULL;
|
||||||
int mbuf_len=0;
|
int mbuf_len=0;
|
||||||
|
struct timeval timeout, *timeoutp;
|
||||||
#ifndef OPENSSL_NO_ENGINE
|
#ifndef OPENSSL_NO_ENGINE
|
||||||
char *engine_id=NULL;
|
char *engine_id=NULL;
|
||||||
char *ssl_client_engine_id=NULL;
|
char *ssl_client_engine_id=NULL;
|
||||||
@ -979,7 +980,6 @@ re_start:
|
|||||||
|
|
||||||
if ( SSL_version(con) == DTLS1_VERSION)
|
if ( SSL_version(con) == DTLS1_VERSION)
|
||||||
{
|
{
|
||||||
struct timeval timeout;
|
|
||||||
|
|
||||||
sbio=BIO_new_dgram(s,BIO_NOCLOSE);
|
sbio=BIO_new_dgram(s,BIO_NOCLOSE);
|
||||||
if (getsockname(s, &peer, (void *)&peerlen) < 0)
|
if (getsockname(s, &peer, (void *)&peerlen) < 0)
|
||||||
@ -1196,6 +1196,12 @@ SSL_set_tlsext_status_ids(con, ids);
|
|||||||
FD_ZERO(&readfds);
|
FD_ZERO(&readfds);
|
||||||
FD_ZERO(&writefds);
|
FD_ZERO(&writefds);
|
||||||
|
|
||||||
|
if ((SSL_version(con) == DTLS1_VERSION) &&
|
||||||
|
DTLSv1_get_timeout(con, &timeout))
|
||||||
|
timeoutp = &timeout;
|
||||||
|
else
|
||||||
|
timeoutp = NULL;
|
||||||
|
|
||||||
if (SSL_in_init(con) && !SSL_total_renegotiations(con))
|
if (SSL_in_init(con) && !SSL_total_renegotiations(con))
|
||||||
{
|
{
|
||||||
in_init=1;
|
in_init=1;
|
||||||
@ -1300,7 +1306,7 @@ SSL_set_tlsext_status_ids(con, ids);
|
|||||||
if(!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) || !read_tty) ) continue;
|
if(!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) || !read_tty) ) continue;
|
||||||
#endif
|
#endif
|
||||||
} else i=select(width,(void *)&readfds,(void *)&writefds,
|
} else i=select(width,(void *)&readfds,(void *)&writefds,
|
||||||
NULL,NULL);
|
NULL,timeoutp);
|
||||||
}
|
}
|
||||||
#elif defined(OPENSSL_SYS_NETWARE)
|
#elif defined(OPENSSL_SYS_NETWARE)
|
||||||
if(!write_tty) {
|
if(!write_tty) {
|
||||||
@ -1310,7 +1316,7 @@ SSL_set_tlsext_status_ids(con, ids);
|
|||||||
i=select(width,(void *)&readfds,(void *)&writefds,
|
i=select(width,(void *)&readfds,(void *)&writefds,
|
||||||
NULL,&tv);
|
NULL,&tv);
|
||||||
} else i=select(width,(void *)&readfds,(void *)&writefds,
|
} else i=select(width,(void *)&readfds,(void *)&writefds,
|
||||||
NULL,NULL);
|
NULL,timeoutp);
|
||||||
}
|
}
|
||||||
#elif defined(OPENSSL_SYS_BEOS_R5)
|
#elif defined(OPENSSL_SYS_BEOS_R5)
|
||||||
/* Under BeOS-R5 the situation is similar to DOS */
|
/* Under BeOS-R5 the situation is similar to DOS */
|
||||||
@ -1328,12 +1334,12 @@ SSL_set_tlsext_status_ids(con, ids);
|
|||||||
if (!i && (stdin_set != 1 || !read_tty))
|
if (!i && (stdin_set != 1 || !read_tty))
|
||||||
continue;
|
continue;
|
||||||
} else i=select(width,(void *)&readfds,(void *)&writefds,
|
} else i=select(width,(void *)&readfds,(void *)&writefds,
|
||||||
NULL,NULL);
|
NULL,timeoutp);
|
||||||
}
|
}
|
||||||
(void)fcntl(fileno(stdin), F_SETFL, 0);
|
(void)fcntl(fileno(stdin), F_SETFL, 0);
|
||||||
#else
|
#else
|
||||||
i=select(width,(void *)&readfds,(void *)&writefds,
|
i=select(width,(void *)&readfds,(void *)&writefds,
|
||||||
NULL,NULL);
|
NULL,timeoutp);
|
||||||
#endif
|
#endif
|
||||||
if ( i < 0)
|
if ( i < 0)
|
||||||
{
|
{
|
||||||
@ -1344,6 +1350,11 @@ SSL_set_tlsext_status_ids(con, ids);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0)
|
||||||
|
{
|
||||||
|
BIO_printf(bio_err,"TIMEOUT occured\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds))
|
if (!ssl_pending && FD_ISSET(SSL_get_fd(con),&writefds))
|
||||||
{
|
{
|
||||||
k=SSL_write(con,&(cbuf[cbuf_off]),
|
k=SSL_write(con,&(cbuf[cbuf_off]),
|
||||||
|
@ -1750,6 +1750,7 @@ static int sv_body(char *hostname, int s, unsigned char *context)
|
|||||||
unsigned long l;
|
unsigned long l;
|
||||||
SSL *con=NULL;
|
SSL *con=NULL;
|
||||||
BIO *sbio;
|
BIO *sbio;
|
||||||
|
struct timeval timeout, *timeoutp;
|
||||||
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
|
#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
#endif
|
#endif
|
||||||
@ -1808,7 +1809,6 @@ static int sv_body(char *hostname, int s, unsigned char *context)
|
|||||||
|
|
||||||
if (SSL_version(con) == DTLS1_VERSION)
|
if (SSL_version(con) == DTLS1_VERSION)
|
||||||
{
|
{
|
||||||
struct timeval timeout;
|
|
||||||
|
|
||||||
sbio=BIO_new_dgram(s,BIO_NOCLOSE);
|
sbio=BIO_new_dgram(s,BIO_NOCLOSE);
|
||||||
|
|
||||||
@ -1919,7 +1919,19 @@ static int sv_body(char *hostname, int s, unsigned char *context)
|
|||||||
read_from_terminal = 1;
|
read_from_terminal = 1;
|
||||||
(void)fcntl(fileno(stdin), F_SETFL, 0);
|
(void)fcntl(fileno(stdin), F_SETFL, 0);
|
||||||
#else
|
#else
|
||||||
i=select(width,(void *)&readfds,NULL,NULL,NULL);
|
if ((SSL_version(con) == DTLS1_VERSION) &&
|
||||||
|
DTLSv1_get_timeout(con, &timeout))
|
||||||
|
timeoutp = &timeout;
|
||||||
|
else
|
||||||
|
timeoutp = NULL;
|
||||||
|
|
||||||
|
i=select(width,(void *)&readfds,NULL,NULL,timeoutp);
|
||||||
|
|
||||||
|
if ((SSL_version(con) == DTLS1_VERSION) && DTLSv1_handle_timeout(con) > 0)
|
||||||
|
{
|
||||||
|
BIO_printf(bio_err,"TIMEOUT occured\n");
|
||||||
|
}
|
||||||
|
|
||||||
if (i <= 0) continue;
|
if (i <= 0) continue;
|
||||||
if (FD_ISSET(fileno(stdin),&readfds))
|
if (FD_ISSET(fileno(stdin),&readfds))
|
||||||
read_from_terminal = 1;
|
read_from_terminal = 1;
|
||||||
|
@ -890,9 +890,6 @@ unsigned long dtls1_output_cert_chain(SSL *s, X509 *x)
|
|||||||
|
|
||||||
int dtls1_read_failed(SSL *s, int code)
|
int dtls1_read_failed(SSL *s, int code)
|
||||||
{
|
{
|
||||||
DTLS1_STATE *state;
|
|
||||||
int send_alert = 0;
|
|
||||||
|
|
||||||
if ( code > 0)
|
if ( code > 0)
|
||||||
{
|
{
|
||||||
fprintf( stderr, "invalid state reached %s:%d", __FILE__, __LINE__);
|
fprintf( stderr, "invalid state reached %s:%d", __FILE__, __LINE__);
|
||||||
@ -912,24 +909,6 @@ int dtls1_read_failed(SSL *s, int code)
|
|||||||
return 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 */
|
#if 0 /* for now, each alert contains only one record number */
|
||||||
item = pqueue_peek(state->rcvd_records);
|
item = pqueue_peek(state->rcvd_records);
|
||||||
if ( item )
|
if ( item )
|
||||||
@ -940,12 +919,12 @@ int dtls1_read_failed(SSL *s, int code)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0 /* no more alert sending, just retransmit the last set of messages */
|
#if 0 /* no more alert sending, just retransmit the last set of messages */
|
||||||
if ( send_alert)
|
if ( state->timeout.read_timeouts >= DTLS1_TMO_READ_COUNT)
|
||||||
ssl3_send_alert(s,SSL3_AL_WARNING,
|
ssl3_send_alert(s,SSL3_AL_WARNING,
|
||||||
DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
|
DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return dtls1_retransmit_buffered_messages(s) ;
|
return dtls1_handle_timeout(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
53
ssl/d1_lib.c
53
ssl/d1_lib.c
@ -188,6 +188,29 @@ void dtls1_clear(SSL *s)
|
|||||||
s->version=DTLS1_VERSION;
|
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
|
* As it's impossible to use stream ciphers in "datagram" mode, this
|
||||||
* simple filter is designed to disengage them in DTLS. Unfortunately
|
* 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));
|
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)
|
static void get_current_time(struct timeval *t)
|
||||||
{
|
{
|
||||||
#ifdef OPENSSL_SYS_WIN32
|
#ifdef OPENSSL_SYS_WIN32
|
||||||
|
@ -773,11 +773,8 @@ start:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Check for timeout */
|
/* Check for timeout */
|
||||||
if (dtls1_is_timer_expired(s))
|
if (dtls1_handle_timeout(s) > 0)
|
||||||
{
|
goto start;
|
||||||
if (dtls1_read_failed(s, -1) > 0)
|
|
||||||
goto start;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get new packet if necessary */
|
/* get new packet if necessary */
|
||||||
if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY))
|
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
|
#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB 72
|
||||||
#endif
|
#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) \
|
#define SSL_session_reused(ssl) \
|
||||||
SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL)
|
SSL_ctrl((ssl),SSL_CTRL_GET_SESSION_REUSED,0,NULL)
|
||||||
#define SSL_num_renegotiations(ssl) \
|
#define SSL_num_renegotiations(ssl) \
|
||||||
|
@ -759,7 +759,7 @@ const SSL_METHOD *func_name(void) \
|
|||||||
dtls1_read_bytes, \
|
dtls1_read_bytes, \
|
||||||
dtls1_write_app_data_bytes, \
|
dtls1_write_app_data_bytes, \
|
||||||
dtls1_dispatch_alert, \
|
dtls1_dispatch_alert, \
|
||||||
ssl3_ctrl, \
|
dtls1_ctrl, \
|
||||||
ssl3_ctx_ctrl, \
|
ssl3_ctx_ctrl, \
|
||||||
ssl3_get_cipher_by_char, \
|
ssl3_get_cipher_by_char, \
|
||||||
ssl3_put_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);
|
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_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);
|
||||||
void dtls1_stop_timer(SSL *s);
|
void dtls1_stop_timer(SSL *s);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user