diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-06-17 23:40:26 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-06-17 23:40:26 +0000 |
commit | bd7bb299c0e9ee5ff52c9d12b46fb14a907b34da (patch) | |
tree | 117a635e9457e1a932bc64941db5869e33179fc9 /networking/zcip.c | |
parent | 459be35234cc24b69309eb0ee22600024c73713e (diff) | |
download | busybox-w32-bd7bb299c0e9ee5ff52c9d12b46fb14a907b34da.tar.gz busybox-w32-bd7bb299c0e9ee5ff52c9d12b46fb14a907b34da.tar.bz2 busybox-w32-bd7bb299c0e9ee5ff52c9d12b46fb14a907b34da.zip |
wget: use monotonic_sec instead of gettimeofday
zcip: use monotonic_us instead of gettimeofday
udhcpcd: simpler, shorter random_xid()
function old new delta
monotonic_sec - 41 +41
find_pair 164 180 +16
run_list_real 2018 2028 +10
cmp_main 547 555 +8
collect_ctx 112 119 +7
singlemount 4544 4549 +5
time_main 1124 1128 +4
static.start_sec - 4 +4
static.lastupdate_sec - 4 +4
sock - 4 +4
read_package_field 253 257 +4
pick 38 40 +2
get_next_line 145 147 +2
count_lines 59 61 +2
process_stdin 435 433 -2
xstrtoul_range_sfx 229 226 -3
static.initialized 4 1 -3
dhcprelay_main 1125 1122 -3
catcher 380 377 -3
arping_main 1969 1966 -3
s 8 4 -4
cfg 4 - -4
static.lastupdate 8 - -8
start 8 - -8
random_xid 95 33 -62
.rodata 129114 129050 -64
zcip_main 1731 1576 -155
progressmeter 1035 867 -168
------------------------------------------------------------------------------
(add/remove: 4/3 grow/shrink: 10/11 up/down: 113/-490) Total: -377 bytes
Diffstat (limited to 'networking/zcip.c')
-rw-r--r-- | networking/zcip.c | 115 |
1 files changed, 53 insertions, 62 deletions
diff --git a/networking/zcip.c b/networking/zcip.c index eb0a7ba41..de4ee0b1a 100644 --- a/networking/zcip.c +++ b/networking/zcip.c | |||
@@ -23,7 +23,6 @@ | |||
23 | // - avoid silent script failures, especially under load... | 23 | // - avoid silent script failures, especially under load... |
24 | // - link status monitoring (restart on link-up; stop on link-down) | 24 | // - link status monitoring (restart on link-up; stop on link-down) |
25 | 25 | ||
26 | #include "libbb.h" | ||
27 | #include <syslog.h> | 26 | #include <syslog.h> |
28 | #include <poll.h> | 27 | #include <poll.h> |
29 | #include <sys/wait.h> | 28 | #include <sys/wait.h> |
@@ -31,10 +30,13 @@ | |||
31 | #include <net/ethernet.h> | 30 | #include <net/ethernet.h> |
32 | #include <net/if.h> | 31 | #include <net/if.h> |
33 | #include <net/if_arp.h> | 32 | #include <net/if_arp.h> |
34 | |||
35 | #include <linux/if_packet.h> | 33 | #include <linux/if_packet.h> |
36 | #include <linux/sockios.h> | 34 | #include <linux/sockios.h> |
37 | 35 | ||
36 | #include "libbb.h" | ||
37 | |||
38 | /* We don't need more than 32 bits of the counter */ | ||
39 | #define MONOTONIC_US() ((unsigned)monotonic_us()) | ||
38 | 40 | ||
39 | struct arp_packet { | 41 | struct arp_packet { |
40 | struct ether_header hdr; | 42 | struct ether_header hdr; |
@@ -78,15 +80,12 @@ static void pick(struct in_addr *ip) | |||
78 | { | 80 | { |
79 | unsigned tmp; | 81 | unsigned tmp; |
80 | 82 | ||
81 | /* use cheaper math than lrand48() mod N */ | ||
82 | do { | 83 | do { |
83 | tmp = (lrand48() >> 16) & IN_CLASSB_HOST; | 84 | tmp = rand() & IN_CLASSB_HOST; |
84 | } while (tmp > (IN_CLASSB_HOST - 0x0200)); | 85 | } while (tmp > (IN_CLASSB_HOST - 0x0200)); |
85 | ip->s_addr = htonl((LINKLOCAL_ADDR + 0x0100) + tmp); | 86 | ip->s_addr = htonl((LINKLOCAL_ADDR + 0x0100) + tmp); |
86 | } | 87 | } |
87 | 88 | ||
88 | /* TODO: we need a flag to direct bb_[p]error_msg output to stderr. */ | ||
89 | |||
90 | /** | 89 | /** |
91 | * Broadcast an ARP packet. | 90 | * Broadcast an ARP packet. |
92 | */ | 91 | */ |
@@ -151,7 +150,7 @@ static int run(char *argv[3], const char *intf, struct in_addr *ip) | |||
151 | */ | 150 | */ |
152 | static unsigned ALWAYS_INLINE ms_rdelay(unsigned secs) | 151 | static unsigned ALWAYS_INLINE ms_rdelay(unsigned secs) |
153 | { | 152 | { |
154 | return lrand48() % (secs * 1000); | 153 | return rand() % (secs * 1000); |
155 | } | 154 | } |
156 | 155 | ||
157 | /** | 156 | /** |
@@ -176,29 +175,31 @@ int zcip_main(int argc, char **argv) | |||
176 | struct ifreq ifr; | 175 | struct ifreq ifr; |
177 | char *intf; | 176 | char *intf; |
178 | char *script_av[3]; | 177 | char *script_av[3]; |
179 | suseconds_t timeout; // milliseconds | 178 | int timeout_ms; /* must be signed */ |
180 | unsigned conflicts; | 179 | unsigned conflicts; |
181 | unsigned nprobes; | 180 | unsigned nprobes; |
182 | unsigned nclaims; | 181 | unsigned nclaims; |
183 | int ready; | 182 | int ready; |
184 | int verbose; | 183 | int verbose; |
185 | } L; | 184 | } L; |
186 | #define null_ip (L.null_ip ) | 185 | #define null_ip (L.null_ip ) |
187 | #define null_addr (L.null_addr) | 186 | #define null_addr (L.null_addr ) |
188 | #define saddr (L.saddr ) | 187 | #define saddr (L.saddr ) |
189 | #define ip (L.ip ) | 188 | #define ip (L.ip ) |
190 | #define ifr (L.ifr ) | 189 | #define ifr (L.ifr ) |
191 | #define intf (L.intf ) | 190 | #define intf (L.intf ) |
192 | #define script_av (L.script_av) | 191 | #define script_av (L.script_av ) |
193 | #define timeout (L.timeout ) | 192 | #define timeout_ms (L.timeout_ms) |
194 | #define conflicts (L.conflicts) | 193 | #define conflicts (L.conflicts ) |
195 | #define nprobes (L.nprobes ) | 194 | #define nprobes (L.nprobes ) |
196 | #define nclaims (L.nclaims ) | 195 | #define nclaims (L.nclaims ) |
197 | #define ready (L.ready ) | 196 | #define ready (L.ready ) |
198 | #define verbose (L.verbose ) | 197 | #define verbose (L.verbose ) |
199 | 198 | ||
200 | memset(&L, 0, sizeof(L)); | 199 | memset(&L, 0, sizeof(L)); |
201 | 200 | ||
201 | srand(MONOTONIC_US()); | ||
202 | |||
202 | #define FOREGROUND (opts & 1) | 203 | #define FOREGROUND (opts & 1) |
203 | #define QUIT (opts & 2) | 204 | #define QUIT (opts & 2) |
204 | // parse commandline: prog [options] ifname script | 205 | // parse commandline: prog [options] ifname script |
@@ -282,7 +283,7 @@ int zcip_main(int argc, char **argv) | |||
282 | // - defend it, within limits | 283 | // - defend it, within limits |
283 | while (1) { | 284 | while (1) { |
284 | struct pollfd fds[1]; | 285 | struct pollfd fds[1]; |
285 | struct timeval tv1; | 286 | unsigned deadline_us; |
286 | struct arp_packet p; | 287 | struct arp_packet p; |
287 | 288 | ||
288 | int source_ip_conflict = 0; | 289 | int source_ip_conflict = 0; |
@@ -293,24 +294,18 @@ int zcip_main(int argc, char **argv) | |||
293 | fds[0].revents = 0; | 294 | fds[0].revents = 0; |
294 | 295 | ||
295 | // poll, being ready to adjust current timeout | 296 | // poll, being ready to adjust current timeout |
296 | if (!timeout) { | 297 | if (!timeout_ms) { |
297 | timeout = ms_rdelay(PROBE_WAIT); | 298 | timeout_ms = ms_rdelay(PROBE_WAIT); |
298 | // FIXME setsockopt(fd, SO_ATTACH_FILTER, ...) to | 299 | // FIXME setsockopt(fd, SO_ATTACH_FILTER, ...) to |
299 | // make the kernel filter out all packets except | 300 | // make the kernel filter out all packets except |
300 | // ones we'd care about. | 301 | // ones we'd care about. |
301 | } | 302 | } |
302 | // set tv1 to the point in time when we timeout | 303 | // set deadline_us to the point in time when we timeout |
303 | gettimeofday(&tv1, NULL); | 304 | deadline_us = MONOTONIC_US() + timeout_ms * 1000; |
304 | tv1.tv_usec += (timeout % 1000) * 1000; | ||
305 | while (tv1.tv_usec > 1000000) { | ||
306 | tv1.tv_usec -= 1000000; | ||
307 | tv1.tv_sec++; | ||
308 | } | ||
309 | tv1.tv_sec += timeout / 1000; | ||
310 | 305 | ||
311 | VDBG("...wait %ld %s nprobes=%d, nclaims=%d\n", | 306 | VDBG("...wait %d %s nprobes=%u, nclaims=%u\n", |
312 | timeout, intf, nprobes, nclaims); | 307 | timeout_ms, intf, nprobes, nclaims); |
313 | switch (poll(fds, 1, timeout)) { | 308 | switch (poll(fds, 1, timeout_ms)) { |
314 | 309 | ||
315 | // timeout | 310 | // timeout |
316 | case 0: | 311 | case 0: |
@@ -321,25 +316,24 @@ int zcip_main(int argc, char **argv) | |||
321 | // have been received, so we can progress through the states | 316 | // have been received, so we can progress through the states |
322 | if (nprobes < PROBE_NUM) { | 317 | if (nprobes < PROBE_NUM) { |
323 | nprobes++; | 318 | nprobes++; |
324 | VDBG("probe/%d %s@%s\n", | 319 | VDBG("probe/%u %s@%s\n", |
325 | nprobes, intf, inet_ntoa(ip)); | 320 | nprobes, intf, inet_ntoa(ip)); |
326 | arp(fd, &saddr, ARPOP_REQUEST, | 321 | arp(fd, &saddr, ARPOP_REQUEST, |
327 | ð_addr, null_ip, | 322 | ð_addr, null_ip, |
328 | &null_addr, ip); | 323 | &null_addr, ip); |
329 | timeout = PROBE_MIN * 1000; | 324 | timeout_ms = PROBE_MIN * 1000; |
330 | timeout += ms_rdelay(PROBE_MAX | 325 | timeout_ms += ms_rdelay(PROBE_MAX - PROBE_MIN); |
331 | - PROBE_MIN); | ||
332 | } | 326 | } |
333 | else { | 327 | else { |
334 | // Switch to announce state. | 328 | // Switch to announce state. |
335 | state = ANNOUNCE; | 329 | state = ANNOUNCE; |
336 | nclaims = 0; | 330 | nclaims = 0; |
337 | VDBG("announce/%d %s@%s\n", | 331 | VDBG("announce/%u %s@%s\n", |
338 | nclaims, intf, inet_ntoa(ip)); | 332 | nclaims, intf, inet_ntoa(ip)); |
339 | arp(fd, &saddr, ARPOP_REQUEST, | 333 | arp(fd, &saddr, ARPOP_REQUEST, |
340 | ð_addr, ip, | 334 | ð_addr, ip, |
341 | ð_addr, ip); | 335 | ð_addr, ip); |
342 | timeout = ANNOUNCE_INTERVAL * 1000; | 336 | timeout_ms = ANNOUNCE_INTERVAL * 1000; |
343 | } | 337 | } |
344 | break; | 338 | break; |
345 | case RATE_LIMIT_PROBE: | 339 | case RATE_LIMIT_PROBE: |
@@ -347,24 +341,24 @@ int zcip_main(int argc, char **argv) | |||
347 | // have been received, so we can move immediately to the announce state | 341 | // have been received, so we can move immediately to the announce state |
348 | state = ANNOUNCE; | 342 | state = ANNOUNCE; |
349 | nclaims = 0; | 343 | nclaims = 0; |
350 | VDBG("announce/%d %s@%s\n", | 344 | VDBG("announce/%u %s@%s\n", |
351 | nclaims, intf, inet_ntoa(ip)); | 345 | nclaims, intf, inet_ntoa(ip)); |
352 | arp(fd, &saddr, ARPOP_REQUEST, | 346 | arp(fd, &saddr, ARPOP_REQUEST, |
353 | ð_addr, ip, | 347 | ð_addr, ip, |
354 | ð_addr, ip); | 348 | ð_addr, ip); |
355 | timeout = ANNOUNCE_INTERVAL * 1000; | 349 | timeout_ms = ANNOUNCE_INTERVAL * 1000; |
356 | break; | 350 | break; |
357 | case ANNOUNCE: | 351 | case ANNOUNCE: |
358 | // timeouts in the ANNOUNCE state mean no conflicting ARP packets | 352 | // timeouts in the ANNOUNCE state mean no conflicting ARP packets |
359 | // have been received, so we can progress through the states | 353 | // have been received, so we can progress through the states |
360 | if (nclaims < ANNOUNCE_NUM) { | 354 | if (nclaims < ANNOUNCE_NUM) { |
361 | nclaims++; | 355 | nclaims++; |
362 | VDBG("announce/%d %s@%s\n", | 356 | VDBG("announce/%u %s@%s\n", |
363 | nclaims, intf, inet_ntoa(ip)); | 357 | nclaims, intf, inet_ntoa(ip)); |
364 | arp(fd, &saddr, ARPOP_REQUEST, | 358 | arp(fd, &saddr, ARPOP_REQUEST, |
365 | ð_addr, ip, | 359 | ð_addr, ip, |
366 | ð_addr, ip); | 360 | ð_addr, ip); |
367 | timeout = ANNOUNCE_INTERVAL * 1000; | 361 | timeout_ms = ANNOUNCE_INTERVAL * 1000; |
368 | } | 362 | } |
369 | else { | 363 | else { |
370 | // Switch to monitor state. | 364 | // Switch to monitor state. |
@@ -375,7 +369,7 @@ int zcip_main(int argc, char **argv) | |||
375 | run(script_av, intf, &ip); | 369 | run(script_av, intf, &ip); |
376 | ready = 1; | 370 | ready = 1; |
377 | conflicts = 0; | 371 | conflicts = 0; |
378 | timeout = -1; // Never timeout in the monitor state. | 372 | timeout_ms = -1; // Never timeout in the monitor state. |
379 | 373 | ||
380 | // NOTE: all other exit paths | 374 | // NOTE: all other exit paths |
381 | // should deconfig ... | 375 | // should deconfig ... |
@@ -386,14 +380,14 @@ int zcip_main(int argc, char **argv) | |||
386 | case DEFEND: | 380 | case DEFEND: |
387 | // We won! No ARP replies, so just go back to monitor. | 381 | // We won! No ARP replies, so just go back to monitor. |
388 | state = MONITOR; | 382 | state = MONITOR; |
389 | timeout = -1; | 383 | timeout_ms = -1; |
390 | conflicts = 0; | 384 | conflicts = 0; |
391 | break; | 385 | break; |
392 | default: | 386 | default: |
393 | // Invalid, should never happen. Restart the whole protocol. | 387 | // Invalid, should never happen. Restart the whole protocol. |
394 | state = PROBE; | 388 | state = PROBE; |
395 | pick(&ip); | 389 | pick(&ip); |
396 | timeout = 0; | 390 | timeout_ms = 0; |
397 | nprobes = 0; | 391 | nprobes = 0; |
398 | nclaims = 0; | 392 | nclaims = 0; |
399 | break; | 393 | break; |
@@ -403,20 +397,17 @@ int zcip_main(int argc, char **argv) | |||
403 | case 1: | 397 | case 1: |
404 | // We need to adjust the timeout in case we didn't receive | 398 | // We need to adjust the timeout in case we didn't receive |
405 | // a conflicting packet. | 399 | // a conflicting packet. |
406 | if (timeout > 0) { | 400 | if (timeout_ms > 0) { |
407 | struct timeval tv2; | 401 | unsigned diff = deadline_us - MONOTONIC_US(); |
408 | 402 | if ((int)(diff) < 0) { | |
409 | gettimeofday(&tv2, NULL); | ||
410 | if (timercmp(&tv1, &tv2, <)) { | ||
411 | // Current time is greater than the expected timeout time. | 403 | // Current time is greater than the expected timeout time. |
412 | // Should never happen. | 404 | // Should never happen. |
413 | VDBG("missed an expected timeout\n"); | 405 | VDBG("missed an expected timeout\n"); |
414 | timeout = 0; | 406 | timeout_ms = 0; |
415 | } else { | 407 | } else { |
416 | VDBG("adjusting timeout\n"); | 408 | VDBG("adjusting timeout\n"); |
417 | timersub(&tv1, &tv2, &tv1); | 409 | timeout_ms = diff / 1000; |
418 | timeout = 1000 * tv1.tv_sec | 410 | if (!timeout_ms) timeout_ms = 1; |
419 | + tv1.tv_usec / 1000; | ||
420 | } | 411 | } |
421 | } | 412 | } |
422 | 413 | ||
@@ -484,13 +475,13 @@ int zcip_main(int argc, char **argv) | |||
484 | conflicts++; | 475 | conflicts++; |
485 | if (conflicts >= MAX_CONFLICTS) { | 476 | if (conflicts >= MAX_CONFLICTS) { |
486 | VDBG("%s ratelimit\n", intf); | 477 | VDBG("%s ratelimit\n", intf); |
487 | timeout = RATE_LIMIT_INTERVAL * 1000; | 478 | timeout_ms = RATE_LIMIT_INTERVAL * 1000; |
488 | state = RATE_LIMIT_PROBE; | 479 | state = RATE_LIMIT_PROBE; |
489 | } | 480 | } |
490 | 481 | ||
491 | // restart the whole protocol | 482 | // restart the whole protocol |
492 | pick(&ip); | 483 | pick(&ip); |
493 | timeout = 0; | 484 | timeout_ms = 0; |
494 | nprobes = 0; | 485 | nprobes = 0; |
495 | nclaims = 0; | 486 | nclaims = 0; |
496 | } | 487 | } |
@@ -500,7 +491,7 @@ int zcip_main(int argc, char **argv) | |||
500 | if (source_ip_conflict) { | 491 | if (source_ip_conflict) { |
501 | VDBG("monitor conflict -- defending\n"); | 492 | VDBG("monitor conflict -- defending\n"); |
502 | state = DEFEND; | 493 | state = DEFEND; |
503 | timeout = DEFEND_INTERVAL * 1000; | 494 | timeout_ms = DEFEND_INTERVAL * 1000; |
504 | arp(fd, &saddr, | 495 | arp(fd, &saddr, |
505 | ARPOP_REQUEST, | 496 | ARPOP_REQUEST, |
506 | ð_addr, ip, | 497 | ð_addr, ip, |
@@ -518,7 +509,7 @@ int zcip_main(int argc, char **argv) | |||
518 | 509 | ||
519 | // restart the whole protocol | 510 | // restart the whole protocol |
520 | pick(&ip); | 511 | pick(&ip); |
521 | timeout = 0; | 512 | timeout_ms = 0; |
522 | nprobes = 0; | 513 | nprobes = 0; |
523 | nclaims = 0; | 514 | nclaims = 0; |
524 | } | 515 | } |
@@ -528,7 +519,7 @@ int zcip_main(int argc, char **argv) | |||
528 | VDBG("invalid state -- starting over\n"); | 519 | VDBG("invalid state -- starting over\n"); |
529 | state = PROBE; | 520 | state = PROBE; |
530 | pick(&ip); | 521 | pick(&ip); |
531 | timeout = 0; | 522 | timeout_ms = 0; |
532 | nprobes = 0; | 523 | nprobes = 0; |
533 | nclaims = 0; | 524 | nclaims = 0; |
534 | break; | 525 | break; |