diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2015-08-04 12:28:21 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2015-08-04 12:28:21 +0200 |
commit | 99e30be38bc167a3b5729154a27ccdb15bbaadb2 (patch) | |
tree | e66c9e2df659f1810c8faf38aef071156dec9eb4 | |
parent | 16aa7a73c40ba5dfaabaedb8a5533619cb8b6cb6 (diff) | |
download | busybox-w32-99e30be38bc167a3b5729154a27ccdb15bbaadb2.tar.gz busybox-w32-99e30be38bc167a3b5729154a27ccdb15bbaadb2.tar.bz2 busybox-w32-99e30be38bc167a3b5729154a27ccdb15bbaadb2.zip |
zcip: code shrink
function old new delta
zcip_main 1263 1230 -33
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | networking/zcip.c | 137 |
1 files changed, 59 insertions, 78 deletions
diff --git a/networking/zcip.c b/networking/zcip.c index 69644b230..5877a8317 100644 --- a/networking/zcip.c +++ b/networking/zcip.c | |||
@@ -215,19 +215,17 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
215 | const struct ether_addr null_addr; | 215 | const struct ether_addr null_addr; |
216 | struct ifreq ifr; | 216 | struct ifreq ifr; |
217 | uint32_t chosen_nip; | 217 | uint32_t chosen_nip; |
218 | int timeout_ms; /* must be signed */ | 218 | int timeout_ms; // must be signed |
219 | unsigned conflicts; | 219 | unsigned conflicts; |
220 | unsigned nprobes; | 220 | unsigned nsent; |
221 | unsigned nclaims; | ||
222 | int verbose; | 221 | int verbose; |
223 | } L; | 222 | } L; |
224 | #define null_addr (L.null_addr ) | 223 | #define null_addr (L.null_addr ) |
225 | #define chosen_nip (L.chosen_nip) | ||
226 | #define ifr (L.ifr ) | 224 | #define ifr (L.ifr ) |
225 | #define chosen_nip (L.chosen_nip) | ||
227 | #define timeout_ms (L.timeout_ms) | 226 | #define timeout_ms (L.timeout_ms) |
228 | #define conflicts (L.conflicts ) | 227 | #define conflicts (L.conflicts ) |
229 | #define nprobes (L.nprobes ) | 228 | #define nsent (L.nsent ) |
230 | #define nclaims (L.nclaims ) | ||
231 | #define verbose (L.verbose ) | 229 | #define verbose (L.verbose ) |
232 | 230 | ||
233 | memset(&L, 0, sizeof(L)); | 231 | memset(&L, 0, sizeof(L)); |
@@ -351,8 +349,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
351 | struct pollfd fds[1]; | 349 | struct pollfd fds[1]; |
352 | unsigned deadline_us; | 350 | unsigned deadline_us; |
353 | struct arp_packet p; | 351 | struct arp_packet p; |
354 | int source_ip_conflict; | 352 | int ip_conflict; |
355 | int target_ip_conflict; | ||
356 | 353 | ||
357 | fds[0].fd = sock_fd; | 354 | fds[0].fd = sock_fd; |
358 | fds[0].events = POLLIN; | 355 | fds[0].events = POLLIN; |
@@ -368,8 +365,8 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
368 | // set deadline_us to the point in time when we timeout | 365 | // set deadline_us to the point in time when we timeout |
369 | deadline_us = MONOTONIC_US() + timeout_ms * 1000; | 366 | deadline_us = MONOTONIC_US() + timeout_ms * 1000; |
370 | 367 | ||
371 | VDBG("...wait %d %s nprobes=%u, nclaims=%u\n", | 368 | VDBG("...wait %d %s nsent=%u\n", |
372 | timeout_ms, argv_intf, nprobes, nclaims); | 369 | timeout_ms, argv_intf, nsent); |
373 | 370 | ||
374 | switch (safe_poll(fds, 1, timeout_ms)) { | 371 | switch (safe_poll(fds, 1, timeout_ms)) { |
375 | 372 | ||
@@ -384,10 +381,10 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
384 | case PROBE: | 381 | case PROBE: |
385 | // timeouts in the PROBE state mean no conflicting ARP packets | 382 | // timeouts in the PROBE state mean no conflicting ARP packets |
386 | // have been received, so we can progress through the states | 383 | // have been received, so we can progress through the states |
387 | if (nprobes < PROBE_NUM) { | 384 | if (nsent < PROBE_NUM) { |
388 | nprobes++; | 385 | nsent++; |
389 | VDBG("probe/%u %s@%s\n", | 386 | VDBG("probe/%u %s@%s\n", |
390 | nprobes, argv_intf, nip_to_a(chosen_nip)); | 387 | nsent, argv_intf, nip_to_a(chosen_nip)); |
391 | timeout_ms = PROBE_MIN * 1000; | 388 | timeout_ms = PROBE_MIN * 1000; |
392 | timeout_ms += random_delay_ms(PROBE_MAX - PROBE_MIN); | 389 | timeout_ms += random_delay_ms(PROBE_MAX - PROBE_MIN); |
393 | arp(/* ARPOP_REQUEST, */ | 390 | arp(/* ARPOP_REQUEST, */ |
@@ -395,25 +392,25 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
395 | &null_addr, chosen_nip); | 392 | &null_addr, chosen_nip); |
396 | break; | 393 | break; |
397 | } | 394 | } |
398 | // Switch to announce state. | 395 | // Switch to announce state |
399 | nclaims = 0; | 396 | nsent = 0; |
400 | state = ANNOUNCE; | 397 | state = ANNOUNCE; |
401 | goto send_announce; | 398 | goto send_announce; |
402 | case ANNOUNCE: | 399 | case ANNOUNCE: |
403 | // timeouts in the ANNOUNCE state mean no conflicting ARP packets | 400 | // timeouts in the ANNOUNCE state mean no conflicting ARP packets |
404 | // have been received, so we can progress through the states | 401 | // have been received, so we can progress through the states |
405 | if (nclaims < ANNOUNCE_NUM) { | 402 | if (nsent < ANNOUNCE_NUM) { |
406 | send_announce: | 403 | send_announce: |
407 | nclaims++; | 404 | nsent++; |
408 | VDBG("announce/%u %s@%s\n", | 405 | VDBG("announce/%u %s@%s\n", |
409 | nclaims, argv_intf, nip_to_a(chosen_nip)); | 406 | nsent, argv_intf, nip_to_a(chosen_nip)); |
410 | timeout_ms = ANNOUNCE_INTERVAL * 1000; | 407 | timeout_ms = ANNOUNCE_INTERVAL * 1000; |
411 | arp(/* ARPOP_REQUEST, */ | 408 | arp(/* ARPOP_REQUEST, */ |
412 | /* &G.eth_addr, */ chosen_nip, | 409 | /* &G.eth_addr, */ chosen_nip, |
413 | &G.eth_addr, chosen_nip); | 410 | &G.eth_addr, chosen_nip); |
414 | break; | 411 | break; |
415 | } | 412 | } |
416 | // Switch to monitor state. | 413 | // Switch to monitor state |
417 | // FIXME update filters | 414 | // FIXME update filters |
418 | run(argv, "config", chosen_nip); | 415 | run(argv, "config", chosen_nip); |
419 | // NOTE: all other exit paths should deconfig... | 416 | // NOTE: all other exit paths should deconfig... |
@@ -424,7 +421,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
424 | state = MONITOR; | 421 | state = MONITOR; |
425 | break; | 422 | break; |
426 | case DEFEND: | 423 | case DEFEND: |
427 | // Defend period ended with no ARP replies - we won. | 424 | // Defend period ended with no ARP replies - we won |
428 | conflicts = 0; | 425 | conflicts = 0; |
429 | timeout_ms = -1; | 426 | timeout_ms = -1; |
430 | state = MONITOR; | 427 | state = MONITOR; |
@@ -443,7 +440,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
443 | diff = 0; | 440 | diff = 0; |
444 | } | 441 | } |
445 | VDBG("adjusting timeout\n"); | 442 | VDBG("adjusting timeout\n"); |
446 | timeout_ms = (diff / 1000) | 1; /* never 0 */ | 443 | timeout_ms = (diff / 1000) | 1; // never 0 |
447 | } | 444 | } |
448 | 445 | ||
449 | if ((fds[0].revents & POLLIN) == 0) { | 446 | if ((fds[0].revents & POLLIN) == 0) { |
@@ -452,7 +449,7 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
452 | // this shouldn't necessarily exit. | 449 | // this shouldn't necessarily exit. |
453 | bb_error_msg("iface %s is down", argv_intf); | 450 | bb_error_msg("iface %s is down", argv_intf); |
454 | if (state >= MONITOR) { | 451 | if (state >= MONITOR) { |
455 | /* only if we are in MONITOR or DEFEND */ | 452 | // only if we are in MONITOR or DEFEND |
456 | run(argv, "deconfig", chosen_nip); | 453 | run(argv, "deconfig", chosen_nip); |
457 | } | 454 | } |
458 | return EXIT_FAILURE; | 455 | return EXIT_FAILURE; |
@@ -478,81 +475,65 @@ int zcip_main(int argc UNUSED_PARAM, char **argv) | |||
478 | struct ether_addr *tha = (struct ether_addr *) p.arp.arp_tha; | 475 | struct ether_addr *tha = (struct ether_addr *) p.arp.arp_tha; |
479 | struct in_addr *spa = (struct in_addr *) p.arp.arp_spa; | 476 | struct in_addr *spa = (struct in_addr *) p.arp.arp_spa; |
480 | struct in_addr *tpa = (struct in_addr *) p.arp.arp_tpa; | 477 | struct in_addr *tpa = (struct in_addr *) p.arp.arp_tpa; |
481 | VDBG("%s recv arp type=%d, op=%d,\n", | 478 | VDBG("source=%s %s\n", ether_ntoa(sha), inet_ntoa(*spa)); |
482 | argv_intf, ntohs(p.eth.ether_type), | 479 | VDBG("target=%s %s\n", ether_ntoa(tha), inet_ntoa(*tpa)); |
483 | ntohs(p.arp.arp_op)); | ||
484 | VDBG("\tsource=%s %s\n", | ||
485 | ether_ntoa(sha), | ||
486 | inet_ntoa(*spa)); | ||
487 | VDBG("\ttarget=%s %s\n", | ||
488 | ether_ntoa(tha), | ||
489 | inet_ntoa(*tpa)); | ||
490 | } | 480 | } |
491 | #endif | 481 | #endif |
492 | source_ip_conflict = 0; | 482 | ip_conflict = 0; |
493 | target_ip_conflict = 0; | ||
494 | |||
495 | if (memcmp(&p.arp.arp_sha, &G.eth_addr, ETH_ALEN) != 0) { | 483 | if (memcmp(&p.arp.arp_sha, &G.eth_addr, ETH_ALEN) != 0) { |
496 | if (memcmp(p.arp.arp_spa, &chosen_nip, 4) == 0) { | 484 | if (memcmp(p.arp.arp_spa, &chosen_nip, 4) == 0) { |
497 | /* A probe or reply with source_ip == chosen ip */ | 485 | // A probe or reply with source_ip == chosen ip |
498 | source_ip_conflict = 1; | 486 | ip_conflict = 1; |
499 | } | 487 | } |
500 | if (p.arp.arp_op == htons(ARPOP_REQUEST) | 488 | if (p.arp.arp_op == htons(ARPOP_REQUEST) |
501 | && memcmp(p.arp.arp_spa, &const_int_0, 4) == 0 | 489 | && memcmp(p.arp.arp_spa, &const_int_0, 4) == 0 |
502 | && memcmp(p.arp.arp_tpa, &chosen_nip, 4) == 0 | 490 | && memcmp(p.arp.arp_tpa, &chosen_nip, 4) == 0 |
503 | ) { | 491 | ) { |
504 | /* A probe with source_ip == 0.0.0.0, target_ip == chosen ip: | 492 | // A probe with source_ip == 0.0.0.0, target_ip == chosen ip: |
505 | * another host trying to claim this ip! | 493 | // another host trying to claim this ip! |
506 | */ | 494 | ip_conflict |= 2; |
507 | target_ip_conflict = 1; | ||
508 | } | 495 | } |
509 | } | 496 | } |
497 | VDBG("state:%d ip_conflict:%d\n", state, ip_conflict); | ||
498 | if (!ip_conflict) | ||
499 | break; | ||
510 | 500 | ||
511 | VDBG("state = %d, source ip conflict = %d, target ip conflict = %d\n", | 501 | // Either src or target IP conflict exists |
512 | state, source_ip_conflict, target_ip_conflict); | 502 | if (state <= ANNOUNCE) { |
513 | switch (state) { | 503 | // PROBE or ANNOUNCE |
514 | case PROBE: | 504 | conflicts++; |
515 | case ANNOUNCE: | 505 | timeout_ms = PROBE_MIN * 1000 |
516 | // When probing or announcing, check for source IP conflicts | 506 | + CONFLICT_MULTIPLIER * random_delay_ms(conflicts); |
517 | // and other hosts doing ARP probes (target IP conflicts). | 507 | chosen_nip = pick_nip(); |
518 | if (source_ip_conflict || target_ip_conflict) { | 508 | nsent = 0; |
519 | conflicts++; | 509 | state = PROBE; |
520 | timeout_ms = PROBE_MIN * 1000 | ||
521 | + CONFLICT_MULTIPLIER * random_delay_ms(conflicts); | ||
522 | chosen_nip = pick_nip(); | ||
523 | nprobes = 0; | ||
524 | nclaims = 0; | ||
525 | state = PROBE; | ||
526 | } | ||
527 | break; | 510 | break; |
528 | case MONITOR: | 511 | } |
529 | // If a conflict, we try to defend with a single ARP probe. | 512 | // MONITOR or DEFEND: only src IP conflict is a problem |
530 | if (source_ip_conflict) { | 513 | if (ip_conflict & 1) { |
531 | VDBG("monitor conflict -- defending\n"); | 514 | if (state == MONITOR) { |
515 | // Src IP conflict, defend with a single ARP probe | ||
516 | VDBG("monitor conflict - defending\n"); | ||
532 | timeout_ms = DEFEND_INTERVAL * 1000; | 517 | timeout_ms = DEFEND_INTERVAL * 1000; |
533 | state = DEFEND; | 518 | state = DEFEND; |
534 | arp(/* ARPOP_REQUEST, */ | 519 | arp(/* ARPOP_REQUEST, */ |
535 | /* &G.eth_addr, */ chosen_nip, | 520 | /* &G.eth_addr, */ chosen_nip, |
536 | &G.eth_addr, chosen_nip); | 521 | &G.eth_addr, chosen_nip); |
522 | break; | ||
537 | } | 523 | } |
538 | break; | 524 | // state == DEFEND |
539 | case DEFEND: | 525 | // Another src IP conflict, start over |
540 | // Well, we tried. Start over (on conflict). | 526 | VDBG("defend conflict - starting over\n"); |
541 | if (source_ip_conflict) { | 527 | run(argv, "deconfig", chosen_nip); |
542 | VDBG("defend conflict -- starting over\n"); | 528 | |
543 | run(argv, "deconfig", chosen_nip); | 529 | // restart the whole protocol |
544 | 530 | timeout_ms = 0; | |
545 | // restart the whole protocol | 531 | chosen_nip = pick_nip(); |
546 | timeout_ms = 0; | 532 | nsent = 0; |
547 | chosen_nip = pick_nip(); | 533 | state = PROBE; |
548 | nprobes = 0; | 534 | } |
549 | nclaims = 0; | 535 | break; // case 1 (packet arrived) |
550 | state = PROBE; | 536 | } // switch (poll) |
551 | } | ||
552 | break; | ||
553 | } // switch state | ||
554 | break; // case 1 (packets arriving) | ||
555 | } // switch poll | ||
556 | } // while (1) | 537 | } // while (1) |
557 | #undef argv_intf | 538 | #undef argv_intf |
558 | } | 539 | } |