817cbc6
diff -up dhcp-4.1.1/client/dhc6.c.retransmission dhcp-4.1.1/client/dhc6.c
817cbc6
--- dhcp-4.1.1/client/dhc6.c.retransmission	2010-03-25 18:32:17.000000000 +0100
817cbc6
+++ dhcp-4.1.1/client/dhc6.c	2010-03-25 18:33:54.000000000 +0100
817cbc6
@@ -354,7 +354,7 @@ dhc6_retrans_init(struct client_state *c
817cbc6
 static void
817cbc6
 dhc6_retrans_advance(struct client_state *client)
817cbc6
 {
817cbc6
-	struct timeval elapsed;
817cbc6
+	struct timeval elapsed, elapsed_after_RT;
817cbc6
 
817cbc6
 	/* elapsed = cur - start */
817cbc6
 	elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
817cbc6
@@ -371,6 +371,8 @@ dhc6_retrans_advance(struct client_state
817cbc6
 		elapsed.tv_sec += 1;
817cbc6
 		elapsed.tv_usec -= 1000000;
817cbc6
 	}
817cbc6
+	elapsed_after_RT.tv_sec = elapsed.tv_sec;
817cbc6
+	elapsed_after_RT.tv_usec = elapsed.tv_usec;
817cbc6
 
817cbc6
 	/*
817cbc6
 	 * RT for each subsequent message transmission is based on the previous
817cbc6
@@ -408,13 +410,10 @@ dhc6_retrans_advance(struct client_state
817cbc6
 		elapsed.tv_usec -= 1000000;
817cbc6
 	}
817cbc6
 	if (elapsed.tv_sec >= client->MRD) {
817cbc6
-		/*
817cbc6
-		 * wake at RT + cur = start + MRD
817cbc6
-		 */
817cbc6
-		client->RT = client->MRD +
817cbc6
-			(client->start_time.tv_sec - cur_tv.tv_sec);
817cbc6
-		client->RT = client->RT * 100 +
817cbc6
-			(client->start_time.tv_usec - cur_tv.tv_usec) / 10000;
817cbc6
+		client->RT = client->MRD - elapsed_after_RT.tv_sec;
817cbc6
+		client->RT = client->RT * 100 - elapsed_after_RT.tv_usec / 10000;
817cbc6
+		if (client->RT < 0)
817cbc6
+			client->RT = 0;
817cbc6
 	}
817cbc6
 	client->txcount++;
817cbc6
 }
817cbc6
@@ -1502,7 +1501,7 @@ do_init6(void *input)
817cbc6
 		elapsed.tv_usec += 1000000;
817cbc6
 	}
817cbc6
 	/* Check if finished (-1 argument). */
817cbc6
-	if ((client->MRD != 0) && (elapsed.tv_sec > client->MRD)) {
817cbc6
+	if ((client->MRD != 0) && (elapsed.tv_sec >= client->MRD)) {
817cbc6
 		log_info("Max retransmission duration exceeded.");
817cbc6
 		client->state = S_STOPPED;
817cbc6
 		if (client->active_lease != NULL) {
817cbc6
@@ -1922,7 +1921,7 @@ do_info_request6(void *input)
817cbc6
 		elapsed.tv_usec += 1000000;
817cbc6
 	}
817cbc6
 	/* Check if finished (-1 argument). */
817cbc6
-	if ((client->MRD != 0) && (elapsed.tv_sec > client->MRD)) {
817cbc6
+	if ((client->MRD != 0) && (elapsed.tv_sec >= client->MRD)) {
817cbc6
 		log_info("Max retransmission duration exceeded.");
817cbc6
 		exit(2);
817cbc6
 	}
817cbc6
@@ -2043,7 +2042,7 @@ do_confirm6(void *input)
817cbc6
 		elapsed.tv_sec -= 1;
817cbc6
 		elapsed.tv_usec += 1000000;
817cbc6
 	}
817cbc6
-	if ((client->MRD != 0) && (elapsed.tv_sec > client->MRD)) {
817cbc6
+	if ((client->MRD != 0) && (elapsed.tv_sec >= client->MRD)) {
817cbc6
 		log_info("Max retransmission duration exceeded.");
817cbc6
 		start_bound(client);
817cbc6
 		return;
817cbc6
@@ -3290,7 +3289,7 @@ do_select6(void *input)
817cbc6
 		elapsed.tv_sec -= 1;
817cbc6
 		elapsed.tv_usec += 1000000;
817cbc6
 	}
817cbc6
-	if ((client->MRD != 0) && (elapsed.tv_sec > client->MRD)) {
817cbc6
+	if ((client->MRD != 0) && (elapsed.tv_sec >= client->MRD)) {
817cbc6
 		log_info("Max retransmission duration exceeded.");
817cbc6
 		abort = ISC_TRUE;
817cbc6
 	}