--- apps/s_client.c	30 Jun 2009 15:56:35 -0000	1.125
+++ apps/s_client.c	27 Jul 2009 12:28:55 -0000
@@ -411,6 +411,7 @@
 	BIO *sbio;
 	char *inrand=NULL;
 	int mbuf_len=0;
+	struct timeval timeout, *timeoutp;
 #ifndef OPENSSL_NO_ENGINE
 	char *engine_id=NULL;
 	char *ssl_client_engine_id=NULL;
@@ -1196,6 +1197,12 @@
 		FD_ZERO(&readfds);
 		FD_ZERO(&writefds);
 
+		if ((SSL_version(con) == DTLS1_VERSION) &&
+			(DTLSv1_get_timeout(con, &timeout) != NULL))
+			timeoutp = &timeout;
+		else
+			timeoutp = NULL;
+
 		if (SSL_in_init(con) && !SSL_total_renegotiations(con))
 			{
 			in_init=1;
@@ -1300,7 +1307,7 @@
 					if(!i && (!((_kbhit()) || (WAIT_OBJECT_0 == WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), 0))) || !read_tty) ) continue;
 #endif
 				} else 	i=select(width,(void *)&readfds,(void *)&writefds,
-					 NULL,NULL);
+					 NULL,timeoutp);
 			}
 #elif defined(OPENSSL_SYS_NETWARE)
 			if(!write_tty) {
@@ -1310,7 +1317,7 @@
 					i=select(width,(void *)&readfds,(void *)&writefds,
 						NULL,&tv);
 				} else 	i=select(width,(void *)&readfds,(void *)&writefds,
-					NULL,NULL);
+					NULL,timeoutp);
 			}
 #elif defined(OPENSSL_SYS_BEOS_R5)
 			/* Under BeOS-R5 the situation is similar to DOS */
@@ -1328,12 +1335,12 @@
 					if (!i && (stdin_set != 1 || !read_tty))
 						continue;
 				} else 	i=select(width,(void *)&readfds,(void *)&writefds,
-					 NULL,NULL);
+					 NULL,timeoutp);
 			}
 			(void)fcntl(fileno(stdin), F_SETFL, 0);
 #else
 			i=select(width,(void *)&readfds,(void *)&writefds,
-				 NULL,NULL);
+				 NULL,timeoutp);
 #endif
 			if ( i < 0)
 				{
@@ -1344,6 +1351,11 @@
 				}
 			}
 
+		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))
 			{
 			k=SSL_write(con,&(cbuf[cbuf_off]),

--- apps/s_server.c	30 Jun 2009 15:56:35 -0000	1.140
+++ apps/s_server.c	27 Jul 2009 12:28:55 -0000
@@ -1750,6 +1750,7 @@
 	unsigned long l;
 	SSL *con=NULL;
 	BIO *sbio;
+	struct timeval timeout, *timeoutp;
 #if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_BEOS_R5)
 	struct timeval tv;
 #endif
@@ -1919,7 +1920,19 @@
 				read_from_terminal = 1;
 			(void)fcntl(fileno(stdin), F_SETFL, 0);
 #else
-			i=select(width,(void *)&readfds,NULL,NULL,NULL);
+			if ((SSL_version(con) == DTLS1_VERSION) &&
+				(DTLSv1_get_timeout(con, &timeout) != NULL))
+				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 (FD_ISSET(fileno(stdin),&readfds))
 				read_from_terminal = 1;

--- ssl/d1_both.c	15 Jul 2009 11:33:24 -0000	1.23
+++ ssl/d1_both.c	27 Jul 2009 12:28:56 -0000
@@ -890,9 +890,6 @@
 
 int dtls1_read_failed(SSL *s, int code)
 	{
-	DTLS1_STATE *state;
-	int send_alert = 0;
-
 	if ( code > 0)
 		{
 		fprintf( stderr, "invalid state reached %s:%d", __FILE__, __LINE__);
@@ -912,24 +909,6 @@
 		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 */
 	item = pqueue_peek(state->rcvd_records);
 	if ( item )
@@ -940,12 +919,12 @@
 #endif
 
 #if 0  /* no more alert sending, just retransmit the last set of messages */
-		if ( send_alert)
-			ssl3_send_alert(s,SSL3_AL_WARNING,
-				DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
+	if ( state->timeout.read_timeouts >= DTLS1_TMO_READ_COUNT)
+		ssl3_send_alert(s,SSL3_AL_WARNING,
+			DTLS1_AD_MISSING_HANDSHAKE_MESSAGE);
 #endif
 
-	return dtls1_retransmit_buffered_messages(s) ;
+	return DTLSv1_handle_timeout(s);
 	}
 
 int

--- ssl/d1_lib.c	31 May 2009 17:13:09 -0000	1.14
+++ ssl/d1_lib.c	27 Jul 2009 12:28:56 -0000
@@ -224,7 +224,7 @@
 	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* DTLSv1_get_timeout(SSL *s, struct timeval* timeleft)
 	{
 	struct timeval timenow;
 
@@ -264,7 +264,7 @@
 	struct timeval timeleft;
 
 	/* Get time left until timeout, return false if no timer running */
-	if (dtls1_get_timeout(s, &timeleft) == NULL)
+	if (DTLSv1_get_timeout(s, &timeleft) == NULL)
 		{
 		return 0;
 		}
@@ -295,6 +295,36 @@
 	BIO_ctrl(SSL_get_rbio(s), BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0, &(s->d1->next_timeout));
 	}
 
+int DTLSv1_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)
 {
 #ifdef OPENSSL_SYS_WIN32

--- ssl/d1_pkt.c	24 Jul 2009 11:52:55 -0000	1.38
+++ ssl/d1_pkt.c	27 Jul 2009 12:28:56 -0000
@@ -773,11 +773,8 @@
 		}
 
 	/* Check for timeout */
-	if (dtls1_is_timer_expired(s))
-		{
-		if (dtls1_read_failed(s, -1) > 0)
-			goto start;
-		}
+	if (DTLSv1_handle_timeout(s) > 0)
+		goto start;
 
 	/* get new packet if necessary */
 	if ((rr->length == 0) || (s->rstate == SSL_ST_READ_BODY))

--- ssl/ssl.h	15 Jul 2009 11:33:24 -0000	1.228
+++ ssl/ssl.h	27 Jul 2009 12:28:56 -0000
@@ -1622,6 +1622,9 @@
 const SSL_METHOD *DTLSv1_server_method(void);	/* DTLSv1.0 */
 const SSL_METHOD *DTLSv1_client_method(void);	/* DTLSv1.0 */
 
+struct timeval* DTLSv1_get_timeout(SSL *s, struct timeval* timeleft);
+int DTLSv1_handle_timeout(SSL *s);
+
 STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *s);
 
 int SSL_do_handshake(SSL *s);

--- ssl/ssl_locl.h	16 May 2009 11:15:42 -0000	1.104
+++ ssl/ssl_locl.h	27 Jul 2009 12:28:56 -0000
@@ -942,7 +942,6 @@
 void dtls1_get_ccs_header(unsigned char *data, struct ccs_header_st *ccs_hdr);
 void dtls1_reset_seq_numbers(SSL *s, int rw);
 long dtls1_default_timeout(void);
-struct timeval* dtls1_get_timeout(SSL *s, struct timeval* timeleft);
 const SSL_CIPHER *dtls1_get_cipher(unsigned int u);
 void dtls1_start_timer(SSL *s);
 void dtls1_stop_timer(SSL *s);
