diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-05-26 17:32:35 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-05-26 17:32:35 +0000 |
commit | fc9e1080320e52fb97ae694627d8101af64f3dad (patch) | |
tree | 2b57edddb15071f8fa13a47e45a735d0e8c52edc | |
parent | 6bb55cfb99090565d565588c281c08ca21993e78 (diff) | |
download | busybox-w32-fc9e1080320e52fb97ae694627d8101af64f3dad.tar.gz busybox-w32-fc9e1080320e52fb97ae694627d8101af64f3dad.tar.bz2 busybox-w32-fc9e1080320e52fb97ae694627d8101af64f3dad.zip |
udhcpc: shrink
udhcpc: guard against zero lease time
function old new delta
timeout 4 - -4
server_addr 4 - -4
requested_ip 4 - -4
perform_release 134 112 -22
udhcpc_main 2511 2485 -26
------------------------------------------------------------------------------
(add/remove: 0/3 grow/shrink: 0/2 up/down: 0/-60) Total: -60 bytes
-rw-r--r-- | include/platform.h | 15 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.c | 33 | ||||
-rw-r--r-- | networking/udhcp/dhcpc.h | 9 |
3 files changed, 36 insertions, 21 deletions
diff --git a/include/platform.h b/include/platform.h index 0e0ccaf90..21224fabf 100644 --- a/include/platform.h +++ b/include/platform.h | |||
@@ -135,7 +135,18 @@ | |||
135 | #define SWAP_LE64(x) (x) | 135 | #define SWAP_LE64(x) (x) |
136 | #endif | 136 | #endif |
137 | 137 | ||
138 | /* ---- Unaligned access ------------------------------------ */ | ||
139 | |||
140 | /* parameter is supposed to be an uint32_t* ptr */ | ||
141 | #if defined(i386) || defined(__x86_64__) /* + other arches? */ | ||
142 | #define get_unaligned_u32p(u32p) (*(u32p)) | ||
143 | #else | ||
144 | /* performs reasonably well (gcc usually inlines memcpy here) */ | ||
145 | #define get_unaligned_u32p(u32p) ({ uint32_t __t; memcpy(&__t, (u32p), 4); __t; }) | ||
146 | #endif | ||
147 | |||
138 | /* ---- Networking ------------------------------------------ */ | 148 | /* ---- Networking ------------------------------------------ */ |
149 | |||
139 | #ifndef __APPLE__ | 150 | #ifndef __APPLE__ |
140 | # include <arpa/inet.h> | 151 | # include <arpa/inet.h> |
141 | # ifndef __socklen_t_defined | 152 | # ifndef __socklen_t_defined |
@@ -146,6 +157,7 @@ typedef int socklen_t; | |||
146 | #endif | 157 | #endif |
147 | 158 | ||
148 | /* ---- Compiler dependent settings ------------------------- */ | 159 | /* ---- Compiler dependent settings ------------------------- */ |
160 | |||
149 | #if (defined __digital__ && defined __unix__) || defined __APPLE__ | 161 | #if (defined __digital__ && defined __unix__) || defined __APPLE__ |
150 | # undef HAVE_MNTENT_H | 162 | # undef HAVE_MNTENT_H |
151 | # undef HAVE_SYS_STATFS_H | 163 | # undef HAVE_SYS_STATFS_H |
@@ -163,9 +175,10 @@ __extension__ typedef unsigned long long __u64; | |||
163 | #endif | 175 | #endif |
164 | 176 | ||
165 | /*----- Kernel versioning ------------------------------------*/ | 177 | /*----- Kernel versioning ------------------------------------*/ |
178 | |||
166 | #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) | 179 | #define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) |
167 | 180 | ||
168 | /* ---- miscellaneous --------------------------------------- */ | 181 | /* ---- Miscellaneous --------------------------------------- */ |
169 | 182 | ||
170 | #if defined(__GNU_LIBRARY__) && __GNU_LIBRARY__ < 5 && \ | 183 | #if defined(__GNU_LIBRARY__) && __GNU_LIBRARY__ < 5 && \ |
171 | !defined(__dietlibc__) && \ | 184 | !defined(__dietlibc__) && \ |
diff --git a/networking/udhcp/dhcpc.c b/networking/udhcp/dhcpc.c index fef8632f6..f1aa36fe6 100644 --- a/networking/udhcp/dhcpc.c +++ b/networking/udhcp/dhcpc.c | |||
@@ -18,9 +18,6 @@ | |||
18 | #include "options.h" | 18 | #include "options.h" |
19 | 19 | ||
20 | 20 | ||
21 | static int timeout; /* = 0. Must be signed */ | ||
22 | static uint32_t requested_ip; /* = 0 */ | ||
23 | static uint32_t server_addr; | ||
24 | static int sockfd = -1; | 21 | static int sockfd = -1; |
25 | 22 | ||
26 | #define LISTEN_NONE 0 | 23 | #define LISTEN_NONE 0 |
@@ -28,6 +25,14 @@ static int sockfd = -1; | |||
28 | #define LISTEN_RAW 2 | 25 | #define LISTEN_RAW 2 |
29 | static smallint listen_mode; | 26 | static smallint listen_mode; |
30 | 27 | ||
28 | #define INIT_SELECTING 0 | ||
29 | #define REQUESTING 1 | ||
30 | #define BOUND 2 | ||
31 | #define RENEWING 3 | ||
32 | #define REBINDING 4 | ||
33 | #define INIT_REBOOT 5 | ||
34 | #define RENEW_REQUESTED 6 | ||
35 | #define RELEASED 7 | ||
31 | static smallint state; | 36 | static smallint state; |
32 | 37 | ||
33 | /* struct client_config_t client_config is in bb_common_bufsiz1 */ | 38 | /* struct client_config_t client_config is in bb_common_bufsiz1 */ |
@@ -71,7 +76,7 @@ static void perform_renew(void) | |||
71 | 76 | ||
72 | 77 | ||
73 | /* perform a release */ | 78 | /* perform a release */ |
74 | static void perform_release(void) | 79 | static void perform_release(uint32_t requested_ip, uint32_t server_addr) |
75 | { | 80 | { |
76 | char buffer[sizeof("255.255.255.255")]; | 81 | char buffer[sizeof("255.255.255.255")]; |
77 | struct in_addr temp_addr; | 82 | struct in_addr temp_addr; |
@@ -90,7 +95,6 @@ static void perform_release(void) | |||
90 | 95 | ||
91 | change_listen_mode(LISTEN_NONE); | 96 | change_listen_mode(LISTEN_NONE); |
92 | state = RELEASED; | 97 | state = RELEASED; |
93 | timeout = INT_MAX; | ||
94 | } | 98 | } |
95 | 99 | ||
96 | 100 | ||
@@ -140,9 +144,12 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
140 | int tryagain_timeout = 20; | 144 | int tryagain_timeout = 20; |
141 | int discover_timeout = 3; | 145 | int discover_timeout = 3; |
142 | int discover_retries = 3; | 146 | int discover_retries = 3; |
147 | uint32_t server_addr = server_addr; /* for compiler */ | ||
148 | uint32_t requested_ip = 0; | ||
143 | uint32_t xid = 0; | 149 | uint32_t xid = 0; |
144 | uint32_t lease_seconds = 0; /* can be given as 32-bit quantity */ | 150 | uint32_t lease_seconds = 0; /* can be given as 32-bit quantity */ |
145 | int packet_num; | 151 | int packet_num; |
152 | int timeout; /* must be signed */ | ||
146 | unsigned already_waited_sec; | 153 | unsigned already_waited_sec; |
147 | unsigned opt; | 154 | unsigned opt; |
148 | int max_fd; | 155 | int max_fd; |
@@ -332,6 +339,7 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
332 | udhcp_run_script(NULL, "deconfig"); | 339 | udhcp_run_script(NULL, "deconfig"); |
333 | change_listen_mode(LISTEN_RAW); | 340 | change_listen_mode(LISTEN_RAW); |
334 | packet_num = 0; | 341 | packet_num = 0; |
342 | timeout = 0; | ||
335 | already_waited_sec = 0; | 343 | already_waited_sec = 0; |
336 | 344 | ||
337 | /* Main event loop. select() waits on signal pipe and possibly | 345 | /* Main event loop. select() waits on signal pipe and possibly |
@@ -510,8 +518,8 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
510 | continue; | 518 | continue; |
511 | /* still selecting - this server looks bad */ | 519 | /* still selecting - this server looks bad */ |
512 | } | 520 | } |
513 | /* can be misaligned, thus memcpy */ | 521 | /* it IS unaligned sometimes, don't "optimize" */ |
514 | memcpy(&server_addr, temp, 4); | 522 | server_addr = get_unaligned_u32p((uint32_t*)temp); |
515 | xid = packet.xid; | 523 | xid = packet.xid; |
516 | requested_ip = packet.yiaddr; | 524 | requested_ip = packet.yiaddr; |
517 | 525 | ||
@@ -535,7 +543,9 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
535 | /* can be misaligned, thus memcpy */ | 543 | /* can be misaligned, thus memcpy */ |
536 | memcpy(&lease_seconds, temp, 4); | 544 | memcpy(&lease_seconds, temp, 4); |
537 | lease_seconds = ntohl(lease_seconds); | 545 | lease_seconds = ntohl(lease_seconds); |
538 | lease_seconds &= 0x0fffffff; /* paranoia: must not be negative */ | 546 | lease_seconds &= 0x0fffffff; /* paranoia: must not be prone to overflows */ |
547 | if (lease_seconds < 10) /* and not too small */ | ||
548 | lease_seconds = 10; | ||
539 | } | 549 | } |
540 | #if ENABLE_FEATURE_UDHCPC_ARPING | 550 | #if ENABLE_FEATURE_UDHCPC_ARPING |
541 | if (opt & OPT_a) { | 551 | if (opt & OPT_a) { |
@@ -576,7 +586,7 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
576 | change_listen_mode(LISTEN_NONE); | 586 | change_listen_mode(LISTEN_NONE); |
577 | if (client_config.quit_after_lease) { | 587 | if (client_config.quit_after_lease) { |
578 | if (client_config.release_on_quit) | 588 | if (client_config.release_on_quit) |
579 | perform_release(); | 589 | perform_release(requested_ip, server_addr); |
580 | goto ret0; | 590 | goto ret0; |
581 | } | 591 | } |
582 | if (!client_config.foreground) | 592 | if (!client_config.foreground) |
@@ -618,12 +628,13 @@ int udhcpc_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
618 | timeout = 0; | 628 | timeout = 0; |
619 | break; | 629 | break; |
620 | case SIGUSR2: | 630 | case SIGUSR2: |
621 | perform_release(); | 631 | perform_release(requested_ip, server_addr); |
632 | timeout = INT_MAX; | ||
622 | break; | 633 | break; |
623 | case SIGTERM: | 634 | case SIGTERM: |
624 | bb_info_msg("Received SIGTERM"); | 635 | bb_info_msg("Received SIGTERM"); |
625 | if (client_config.release_on_quit) | 636 | if (client_config.release_on_quit) |
626 | perform_release(); | 637 | perform_release(requested_ip, server_addr); |
627 | goto ret0; | 638 | goto ret0; |
628 | } | 639 | } |
629 | } | 640 | } |
diff --git a/networking/udhcp/dhcpc.h b/networking/udhcp/dhcpc.h index 9331466e1..97d3b3c9d 100644 --- a/networking/udhcp/dhcpc.h +++ b/networking/udhcp/dhcpc.h | |||
@@ -8,15 +8,6 @@ | |||
8 | # pragma GCC visibility push(hidden) | 8 | # pragma GCC visibility push(hidden) |
9 | #endif | 9 | #endif |
10 | 10 | ||
11 | #define INIT_SELECTING 0 | ||
12 | #define REQUESTING 1 | ||
13 | #define BOUND 2 | ||
14 | #define RENEWING 3 | ||
15 | #define REBINDING 4 | ||
16 | #define INIT_REBOOT 5 | ||
17 | #define RENEW_REQUESTED 6 | ||
18 | #define RELEASED 7 | ||
19 | |||
20 | struct client_config_t { | 11 | struct client_config_t { |
21 | /* TODO: combine flag fields into single "unsigned opt" */ | 12 | /* TODO: combine flag fields into single "unsigned opt" */ |
22 | /* (can be set directly to the result of getopt32) */ | 13 | /* (can be set directly to the result of getopt32) */ |