aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-05-21 07:03:03 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-05-21 07:03:03 +0000
commit19903f0d447116baef455eddc14458b1dfd1c834 (patch)
tree94736618159031472f02cc817617899f9dbdeaaf
parentb23429198eedc77763d05e3c6fcf319721800b32 (diff)
downloadbusybox-w32-19903f0d447116baef455eddc14458b1dfd1c834.tar.gz
busybox-w32-19903f0d447116baef455eddc14458b1dfd1c834.tar.bz2
busybox-w32-19903f0d447116baef455eddc14458b1dfd1c834.zip
udhcpc: simplify renewal of the lease
-rw-r--r--networking/udhcp/dhcpc.c41
1 files changed, 19 insertions, 22 deletions
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c
index eeef435de..7138389b8 100644
--- a/networking/udhcp/dhcpc.c
+++ b/networking/udhcp/dhcpc.c
@@ -143,10 +143,7 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv)
143 uint32_t xid = 0; 143 uint32_t xid = 0;
144 uint32_t lease_seconds = 0; /* can be given as 32-bit quantity */ 144 uint32_t lease_seconds = 0; /* can be given as 32-bit quantity */
145 int packet_num; 145 int packet_num;
146 /* t1, t2... what a wonderful names... */ 146 unsigned already_waited_sec;
147 unsigned t1 = t1; /* for gcc */
148 unsigned t2 = t2;
149 unsigned timestamp_got_lease = timestamp_got_lease;
150 unsigned opt; 147 unsigned opt;
151 int max_fd; 148 int max_fd;
152 int retval; 149 int retval;
@@ -337,6 +334,7 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv)
337 udhcp_run_script(NULL, "deconfig"); 334 udhcp_run_script(NULL, "deconfig");
338 change_listen_mode(LISTEN_RAW); 335 change_listen_mode(LISTEN_RAW);
339 packet_num = 0; 336 packet_num = 0;
337 already_waited_sec = 0;
340 338
341 /* Main event loop. select() waits on signal pipe and possibly 339 /* Main event loop. select() waits on signal pipe and possibly
342 * on sockfd. 340 * on sockfd.
@@ -353,7 +351,7 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv)
353 } 351 }
354 max_fd = udhcp_sp_fd_set(&rfds, sockfd); 352 max_fd = udhcp_sp_fd_set(&rfds, sockfd);
355 353
356 tv.tv_sec = timeout; 354 tv.tv_sec = timeout - already_waited_sec;
357 tv.tv_usec = 0; 355 tv.tv_usec = 0;
358 retval = 0; /* If we already timed out, fall through, else... */ 356 retval = 0; /* If we already timed out, fall through, else... */
359 if (tv.tv_sec > 0) { 357 if (tv.tv_sec > 0) {
@@ -373,6 +371,9 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv)
373 * resend discover/renew/whatever 371 * resend discover/renew/whatever
374 */ 372 */
375 if (retval == 0) { 373 if (retval == 0) {
374 /* We will restart wait afresh in any case */
375 already_waited_sec = 0;
376
376 switch (state) { 377 switch (state) {
377 case INIT_SELECTING: 378 case INIT_SELECTING:
378 if (packet_num < discover_retries) { 379 if (packet_num < discover_retries) {
@@ -420,33 +421,29 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv)
420 packet_num = 0; 421 packet_num = 0;
421 continue; 422 continue;
422 case BOUND: 423 case BOUND:
423 /* Lease is starting to run out, time to enter renewing state */ 424 /* Half of the lease passed, time to enter renewing state */
424 change_listen_mode(LISTEN_KERNEL); 425 change_listen_mode(LISTEN_KERNEL);
425 DEBUG("Entering renew state"); 426 DEBUG("Entering renew state");
426 state = RENEWING; 427 state = RENEWING;
427 /* fall right through */ 428 /* fall right through */
428 case RENEWING: 429 case RENEWING:
429 /* Either set a new T1, or enter REBINDING state */ 430 if (timeout > 60) {
430 if ((t2 - t1) > (lease_seconds / (4*60*60) + 1)) {
431 /* send a request packet */ 431 /* send a request packet */
432 send_renew(xid, server_addr, requested_ip); /* unicast */ 432 send_renew(xid, server_addr, requested_ip); /* unicast */
433 t1 += (t2 - t1) / 2; 433 timeout >>= 1;
434 timeout = t1 - ((unsigned)monotonic_sec() - timestamp_got_lease);
435 continue; 434 continue;
436 } 435 }
437 /* Timed out, enter rebinding state */ 436 /* Timed out, enter rebinding state */
438 DEBUG("Entering rebinding state"); 437 DEBUG("Entering rebinding state");
439 state = REBINDING; 438 state = REBINDING;
440 timeout = (t2 - t1);
441 continue; 439 continue;
442 case REBINDING: 440 case REBINDING:
443 /* Lease is *really* about to run out, 441 /* Lease is *really* about to run out,
444 * try to find DHCP server using broadcast */ 442 * try to find DHCP server using broadcast */
445 if ((lease_seconds - t2) > (lease_seconds / (4*60*60) + 1)) { 443 if (timeout > 0) {
446 /* send a request packet */ 444 /* send a request packet */
447 send_renew(xid, 0, requested_ip); /* broadcast */ 445 send_renew(xid, 0, requested_ip); /* broadcast */
448 t2 += (lease_seconds - t2) / 2; 446 timeout >>= 1;
449 timeout = t2 - ((unsigned)monotonic_sec() - timestamp_got_lease);
450 continue; 447 continue;
451 } 448 }
452 /* Timed out, enter init state */ 449 /* Timed out, enter init state */
@@ -454,7 +451,7 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv)
454 udhcp_run_script(NULL, "deconfig"); 451 udhcp_run_script(NULL, "deconfig");
455 change_listen_mode(LISTEN_RAW); 452 change_listen_mode(LISTEN_RAW);
456 state = INIT_SELECTING; 453 state = INIT_SELECTING;
457 timeout = 0; 454 /*timeout = 0; - already is */
458 packet_num = 0; 455 packet_num = 0;
459 continue; 456 continue;
460 /* case RELEASED: */ 457 /* case RELEASED: */
@@ -477,7 +474,7 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv)
477 /* If this packet will turn out to be unrelated/bogus, 474 /* If this packet will turn out to be unrelated/bogus,
478 * we will go back and wait for next one. 475 * we will go back and wait for next one.
479 * Be sure timeout is properly decreased. */ 476 * Be sure timeout is properly decreased. */
480 timeout -= (unsigned)monotonic_sec() - timestamp_before_wait; 477 already_waited_sec += (unsigned)monotonic_sec() - timestamp_before_wait;
481 478
482 if (len == -1) { /* error is severe, reopen socket */ 479 if (len == -1) { /* error is severe, reopen socket */
483 DEBUG("error on read, %s, reopening socket", strerror(errno)); 480 DEBUG("error on read, %s, reopening socket", strerror(errno));
@@ -523,6 +520,7 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv)
523 state = REQUESTING; 520 state = REQUESTING;
524 timeout = 0; 521 timeout = 0;
525 packet_num = 0; 522 packet_num = 0;
523 already_waited_sec = 0;
526 } 524 }
527 continue; 525 continue;
528 case RENEW_REQUESTED: 526 case RENEW_REQUESTED:
@@ -538,6 +536,7 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv)
538 /* can be misaligned, thus memcpy */ 536 /* can be misaligned, thus memcpy */
539 memcpy(&lease_seconds, temp, 4); 537 memcpy(&lease_seconds, temp, 4);
540 lease_seconds = ntohl(lease_seconds); 538 lease_seconds = ntohl(lease_seconds);
539 lease_seconds &= 0x0fffffff; /* paranoia: must not be negative */
541 } 540 }
542#if ENABLE_FEATURE_UDHCPC_ARPING 541#if ENABLE_FEATURE_UDHCPC_ARPING
543 if (opt & OPT_a) { 542 if (opt & OPT_a) {
@@ -557,20 +556,16 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv)
557 requested_ip = 0; 556 requested_ip = 0;
558 timeout = tryagain_timeout; 557 timeout = tryagain_timeout;
559 packet_num = 0; 558 packet_num = 0;
559 already_waited_sec = 0;
560 continue; /* back to main loop */ 560 continue; /* back to main loop */
561 } 561 }
562 } 562 }
563#endif 563#endif
564 /* enter bound state */ 564 /* enter bound state */
565 t1 = lease_seconds / 2; 565 timeout = lease_seconds / 2;
566
567 /* little fixed point for n * .875 */
568 t2 = (lease_seconds * 7) >> 3;
569 temp_addr.s_addr = packet.yiaddr; 566 temp_addr.s_addr = packet.yiaddr;
570 bb_info_msg("Lease of %s obtained, lease time %u", 567 bb_info_msg("Lease of %s obtained, lease time %u",
571 inet_ntoa(temp_addr), (unsigned)lease_seconds); 568 inet_ntoa(temp_addr), (unsigned)lease_seconds);
572 timestamp_got_lease = monotonic_sec();
573 timeout = t1;
574 requested_ip = packet.yiaddr; 569 requested_ip = packet.yiaddr;
575 udhcp_run_script(&packet, 570 udhcp_run_script(&packet,
576 ((state == RENEWING || state == REBINDING) ? "renew" : "bound")); 571 ((state == RENEWING || state == REBINDING) ? "renew" : "bound"));
@@ -585,6 +580,7 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv)
585 if (!client_config.foreground) 580 if (!client_config.foreground)
586 client_background(); 581 client_background();
587 582
583 already_waited_sec = 0;
588 continue; /* back to main loop */ 584 continue; /* back to main loop */
589 } 585 }
590 if (*message == DHCPNAK) { 586 if (*message == DHCPNAK) {
@@ -599,6 +595,7 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv)
599 requested_ip = 0; 595 requested_ip = 0;
600 timeout = 0; 596 timeout = 0;
601 packet_num = 0; 597 packet_num = 0;
598 already_waited_sec = 0;
602 } 599 }
603 continue; 600 continue;
604 /* case BOUND, RELEASED: - ignore all packets */ 601 /* case BOUND, RELEASED: - ignore all packets */