Loading crypto/bio/bio.h +2 −1 Original line number Diff line number Diff line Loading @@ -159,7 +159,8 @@ extern "C" { #define BIO_CTRL_DGRAM_SET_PEER 44 /* Destination for the data */ #define BIO_CTRL_DGRAM_SET_TIMEOUT 45 #define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45 /* Next DTLS handshake timeout to * adjust socket timeouts */ /* modifiers */ #define BIO_FP_READ 0x02 Loading crypto/bio/bss_dgram.c +88 −36 Original line number Diff line number Diff line Loading @@ -110,8 +110,8 @@ typedef struct bio_dgram_data_st unsigned int connected; unsigned int _errno; unsigned int mtu; struct timeval hstimeoutdiff; struct timeval hstimeout; struct timeval next_timeout; struct timeval socket_timeout; } bio_dgram_data; BIO_METHOD *BIO_s_datagram(void) Loading Loading @@ -174,6 +174,87 @@ static int dgram_clear(BIO *a) return(1); } static void dgram_adjust_rcv_timeout(BIO *b) { #if defined(SO_RCVTIMEO) bio_dgram_data *data = (bio_dgram_data *)b->ptr; int sz = sizeof(int); /* Is a timer active? */ if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) { struct timeval timenow, timeleft; /* Read current socket timeout */ #ifdef OPENSSL_SYS_WINDOWS int timeout; if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, (void*)&timeout, &sz) < 0) { perror("getsockopt"); } else { data->socket_timeout.tv_sec = timeout / 1000; data->socket_timeout.tv_usec = (timeout % 1000) * 1000; } #else if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout), (void *)&sz) < 0) { perror("getsockopt"); } #endif /* Get current time */ get_current_time(&timenow); /* Calculate time left until timer expires */ memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval)); timeleft.tv_sec -= timenow.tv_sec; timeleft.tv_usec -= timenow.tv_usec; if (timeleft.tv_usec < 0) { timeleft.tv_sec--; timeleft.tv_usec += 1000000; } /* Adjust socket timeout if next handhake message timer * will expire earlier. */ if (data->socket_timeout.tv_sec < timeleft.tv_sec || (data->socket_timeout.tv_sec == timeleft.tv_sec && data->socket_timeout.tv_usec <= timeleft.tv_usec)) { #ifdef OPENSSL_SYS_WINDOWS timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000; if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, (void*)&timeout, sizeof(timeout)) < 0) { perror("setsockopt"); } #else if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft, sizeof(struct timeval)) < 0) { perror("setsockopt"); } #endif } } #endif } static void dgram_reset_rcv_timeout(BIO *b) { #if defined(SO_RCVTIMEO) bio_dgram_data *data = (bio_dgram_data *)b->ptr; #ifdef OPENSSL_SYS_WINDOWS int timeout = data->socket_timeout.tv_sec * 1000 + data->socket_timeout.tv_usec / 1000; if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, (void*)&timeout, sizeof(timeout)) < 0) { perror("setsockopt"); } #else if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout), sizeof(struct timeval)) < 0) { perror("setsockopt"); } #endif #endif } static int dgram_read(BIO *b, char *out, int outl) { int ret=0; Loading @@ -191,7 +272,9 @@ static int dgram_read(BIO *b, char *out, int outl) * but this is not universal. Cast to (void *) to avoid * compiler warnings. */ dgram_adjust_rcv_timeout(b); ret=recvfrom(b->num,out,outl,0,&peer,(void *)&peerlen); dgram_reset_rcv_timeout(b); if ( ! data->connected && ret > 0) BIO_ctrl(b, BIO_CTRL_DGRAM_CONNECT, 0, &peer); Loading @@ -206,22 +289,6 @@ static int dgram_read(BIO *b, char *out, int outl) } memset(&(data->hstimeout), 0, sizeof(struct timeval)); } else { if (data->hstimeout.tv_sec > 0 || data->hstimeout.tv_usec > 0) { struct timeval curtime; get_current_time(&curtime); 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); } Loading Loading @@ -370,22 +437,8 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) memcpy(&(data->peer), to, sizeof(struct sockaddr)); break; case BIO_CTRL_DGRAM_SET_TIMEOUT: if (num > 0) { get_current_time(&data->hstimeout); 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)); } case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: memcpy(&(data->next_timeout), ptr, sizeof(struct timeval)); break; #if defined(SO_RCVTIMEO) case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: Loading @@ -402,7 +455,6 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) sizeof(struct timeval)) < 0) { perror("setsockopt"); ret = -1; } #endif memcpy(&(data->hstimeoutdiff), ptr, sizeof(struct timeval)); break; case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT: #ifdef OPENSSL_SYS_WINDOWS Loading ssl/d1_both.c +2 −3 Original line number Diff line number Diff line Loading @@ -883,7 +883,6 @@ unsigned long dtls1_output_cert_chain(SSL *s, X509 *x) int dtls1_read_failed(SSL *s, int code) { DTLS1_STATE *state; BIO *bio; int send_alert = 0; if ( code > 0) Loading @@ -892,8 +891,7 @@ int dtls1_read_failed(SSL *s, int code) return 1; } bio = SSL_get_rbio(s); if ( ! BIO_dgram_recv_timedout(bio)) if (!dtls1_is_timer_expired(s)) { /* not a timeout, none of our business, let higher layers handle this. in fact it's probably an error */ Loading @@ -906,6 +904,7 @@ 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) Loading ssl/d1_clnt.c +9 −9 Original line number Diff line number Diff line Loading @@ -233,7 +233,7 @@ int dtls1_connect(SSL *s) /* every DTLS ClientHello resets Finished MAC */ ssl3_init_finished_mac(s); BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL); dtls1_start_timer(s); ret=dtls1_client_hello(s); if (ret <= 0) goto end; Loading @@ -259,7 +259,7 @@ int dtls1_connect(SSL *s) if (ret <= 0) goto end; else { BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL); dtls1_stop_timer(s); if (s->hit) s->state=SSL3_ST_CR_FINISHED_A; else Loading @@ -274,7 +274,7 @@ int dtls1_connect(SSL *s) ret = dtls1_get_hello_verify(s); if ( ret <= 0) goto end; BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL); dtls1_stop_timer(s); if ( s->d1->send_cookie) /* start again, with a cookie */ s->state=SSL3_ST_CW_CLNT_HELLO_A; else Loading Loading @@ -336,7 +336,7 @@ int dtls1_connect(SSL *s) case SSL3_ST_CW_CERT_B: case SSL3_ST_CW_CERT_C: case SSL3_ST_CW_CERT_D: BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL); dtls1_start_timer(s); ret=dtls1_send_client_certificate(s); if (ret <= 0) goto end; s->state=SSL3_ST_CW_KEY_EXCH_A; Loading @@ -345,7 +345,7 @@ int dtls1_connect(SSL *s) case SSL3_ST_CW_KEY_EXCH_A: case SSL3_ST_CW_KEY_EXCH_B: BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL); dtls1_start_timer(s); ret=dtls1_send_client_key_exchange(s); if (ret <= 0) goto end; /* EAY EAY EAY need to check for DH fix cert Loading @@ -367,7 +367,7 @@ int dtls1_connect(SSL *s) case SSL3_ST_CW_CERT_VRFY_A: case SSL3_ST_CW_CERT_VRFY_B: BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL); dtls1_start_timer(s); ret=dtls1_send_client_verify(s); if (ret <= 0) goto end; s->state=SSL3_ST_CW_CHANGE_A; Loading @@ -377,7 +377,7 @@ int dtls1_connect(SSL *s) case SSL3_ST_CW_CHANGE_A: case SSL3_ST_CW_CHANGE_B: BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL); dtls1_start_timer(s); ret=dtls1_send_change_cipher_spec(s, SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B); if (ret <= 0) goto end; Loading Loading @@ -412,7 +412,7 @@ int dtls1_connect(SSL *s) case SSL3_ST_CW_FINISHED_A: case SSL3_ST_CW_FINISHED_B: BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL); dtls1_start_timer(s); ret=dtls1_send_finished(s, SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B, s->method->ssl3_enc->client_finished_label, Loading Loading @@ -445,7 +445,7 @@ int dtls1_connect(SSL *s) ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A, SSL3_ST_CR_FINISHED_B); if (ret <= 0) goto end; BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL); dtls1_stop_timer(s); if (s->hit) s->state=SSL3_ST_CW_CHANGE_A; Loading ssl/d1_lib.c +109 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,11 @@ #include <openssl/objects.h> #include "ssl_locl.h" #ifdef OPENSSL_SYS_WIN32 #include <sys/timeb.h> #endif static void get_current_time(struct timeval *t); const char dtls1_version_str[]="DTLSv1" OPENSSL_VERSION_PTEXT; SSL3_ENC_METHOD DTLSv1_enc_data={ Loading Loading @@ -201,3 +206,107 @@ const SSL_CIPHER *dtls1_get_cipher(unsigned int u) return ciph; } void dtls1_start_timer(SSL *s) { /* If timer is not set, initialize duration with 1 second */ if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { s->d1->timeout_duration = 1; } /* Set timeout to current time */ get_current_time(&(s->d1->next_timeout)); /* Add duration to current time */ s->d1->next_timeout.tv_sec += s->d1->timeout_duration; BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout)); } struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft) { struct timeval timenow; /* If no timeout is set, just return NULL */ if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { return NULL; } /* Get current time */ get_current_time(&timenow); /* If timer already expired, set remaining time to 0 */ if (s->d1->next_timeout.tv_sec < timenow.tv_sec || (s->d1->next_timeout.tv_sec == timenow.tv_sec && s->d1->next_timeout.tv_usec <= timenow.tv_usec)) { memset(timeleft, 0, sizeof(struct timeval)); return timeleft; } /* Calculate time left until timer expires */ memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval)); timeleft->tv_sec -= timenow.tv_sec; timeleft->tv_usec -= timenow.tv_usec; if (timeleft->tv_usec < 0) { timeleft->tv_sec--; timeleft->tv_usec += 1000000; } return timeleft; } int dtls1_is_timer_expired(SSL *s) { struct timeval timeleft; /* Get time left until timeout, return false if no timer running */ if (dtls1_get_timeout(s, &timeleft) == NULL) { return 0; } /* Return false if timer is not expired yet */ if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) { return 0; } /* Timer expired, so return true */ return 1; } void dtls1_double_timeout(SSL *s) { s->d1->timeout_duration *= 2; if (s->d1->timeout_duration > 60) s->d1->timeout_duration = 60; dtls1_start_timer(s); } void dtls1_stop_timer(SSL *s) { /* Reset everything */ memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); s->d1->timeout_duration = 1; BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout)); } static void get_current_time(struct timeval *t) { #ifdef OPENSSL_SYS_WIN32 struct _timeb tb; _ftime(&tb); t->tv_sec = (long)tb.time; t->tv_usec = (long)tb.millitm * 1000; #elif defined(OPENSSL_SYS_VMS) struct timeb tb; ftime(&tb); t->tv_sec = (long)tb.time; t->tv_usec = (long)tb.millitm * 1000; #else gettimeofday(t, NULL); #endif } Loading
crypto/bio/bio.h +2 −1 Original line number Diff line number Diff line Loading @@ -159,7 +159,8 @@ extern "C" { #define BIO_CTRL_DGRAM_SET_PEER 44 /* Destination for the data */ #define BIO_CTRL_DGRAM_SET_TIMEOUT 45 #define BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT 45 /* Next DTLS handshake timeout to * adjust socket timeouts */ /* modifiers */ #define BIO_FP_READ 0x02 Loading
crypto/bio/bss_dgram.c +88 −36 Original line number Diff line number Diff line Loading @@ -110,8 +110,8 @@ typedef struct bio_dgram_data_st unsigned int connected; unsigned int _errno; unsigned int mtu; struct timeval hstimeoutdiff; struct timeval hstimeout; struct timeval next_timeout; struct timeval socket_timeout; } bio_dgram_data; BIO_METHOD *BIO_s_datagram(void) Loading Loading @@ -174,6 +174,87 @@ static int dgram_clear(BIO *a) return(1); } static void dgram_adjust_rcv_timeout(BIO *b) { #if defined(SO_RCVTIMEO) bio_dgram_data *data = (bio_dgram_data *)b->ptr; int sz = sizeof(int); /* Is a timer active? */ if (data->next_timeout.tv_sec > 0 || data->next_timeout.tv_usec > 0) { struct timeval timenow, timeleft; /* Read current socket timeout */ #ifdef OPENSSL_SYS_WINDOWS int timeout; if (getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, (void*)&timeout, &sz) < 0) { perror("getsockopt"); } else { data->socket_timeout.tv_sec = timeout / 1000; data->socket_timeout.tv_usec = (timeout % 1000) * 1000; } #else if ( getsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout), (void *)&sz) < 0) { perror("getsockopt"); } #endif /* Get current time */ get_current_time(&timenow); /* Calculate time left until timer expires */ memcpy(&timeleft, &(data->next_timeout), sizeof(struct timeval)); timeleft.tv_sec -= timenow.tv_sec; timeleft.tv_usec -= timenow.tv_usec; if (timeleft.tv_usec < 0) { timeleft.tv_sec--; timeleft.tv_usec += 1000000; } /* Adjust socket timeout if next handhake message timer * will expire earlier. */ if (data->socket_timeout.tv_sec < timeleft.tv_sec || (data->socket_timeout.tv_sec == timeleft.tv_sec && data->socket_timeout.tv_usec <= timeleft.tv_usec)) { #ifdef OPENSSL_SYS_WINDOWS timeout = timeleft.tv_sec * 1000 + timeleft.tv_usec / 1000; if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, (void*)&timeout, sizeof(timeout)) < 0) { perror("setsockopt"); } #else if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &timeleft, sizeof(struct timeval)) < 0) { perror("setsockopt"); } #endif } } #endif } static void dgram_reset_rcv_timeout(BIO *b) { #if defined(SO_RCVTIMEO) bio_dgram_data *data = (bio_dgram_data *)b->ptr; #ifdef OPENSSL_SYS_WINDOWS int timeout = data->socket_timeout.tv_sec * 1000 + data->socket_timeout.tv_usec / 1000; if (setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, (void*)&timeout, sizeof(timeout)) < 0) { perror("setsockopt"); } #else if ( setsockopt(b->num, SOL_SOCKET, SO_RCVTIMEO, &(data->socket_timeout), sizeof(struct timeval)) < 0) { perror("setsockopt"); } #endif #endif } static int dgram_read(BIO *b, char *out, int outl) { int ret=0; Loading @@ -191,7 +272,9 @@ static int dgram_read(BIO *b, char *out, int outl) * but this is not universal. Cast to (void *) to avoid * compiler warnings. */ dgram_adjust_rcv_timeout(b); ret=recvfrom(b->num,out,outl,0,&peer,(void *)&peerlen); dgram_reset_rcv_timeout(b); if ( ! data->connected && ret > 0) BIO_ctrl(b, BIO_CTRL_DGRAM_CONNECT, 0, &peer); Loading @@ -206,22 +289,6 @@ static int dgram_read(BIO *b, char *out, int outl) } memset(&(data->hstimeout), 0, sizeof(struct timeval)); } else { if (data->hstimeout.tv_sec > 0 || data->hstimeout.tv_usec > 0) { struct timeval curtime; get_current_time(&curtime); 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); } Loading Loading @@ -370,22 +437,8 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) memcpy(&(data->peer), to, sizeof(struct sockaddr)); break; case BIO_CTRL_DGRAM_SET_TIMEOUT: if (num > 0) { get_current_time(&data->hstimeout); 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)); } case BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT: memcpy(&(data->next_timeout), ptr, sizeof(struct timeval)); break; #if defined(SO_RCVTIMEO) case BIO_CTRL_DGRAM_SET_RECV_TIMEOUT: Loading @@ -402,7 +455,6 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) sizeof(struct timeval)) < 0) { perror("setsockopt"); ret = -1; } #endif memcpy(&(data->hstimeoutdiff), ptr, sizeof(struct timeval)); break; case BIO_CTRL_DGRAM_GET_RECV_TIMEOUT: #ifdef OPENSSL_SYS_WINDOWS Loading
ssl/d1_both.c +2 −3 Original line number Diff line number Diff line Loading @@ -883,7 +883,6 @@ unsigned long dtls1_output_cert_chain(SSL *s, X509 *x) int dtls1_read_failed(SSL *s, int code) { DTLS1_STATE *state; BIO *bio; int send_alert = 0; if ( code > 0) Loading @@ -892,8 +891,7 @@ int dtls1_read_failed(SSL *s, int code) return 1; } bio = SSL_get_rbio(s); if ( ! BIO_dgram_recv_timedout(bio)) if (!dtls1_is_timer_expired(s)) { /* not a timeout, none of our business, let higher layers handle this. in fact it's probably an error */ Loading @@ -906,6 +904,7 @@ 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) Loading
ssl/d1_clnt.c +9 −9 Original line number Diff line number Diff line Loading @@ -233,7 +233,7 @@ int dtls1_connect(SSL *s) /* every DTLS ClientHello resets Finished MAC */ ssl3_init_finished_mac(s); BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL); dtls1_start_timer(s); ret=dtls1_client_hello(s); if (ret <= 0) goto end; Loading @@ -259,7 +259,7 @@ int dtls1_connect(SSL *s) if (ret <= 0) goto end; else { BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL); dtls1_stop_timer(s); if (s->hit) s->state=SSL3_ST_CR_FINISHED_A; else Loading @@ -274,7 +274,7 @@ int dtls1_connect(SSL *s) ret = dtls1_get_hello_verify(s); if ( ret <= 0) goto end; BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL); dtls1_stop_timer(s); if ( s->d1->send_cookie) /* start again, with a cookie */ s->state=SSL3_ST_CW_CLNT_HELLO_A; else Loading Loading @@ -336,7 +336,7 @@ int dtls1_connect(SSL *s) case SSL3_ST_CW_CERT_B: case SSL3_ST_CW_CERT_C: case SSL3_ST_CW_CERT_D: BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL); dtls1_start_timer(s); ret=dtls1_send_client_certificate(s); if (ret <= 0) goto end; s->state=SSL3_ST_CW_KEY_EXCH_A; Loading @@ -345,7 +345,7 @@ int dtls1_connect(SSL *s) case SSL3_ST_CW_KEY_EXCH_A: case SSL3_ST_CW_KEY_EXCH_B: BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL); dtls1_start_timer(s); ret=dtls1_send_client_key_exchange(s); if (ret <= 0) goto end; /* EAY EAY EAY need to check for DH fix cert Loading @@ -367,7 +367,7 @@ int dtls1_connect(SSL *s) case SSL3_ST_CW_CERT_VRFY_A: case SSL3_ST_CW_CERT_VRFY_B: BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL); dtls1_start_timer(s); ret=dtls1_send_client_verify(s); if (ret <= 0) goto end; s->state=SSL3_ST_CW_CHANGE_A; Loading @@ -377,7 +377,7 @@ int dtls1_connect(SSL *s) case SSL3_ST_CW_CHANGE_A: case SSL3_ST_CW_CHANGE_B: BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL); dtls1_start_timer(s); ret=dtls1_send_change_cipher_spec(s, SSL3_ST_CW_CHANGE_A,SSL3_ST_CW_CHANGE_B); if (ret <= 0) goto end; Loading Loading @@ -412,7 +412,7 @@ int dtls1_connect(SSL *s) case SSL3_ST_CW_FINISHED_A: case SSL3_ST_CW_FINISHED_B: BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 1, NULL); dtls1_start_timer(s); ret=dtls1_send_finished(s, SSL3_ST_CW_FINISHED_A,SSL3_ST_CW_FINISHED_B, s->method->ssl3_enc->client_finished_label, Loading Loading @@ -445,7 +445,7 @@ int dtls1_connect(SSL *s) ret=ssl3_get_finished(s,SSL3_ST_CR_FINISHED_A, SSL3_ST_CR_FINISHED_B); if (ret <= 0) goto end; BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL); dtls1_stop_timer(s); if (s->hit) s->state=SSL3_ST_CW_CHANGE_A; Loading
ssl/d1_lib.c +109 −0 Original line number Diff line number Diff line Loading @@ -61,6 +61,11 @@ #include <openssl/objects.h> #include "ssl_locl.h" #ifdef OPENSSL_SYS_WIN32 #include <sys/timeb.h> #endif static void get_current_time(struct timeval *t); const char dtls1_version_str[]="DTLSv1" OPENSSL_VERSION_PTEXT; SSL3_ENC_METHOD DTLSv1_enc_data={ Loading Loading @@ -201,3 +206,107 @@ const SSL_CIPHER *dtls1_get_cipher(unsigned int u) return ciph; } void dtls1_start_timer(SSL *s) { /* If timer is not set, initialize duration with 1 second */ if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { s->d1->timeout_duration = 1; } /* Set timeout to current time */ get_current_time(&(s->d1->next_timeout)); /* Add duration to current time */ s->d1->next_timeout.tv_sec += s->d1->timeout_duration; BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout)); } struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft) { struct timeval timenow; /* If no timeout is set, just return NULL */ if (s->d1->next_timeout.tv_sec == 0 && s->d1->next_timeout.tv_usec == 0) { return NULL; } /* Get current time */ get_current_time(&timenow); /* If timer already expired, set remaining time to 0 */ if (s->d1->next_timeout.tv_sec < timenow.tv_sec || (s->d1->next_timeout.tv_sec == timenow.tv_sec && s->d1->next_timeout.tv_usec <= timenow.tv_usec)) { memset(timeleft, 0, sizeof(struct timeval)); return timeleft; } /* Calculate time left until timer expires */ memcpy(timeleft, &(s->d1->next_timeout), sizeof(struct timeval)); timeleft->tv_sec -= timenow.tv_sec; timeleft->tv_usec -= timenow.tv_usec; if (timeleft->tv_usec < 0) { timeleft->tv_sec--; timeleft->tv_usec += 1000000; } return timeleft; } int dtls1_is_timer_expired(SSL *s) { struct timeval timeleft; /* Get time left until timeout, return false if no timer running */ if (dtls1_get_timeout(s, &timeleft) == NULL) { return 0; } /* Return false if timer is not expired yet */ if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) { return 0; } /* Timer expired, so return true */ return 1; } void dtls1_double_timeout(SSL *s) { s->d1->timeout_duration *= 2; if (s->d1->timeout_duration > 60) s->d1->timeout_duration = 60; dtls1_start_timer(s); } void dtls1_stop_timer(SSL *s) { /* Reset everything */ memset(&(s->d1->next_timeout), 0, sizeof(struct timeval)); s->d1->timeout_duration = 1; BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout)); } static void get_current_time(struct timeval *t) { #ifdef OPENSSL_SYS_WIN32 struct _timeb tb; _ftime(&tb); t->tv_sec = (long)tb.time; t->tv_usec = (long)tb.millitm * 1000; #elif defined(OPENSSL_SYS_VMS) struct timeb tb; ftime(&tb); t->tv_sec = (long)tb.time; t->tv_usec = (long)tb.millitm * 1000; #else gettimeofday(t, NULL); #endif }