PR: 1829
Submitted by: Robin Seggelmann <seggelmann@fh-muenster.de> Approved by: steve@openssl.org DTLS timer bug fix from 1.0.0-stable with fixes.
This commit is contained in:
parent
1f9a128519
commit
b00c36e366
@ -158,6 +158,7 @@ extern "C" {
|
|||||||
|
|
||||||
#define BIO_CTRL_DGRAM_SET_PEER 44 /* Destination for the data */
|
#define BIO_CTRL_DGRAM_SET_PEER 44 /* Destination for the data */
|
||||||
|
|
||||||
|
#define BIO_CTRL_DGRAM_SET_TIMEOUT 45
|
||||||
|
|
||||||
/* modifiers */
|
/* modifiers */
|
||||||
#define BIO_FP_READ 0x02
|
#define BIO_FP_READ 0x02
|
||||||
|
@ -66,6 +66,10 @@
|
|||||||
|
|
||||||
#include <openssl/bio.h>
|
#include <openssl/bio.h>
|
||||||
|
|
||||||
|
#ifdef OPENSSL_SYS_WIN32
|
||||||
|
#include <sys/timeb.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#define IP_MTU 14 /* linux is lame */
|
#define IP_MTU 14 /* linux is lame */
|
||||||
|
|
||||||
#ifdef WATT32
|
#ifdef WATT32
|
||||||
@ -104,6 +108,8 @@ typedef struct bio_dgram_data_st
|
|||||||
unsigned int connected;
|
unsigned int connected;
|
||||||
unsigned int _errno;
|
unsigned int _errno;
|
||||||
unsigned int mtu;
|
unsigned int mtu;
|
||||||
|
struct timeval hstimeoutdiff;
|
||||||
|
struct timeval hstimeout;
|
||||||
} bio_dgram_data;
|
} bio_dgram_data;
|
||||||
|
|
||||||
BIO_METHOD *BIO_s_datagram(void)
|
BIO_METHOD *BIO_s_datagram(void)
|
||||||
@ -196,6 +202,30 @@ static int dgram_read(BIO *b, char *out, int outl)
|
|||||||
BIO_set_retry_read(b);
|
BIO_set_retry_read(b);
|
||||||
data->_errno = get_last_socket_error();
|
data->_errno = get_last_socket_error();
|
||||||
}
|
}
|
||||||
|
memset(&(data->hstimeout), 0, sizeof(struct timeval));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (data->hstimeout.tv_sec > 0 || data->hstimeout.tv_usec > 0)
|
||||||
|
{
|
||||||
|
struct timeval curtime;
|
||||||
|
#ifdef OPENSSL_SYS_WIN32
|
||||||
|
struct _timeb tb;
|
||||||
|
_ftime(&tb);
|
||||||
|
curtime.tv_sec = (long)tb.time;
|
||||||
|
curtime.tv_usec = (long)tb.millitm * 1000;
|
||||||
|
#else
|
||||||
|
gettimeofday(&curtime, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (curtime.tv_sec >= data->hstimeout.tv_sec &&
|
||||||
|
curtime.tv_usec >= data->hstimeout.tv_usec)
|
||||||
|
{
|
||||||
|
data->_errno = EAGAIN;
|
||||||
|
ret = -1;
|
||||||
|
memset(&(data->hstimeout), 0, sizeof(struct timeval));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return(ret);
|
return(ret);
|
||||||
@ -345,6 +375,30 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
|
|||||||
|
|
||||||
memcpy(&(data->peer), to, sizeof(struct sockaddr));
|
memcpy(&(data->peer), to, sizeof(struct sockaddr));
|
||||||
break;
|
break;
|
||||||
|
case BIO_CTRL_DGRAM_SET_TIMEOUT:
|
||||||
|
if (num > 0)
|
||||||
|
{
|
||||||
|
#ifdef OPENSSL_SYS_WIN32
|
||||||
|
struct _timeb tb;
|
||||||
|
_ftime(&tb);
|
||||||
|
data->hstimeout.tv_sec = (long)tb.time;
|
||||||
|
data->hstimeout.tv_usec = (long)tb.millitm * 1000;
|
||||||
|
#else
|
||||||
|
gettimeofday(&(data->hstimeout), NULL);
|
||||||
|
#endif
|
||||||
|
data->hstimeout.tv_sec += data->hstimeoutdiff.tv_sec;
|
||||||
|
data->hstimeout.tv_usec += data->hstimeoutdiff.tv_usec;
|
||||||
|
if (data->hstimeout.tv_usec >= 1000000)
|
||||||
|
{
|
||||||
|
data->hstimeout.tv_sec++;
|
||||||
|
data->hstimeout.tv_usec -= 1000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memset(&(data->hstimeout), 0, sizeof(struct timeval));
|
||||||
|
}
|
||||||
|
break;
|
||||||
#if defined(SO_RCVTIMEO)
|
#if defined(SO_RCVTIMEO)
|
||||||
case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
|
case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT:
|
||||||
#ifdef OPENSSL_SYS_WINDOWS
|
#ifdef OPENSSL_SYS_WINDOWS
|
||||||
@ -360,6 +414,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr)
|
|||||||
sizeof(struct timeval)) < 0)
|
sizeof(struct timeval)) < 0)
|
||||||
{ perror("setsockopt"); ret = -1; }
|
{ perror("setsockopt"); ret = -1; }
|
||||||
#endif
|
#endif
|
||||||
|
memcpy(&(data->hstimeoutdiff), ptr, sizeof(struct timeval));
|
||||||
break;
|
break;
|
||||||
case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
|
case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT:
|
||||||
#ifdef OPENSSL_SYS_WINDOWS
|
#ifdef OPENSSL_SYS_WINDOWS
|
||||||
|
@ -229,6 +229,7 @@ int dtls1_connect(SSL *s)
|
|||||||
/* every DTLS ClientHello resets Finished MAC */
|
/* every DTLS ClientHello resets Finished MAC */
|
||||||
ssl3_init_finished_mac(s);
|
ssl3_init_finished_mac(s);
|
||||||
|
|
||||||
|
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL);
|
||||||
ret=dtls1_client_hello(s);
|
ret=dtls1_client_hello(s);
|
||||||
if (ret <= 0) goto end;
|
if (ret <= 0) goto end;
|
||||||
|
|
||||||
@ -254,6 +255,7 @@ int dtls1_connect(SSL *s)
|
|||||||
if (ret <= 0) goto end;
|
if (ret <= 0) goto end;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL);
|
||||||
if (s->hit)
|
if (s->hit)
|
||||||
s->state=SSL3_ST_CR_FINISHED_A;
|
s->state=SSL3_ST_CR_FINISHED_A;
|
||||||
else
|
else
|
||||||
@ -268,6 +270,7 @@ int dtls1_connect(SSL *s)
|
|||||||
ret = dtls1_get_hello_verify(s);
|
ret = dtls1_get_hello_verify(s);
|
||||||
if ( ret <= 0)
|
if ( ret <= 0)
|
||||||
goto end;
|
goto end;
|
||||||
|
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL);
|
||||||
if ( s->d1->send_cookie) /* start again, with a cookie */
|
if ( s->d1->send_cookie) /* start again, with a cookie */
|
||||||
s->state=SSL3_ST_CW_CLNT_HELLO_A;
|
s->state=SSL3_ST_CW_CLNT_HELLO_A;
|
||||||
else
|
else
|
||||||
@ -329,6 +332,7 @@ int dtls1_connect(SSL *s)
|
|||||||
case SSL3_ST_CW_CERT_B:
|
case SSL3_ST_CW_CERT_B:
|
||||||
case SSL3_ST_CW_CERT_C:
|
case SSL3_ST_CW_CERT_C:
|
||||||
case SSL3_ST_CW_CERT_D:
|
case SSL3_ST_CW_CERT_D:
|
||||||
|
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL);
|
||||||
ret=dtls1_send_client_certificate(s);
|
ret=dtls1_send_client_certificate(s);
|
||||||
if (ret <= 0) goto end;
|
if (ret <= 0) goto end;
|
||||||
s->state=SSL3_ST_CW_KEY_EXCH_A;
|
s->state=SSL3_ST_CW_KEY_EXCH_A;
|
||||||
@ -337,6 +341,7 @@ int dtls1_connect(SSL *s)
|
|||||||
|
|
||||||
case SSL3_ST_CW_KEY_EXCH_A:
|
case SSL3_ST_CW_KEY_EXCH_A:
|
||||||
case SSL3_ST_CW_KEY_EXCH_B:
|
case SSL3_ST_CW_KEY_EXCH_B:
|
||||||
|
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL);
|
||||||
ret=dtls1_send_client_key_exchange(s);
|
ret=dtls1_send_client_key_exchange(s);
|
||||||
if (ret <= 0) goto end;
|
if (ret <= 0) goto end;
|
||||||
l=s->s3->tmp.new_cipher->algorithms;
|
l=s->s3->tmp.new_cipher->algorithms;
|
||||||
@ -359,6 +364,7 @@ int dtls1_connect(SSL *s)
|
|||||||
|
|
||||||
case SSL3_ST_CW_CERT_VRFY_A:
|
case SSL3_ST_CW_CERT_VRFY_A:
|
||||||
case SSL3_ST_CW_CERT_VRFY_B:
|
case SSL3_ST_CW_CERT_VRFY_B:
|
||||||
|
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL);
|
||||||
ret=dtls1_send_client_verify(s);
|
ret=dtls1_send_client_verify(s);
|
||||||
if (ret <= 0) goto end;
|
if (ret <= 0) goto end;
|
||||||
s->state=SSL3_ST_CW_CHANGE_A;
|
s->state=SSL3_ST_CW_CHANGE_A;
|
||||||
@ -368,6 +374,7 @@ int dtls1_connect(SSL *s)
|
|||||||
|
|
||||||
case SSL3_ST_CW_CHANGE_A:
|
case SSL3_ST_CW_CHANGE_A:
|
||||||
case SSL3_ST_CW_CHANGE_B:
|
case SSL3_ST_CW_CHANGE_B:
|
||||||
|
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL);
|
||||||
ret=dtls1_send_change_cipher_spec(s,
|
ret=dtls1_send_change_cipher_spec(s,
|
||||||
SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
|
SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B);
|
||||||
if (ret <= 0) goto end;
|
if (ret <= 0) goto end;
|
||||||
@ -402,6 +409,7 @@ int dtls1_connect(SSL *s)
|
|||||||
|
|
||||||
case SSL3_ST_CW_FINISHED_A:
|
case SSL3_ST_CW_FINISHED_A:
|
||||||
case SSL3_ST_CW_FINISHED_B:
|
case SSL3_ST_CW_FINISHED_B:
|
||||||
|
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL);
|
||||||
ret=dtls1_send_finished(s,
|
ret=dtls1_send_finished(s,
|
||||||
SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B,
|
SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B,
|
||||||
s->method->ssl3_enc->client_finished_label,
|
s->method->ssl3_enc->client_finished_label,
|
||||||
@ -435,6 +443,7 @@ int dtls1_connect(SSL *s)
|
|||||||
ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
|
ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A,
|
||||||
SSL3_ST_CR_FINISHED_B);
|
SSL3_ST_CR_FINISHED_B);
|
||||||
if (ret <= 0) goto end;
|
if (ret <= 0) goto end;
|
||||||
|
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL);
|
||||||
|
|
||||||
if (s->hit)
|
if (s->hit)
|
||||||
s->state=SSL3_ST_CW_CHANGE_A;
|
s->state=SSL3_ST_CW_CHANGE_A;
|
||||||
|
@ -247,6 +247,7 @@ int dtls1_accept(SSL *s)
|
|||||||
case SSL3_ST_SW_HELLO_REQ_B:
|
case SSL3_ST_SW_HELLO_REQ_B:
|
||||||
|
|
||||||
s->shutdown=0;
|
s->shutdown=0;
|
||||||
|
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL);
|
||||||
ret=dtls1_send_hello_request(s);
|
ret=dtls1_send_hello_request(s);
|
||||||
if (ret <= 0) goto end;
|
if (ret <= 0) goto end;
|
||||||
s->s3->tmp.next_state=SSL3_ST_SW_HELLO_REQ_C;
|
s->s3->tmp.next_state=SSL3_ST_SW_HELLO_REQ_C;
|
||||||
@ -267,6 +268,7 @@ int dtls1_accept(SSL *s)
|
|||||||
s->shutdown=0;
|
s->shutdown=0;
|
||||||
ret=ssl3_get_client_hello(s);
|
ret=ssl3_get_client_hello(s);
|
||||||
if (ret <= 0) goto end;
|
if (ret <= 0) goto end;
|
||||||
|
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL);
|
||||||
s->new_session = 2;
|
s->new_session = 2;
|
||||||
|
|
||||||
if ( s->d1->send_cookie)
|
if ( s->d1->send_cookie)
|
||||||
@ -280,6 +282,7 @@ int dtls1_accept(SSL *s)
|
|||||||
case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A:
|
case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_A:
|
||||||
case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B:
|
case DTLS1_ST_SW_HELLO_VERIFY_REQUEST_B:
|
||||||
|
|
||||||
|
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL);
|
||||||
ret = dtls1_send_hello_verify_request(s);
|
ret = dtls1_send_hello_verify_request(s);
|
||||||
if ( ret <= 0) goto end;
|
if ( ret <= 0) goto end;
|
||||||
s->d1->send_cookie = 0;
|
s->d1->send_cookie = 0;
|
||||||
@ -293,6 +296,7 @@ int dtls1_accept(SSL *s)
|
|||||||
|
|
||||||
case SSL3_ST_SW_SRVR_HELLO_A:
|
case SSL3_ST_SW_SRVR_HELLO_A:
|
||||||
case SSL3_ST_SW_SRVR_HELLO_B:
|
case SSL3_ST_SW_SRVR_HELLO_B:
|
||||||
|
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL);
|
||||||
ret=dtls1_send_server_hello(s);
|
ret=dtls1_send_server_hello(s);
|
||||||
if (ret <= 0) goto end;
|
if (ret <= 0) goto end;
|
||||||
|
|
||||||
@ -308,6 +312,7 @@ int dtls1_accept(SSL *s)
|
|||||||
/* Check if it is anon DH */
|
/* Check if it is anon DH */
|
||||||
if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
|
if (!(s->s3->tmp.new_cipher->algorithms & SSL_aNULL))
|
||||||
{
|
{
|
||||||
|
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL);
|
||||||
ret=dtls1_send_server_certificate(s);
|
ret=dtls1_send_server_certificate(s);
|
||||||
if (ret <= 0) goto end;
|
if (ret <= 0) goto end;
|
||||||
}
|
}
|
||||||
@ -349,6 +354,7 @@ int dtls1_accept(SSL *s)
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL);
|
||||||
ret=dtls1_send_server_key_exchange(s);
|
ret=dtls1_send_server_key_exchange(s);
|
||||||
if (ret <= 0) goto end;
|
if (ret <= 0) goto end;
|
||||||
}
|
}
|
||||||
@ -385,6 +391,7 @@ int dtls1_accept(SSL *s)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
s->s3->tmp.cert_request=1;
|
s->s3->tmp.cert_request=1;
|
||||||
|
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL);
|
||||||
ret=dtls1_send_certificate_request(s);
|
ret=dtls1_send_certificate_request(s);
|
||||||
if (ret <= 0) goto end;
|
if (ret <= 0) goto end;
|
||||||
#ifndef NETSCAPE_HANG_BUG
|
#ifndef NETSCAPE_HANG_BUG
|
||||||
@ -399,6 +406,7 @@ int dtls1_accept(SSL *s)
|
|||||||
|
|
||||||
case SSL3_ST_SW_SRVR_DONE_A:
|
case SSL3_ST_SW_SRVR_DONE_A:
|
||||||
case SSL3_ST_SW_SRVR_DONE_B:
|
case SSL3_ST_SW_SRVR_DONE_B:
|
||||||
|
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL);
|
||||||
ret=dtls1_send_server_done(s);
|
ret=dtls1_send_server_done(s);
|
||||||
if (ret <= 0) goto end;
|
if (ret <= 0) goto end;
|
||||||
s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
|
s->s3->tmp.next_state=SSL3_ST_SR_CERT_A;
|
||||||
@ -426,6 +434,7 @@ int dtls1_accept(SSL *s)
|
|||||||
ret = ssl3_check_client_hello(s);
|
ret = ssl3_check_client_hello(s);
|
||||||
if (ret <= 0)
|
if (ret <= 0)
|
||||||
goto end;
|
goto end;
|
||||||
|
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL);
|
||||||
if (ret == 2)
|
if (ret == 2)
|
||||||
s->state = SSL3_ST_SR_CLNT_HELLO_C;
|
s->state = SSL3_ST_SR_CLNT_HELLO_C;
|
||||||
else {
|
else {
|
||||||
@ -433,6 +442,7 @@ int dtls1_accept(SSL *s)
|
|||||||
* have not asked for it :-) */
|
* have not asked for it :-) */
|
||||||
ret=ssl3_get_client_certificate(s);
|
ret=ssl3_get_client_certificate(s);
|
||||||
if (ret <= 0) goto end;
|
if (ret <= 0) goto end;
|
||||||
|
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL);
|
||||||
s->init_num=0;
|
s->init_num=0;
|
||||||
s->state=SSL3_ST_SR_KEY_EXCH_A;
|
s->state=SSL3_ST_SR_KEY_EXCH_A;
|
||||||
}
|
}
|
||||||
@ -442,6 +452,7 @@ int dtls1_accept(SSL *s)
|
|||||||
case SSL3_ST_SR_KEY_EXCH_B:
|
case SSL3_ST_SR_KEY_EXCH_B:
|
||||||
ret=ssl3_get_client_key_exchange(s);
|
ret=ssl3_get_client_key_exchange(s);
|
||||||
if (ret <= 0) goto end;
|
if (ret <= 0) goto end;
|
||||||
|
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL);
|
||||||
s->state=SSL3_ST_SR_CERT_VRFY_A;
|
s->state=SSL3_ST_SR_CERT_VRFY_A;
|
||||||
s->init_num=0;
|
s->init_num=0;
|
||||||
|
|
||||||
@ -462,6 +473,7 @@ int dtls1_accept(SSL *s)
|
|||||||
/* we should decide if we expected this one */
|
/* we should decide if we expected this one */
|
||||||
ret=ssl3_get_cert_verify(s);
|
ret=ssl3_get_cert_verify(s);
|
||||||
if (ret <= 0) goto end;
|
if (ret <= 0) goto end;
|
||||||
|
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL);
|
||||||
|
|
||||||
s->state=SSL3_ST_SR_FINISHED_A;
|
s->state=SSL3_ST_SR_FINISHED_A;
|
||||||
s->init_num=0;
|
s->init_num=0;
|
||||||
@ -472,6 +484,7 @@ int dtls1_accept(SSL *s)
|
|||||||
ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
|
ret=ssl3_get_finished(s,SSL3_ST_SR_FINISHED_A,
|
||||||
SSL3_ST_SR_FINISHED_B);
|
SSL3_ST_SR_FINISHED_B);
|
||||||
if (ret <= 0) goto end;
|
if (ret <= 0) goto end;
|
||||||
|
BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL);
|
||||||
if (s->hit)
|
if (s->hit)
|
||||||
s->state=SSL_ST_OK;
|
s->state=SSL_ST_OK;
|
||||||
else
|
else
|
||||||
|
Loading…
x
Reference in New Issue
Block a user