diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h index ca1116241..ddbac5836 100644 --- a/include/polarssl/ssl.h +++ b/include/polarssl/ssl.h @@ -253,12 +253,8 @@ /* * DTLS retransmission states, see RFC 6347 4.2.4 * - * Warning: the state is sometimes explicit sometimes implicit! - * - PREPARING is explicit (but could be implicit from ssl->state) - * - SENDING is merged in PREPARING for initial sends, explicit for resends - * - WAITING is usually implicit from ssl->state, except after resend - * - FINISHED is explicit (but could be implicit from state) - * TODO-DTLS: clean that up + * The SENDING state is merged in PREPARING for initial sends, + * but is distinct for resends. */ #define SSL_RETRANS_PREPARING 0 #define SSL_RETRANS_SENDING 1 @@ -2082,6 +2078,7 @@ static inline size_t ssl_hs_hdr_len( const ssl_context *ssl ) } #if defined(POLARSSL_SSL_PROTO_DTLS) +void ssl_send_flight_completed( ssl_context *ssl ); void ssl_recv_flight_completed( ssl_context *ssl ); int ssl_resend( ssl_context *ssl ); #endif diff --git a/library/ssl_cli.c b/library/ssl_cli.c index a117647db..c83e6ac95 100644 --- a/library/ssl_cli.c +++ b/library/ssl_cli.c @@ -759,6 +759,11 @@ static int ssl_write_client_hello( ssl_context *ssl ) ssl->state++; +#if defined(POLARSSL_SSL_PROTO_DTLS) + if( ssl->transport == SSL_TRANSPORT_DATAGRAM ) + ssl_send_flight_completed( ssl ); +#endif + if( ( ret = ssl_write_record( ssl ) ) != 0 ) { SSL_DEBUG_RET( 1, "ssl_write_record", ret ); diff --git a/library/ssl_srv.c b/library/ssl_srv.c index ba46f5a61..219fc018f 100644 --- a/library/ssl_srv.c +++ b/library/ssl_srv.c @@ -2831,6 +2831,11 @@ static int ssl_write_server_hello_done( ssl_context *ssl ) ssl->state++; +#if defined(POLARSSL_SSL_PROTO_DTLS) + if( ssl->transport == SSL_TRANSPORT_DATAGRAM ) + ssl_send_flight_completed( ssl ); +#endif + if( ( ret = ssl_write_record( ssl ) ) != 0 ) { SSL_DEBUG_RET( 1, "ssl_write_record", ret ); diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 3f3d4ee57..f6626c995 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1961,12 +1961,14 @@ int ssl_fetch_input( ssl_context *ssl, size_t nb_want ) else ret = ssl->f_recv( ssl->p_bio, ssl->in_hdr, len ); - SSL_DEBUG_RET( 2, "ssl->f_recv", ret ); + SSL_DEBUG_RET( 2, "ssl->f_recv(_timeout)", ret ); if( ret == 0 ) return( POLARSSL_ERR_SSL_CONN_EOF ); - if( ret == POLARSSL_ERR_NET_TIMEOUT ) + if( ret == POLARSSL_ERR_NET_TIMEOUT || + ( ret == POLARSSL_ERR_NET_WANT_READ && + ssl_check_timer( ssl ) != 0 ) ) { SSL_DEBUG_MSG( 2, ( "recv timeout" ) ); @@ -2206,6 +2208,9 @@ int ssl_resend( ssl_context *ssl ) ssl_swap_epochs( ssl ); ssl->handshake->retransmit_state = SSL_RETRANS_SENDING; + + /* Cancel running timer */ + ssl_set_timer( ssl, 0 ); } while( ssl->handshake->cur_msg != NULL ) @@ -2242,6 +2247,9 @@ int ssl_resend( ssl_context *ssl ) else ssl->handshake->retransmit_state = SSL_RETRANS_WAITING; + /* WIP: hardcoded 1 sec will be replaced */ + ssl_set_timer( ssl, 1000 ); + SSL_DEBUG_MSG( 2, ( "<= ssl_resend" ) ); return( 0 ); @@ -2260,6 +2268,9 @@ void ssl_recv_flight_completed( ssl_context *ssl ) /* The next incoming flight will start with this msg_seq */ ssl->handshake->in_flight_start_seq = ssl->handshake->in_msg_seq; + /* Cancel timer */ + ssl_set_timer( ssl, 0 ); + if( ssl->in_msgtype == SSL_MSG_HANDSHAKE && ssl->in_msg[0] == SSL_HS_FINISHED ) { @@ -2268,6 +2279,23 @@ void ssl_recv_flight_completed( ssl_context *ssl ) else ssl->handshake->retransmit_state = SSL_RETRANS_PREPARING; } + +/* + * To be called when the last message of an outgoing flight is send. + */ +void ssl_send_flight_completed( ssl_context *ssl ) +{ + /* WIP: hardcoded 1 sec is temporary */ + ssl_set_timer( ssl, 1000 ); + + if( ssl->in_msgtype == SSL_MSG_HANDSHAKE && + ssl->in_msg[0] == SSL_HS_FINISHED ) + { + ssl->handshake->retransmit_state = SSL_RETRANS_FINISHED; + } + else + ssl->handshake->retransmit_state = SSL_RETRANS_WAITING; +} #endif /* POLARSSL_SSL_PROTO_DTLS */ /* @@ -3152,7 +3180,7 @@ read_record_header: #if defined(POLARSSL_SSL_PROTO_DTLS) if( ssl->transport == SSL_TRANSPORT_DATAGRAM && ssl->handshake != NULL && - ssl->handshake->retransmit_state == SSL_RETRANS_FINISHED ) + ssl->state == SSL_HANDSHAKE_OVER ) { if( ssl->in_msgtype == SSL_MSG_HANDSHAKE && ssl->in_msg[0] == SSL_HS_FINISHED ) @@ -4263,6 +4291,11 @@ int ssl_write_finished( ssl_context *ssl ) } #endif +#if defined(POLARSSL_SSL_PROTO_DTLS) + if( ssl->transport == SSL_TRANSPORT_DATAGRAM ) + ssl_send_flight_completed( ssl ); +#endif + if( ( ret = ssl_write_record( ssl ) ) != 0 ) { SSL_DEBUG_RET( 1, "ssl_write_record", ret );