aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2015-08-04 03:27:56 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2015-08-04 03:27:56 +0200
commit16aa7a73c40ba5dfaabaedb8a5533619cb8b6cb6 (patch)
tree1f02082e54b6e7a43bbfb0fee087fedcd272e23a
parent64ed5f0d3c5eefbb208d4a334654834c78be2cbd (diff)
downloadbusybox-w32-16aa7a73c40ba5dfaabaedb8a5533619cb8b6cb6.tar.gz
busybox-w32-16aa7a73c40ba5dfaabaedb8a5533619cb8b6cb6.tar.bz2
busybox-w32-16aa7a73c40ba5dfaabaedb8a5533619cb8b6cb6.zip
zcip: simplify code
function old new delta zcip_main 1411 1263 -148 Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/zcip.c235
1 files changed, 96 insertions, 139 deletions
diff --git a/networking/zcip.c b/networking/zcip.c
index 962ba2e60..69644b230 100644
--- a/networking/zcip.c
+++ b/networking/zcip.c
@@ -56,26 +56,26 @@ struct arp_packet {
56} PACKED; 56} PACKED;
57 57
58enum { 58enum {
59/* 169.254.0.0 */ 59 /* 169.254.0.0 */
60 LINKLOCAL_ADDR = 0xa9fe0000, 60 LINKLOCAL_ADDR = 0xa9fe0000,
61 61
62/* protocol timeout parameters, specified in seconds */ 62 /* 0-1 seconds before sending 1st probe */
63 PROBE_WAIT = 1, 63 PROBE_WAIT = 1,
64 /* 1-2 seconds between probes */
64 PROBE_MIN = 1, 65 PROBE_MIN = 1,
65 PROBE_MAX = 2, 66 PROBE_MAX = 2,
66 PROBE_NUM = 3, 67 PROBE_NUM = 3, /* total probes to send */
67 MAX_CONFLICTS = 10, 68 ANNOUNCE_INTERVAL = 2, /* 2 seconds between announces */
68 RATE_LIMIT_INTERVAL = 60, 69 ANNOUNCE_NUM = 3, /* announces to send */
69 ANNOUNCE_WAIT = 2, 70 /* if probe/announce sees a conflict, multiply RANDOM(NUM_CONFLICT) by... */
70 ANNOUNCE_NUM = 2, 71 CONFLICT_MULTIPLIER = 2,
71 ANNOUNCE_INTERVAL = 2, 72 /* if we monitor and see a conflict, how long is defend state? */
72 DEFEND_INTERVAL = 10 73 DEFEND_INTERVAL = 10
73}; 74};
74 75
75/* States during the configuration process. */ 76/* States during the configuration process. */
76enum { 77enum {
77 PROBE = 0, 78 PROBE = 0,
78 RATE_LIMIT_PROBE,
79 ANNOUNCE, 79 ANNOUNCE,
80 MONITOR, 80 MONITOR,
81 DEFEND 81 DEFEND
@@ -89,13 +89,11 @@ enum {
89}; 89};
90 90
91struct globals { 91struct globals {
92 struct sockaddr saddr; 92 struct sockaddr iface_sockaddr;
93 struct ether_addr eth_addr; 93 struct ether_addr eth_addr;
94 uint32_t localnet_ip; 94 uint32_t localnet_ip;
95} FIX_ALIASING; 95} FIX_ALIASING;
96#define G (*(struct globals*)&bb_common_bufsiz1) 96#define G (*(struct globals*)&bb_common_bufsiz1)
97#define saddr (G.saddr )
98#define eth_addr (G.eth_addr)
99#define INIT_G() do { } while (0) 97#define INIT_G() do { } while (0)
100 98
101 99
@@ -113,17 +111,24 @@ static uint32_t pick_nip(void)
113 return htonl((G.localnet_ip + 0x0100) + tmp); 111 return htonl((G.localnet_ip + 0x0100) + tmp);
114} 112}
115 113
114static const char *nip_to_a(uint32_t nip)
115{
116 struct in_addr in;
117 in.s_addr = nip;
118 return inet_ntoa(in);
119}
120
116/** 121/**
117 * Broadcast an ARP packet. 122 * Broadcast an ARP packet.
118 */ 123 */
119static void arp( 124static void arp(
120 /* int op, - always ARPOP_REQUEST */ 125 /* int op, - always ARPOP_REQUEST */
121 /* const struct ether_addr *source_eth, - always &eth_addr */ 126 /* const struct ether_addr *source_eth, - always &G.eth_addr */
122 struct in_addr source_ip, 127 uint32_t source_nip,
123 const struct ether_addr *target_eth, struct in_addr target_ip) 128 const struct ether_addr *target_eth, uint32_t target_nip)
124{ 129{
125 enum { op = ARPOP_REQUEST }; 130 enum { op = ARPOP_REQUEST };
126#define source_eth (&eth_addr) 131#define source_eth (&G.eth_addr)
127 132
128 struct arp_packet p; 133 struct arp_packet p;
129 memset(&p, 0, sizeof(p)); 134 memset(&p, 0, sizeof(p));
@@ -140,18 +145,18 @@ static void arp(
140 p.arp.arp_pln = 4; 145 p.arp.arp_pln = 4;
141 p.arp.arp_op = htons(op); 146 p.arp.arp_op = htons(op);
142 memcpy(&p.arp.arp_sha, source_eth, ETH_ALEN); 147 memcpy(&p.arp.arp_sha, source_eth, ETH_ALEN);
143 memcpy(&p.arp.arp_spa, &source_ip, sizeof(p.arp.arp_spa)); 148 memcpy(&p.arp.arp_spa, &source_nip, 4);
144 memcpy(&p.arp.arp_tha, target_eth, ETH_ALEN); 149 memcpy(&p.arp.arp_tha, target_eth, ETH_ALEN);
145 memcpy(&p.arp.arp_tpa, &target_ip, sizeof(p.arp.arp_tpa)); 150 memcpy(&p.arp.arp_tpa, &target_nip, 4);
146 151
147 // send it 152 // send it
148 // Even though sock_fd is already bound to saddr, just send() 153 // Even though sock_fd is already bound to G.iface_sockaddr, just send()
149 // won't work, because "socket is not connected" 154 // won't work, because "socket is not connected"
150 // (and connect() won't fix that, "operation not supported"). 155 // (and connect() won't fix that, "operation not supported").
151 // Thus we sendto() to saddr. I wonder which sockaddr 156 // Thus we sendto() to G.iface_sockaddr. I wonder which sockaddr
152 // (from bind() or from sendto()?) kernel actually uses 157 // (from bind() or from sendto()?) kernel actually uses
153 // to determine iface to emit the packet from... 158 // to determine iface to emit the packet from...
154 xsendto(sock_fd, &p, sizeof(p), &saddr, sizeof(saddr)); 159 xsendto(sock_fd, &p, sizeof(p), &G.iface_sockaddr, sizeof(G.iface_sockaddr));
155#undef source_eth 160#undef source_eth
156} 161}
157 162
@@ -159,18 +164,18 @@ static void arp(
159 * Run a script. 164 * Run a script.
160 * argv[0]:intf argv[1]:script_name argv[2]:junk argv[3]:NULL 165 * argv[0]:intf argv[1]:script_name argv[2]:junk argv[3]:NULL
161 */ 166 */
162static int run(char *argv[3], const char *param, struct in_addr *ip) 167static int run(char *argv[3], const char *param, uint32_t nip)
163{ 168{
164 int status; 169 int status;
165 char *addr = addr; /* for gcc */ 170 const char *addr = addr; /* for gcc */
166 const char *fmt = "%s %s %s" + 3; 171 const char *fmt = "%s %s %s" + 3;
167 172
168 argv[2] = (char*)param; 173 argv[2] = (char*)param;
169 174
170 VDBG("%s run %s %s\n", argv[0], argv[1], argv[2]); 175 VDBG("%s run %s %s\n", argv[0], argv[1], argv[2]);
171 176
172 if (ip) { 177 if (nip != 0) {
173 addr = inet_ntoa(*ip); 178 addr = nip_to_a(nip);
174 xsetenv("ip", addr); 179 xsetenv("ip", addr);
175 fmt -= 3; 180 fmt -= 3;
176 } 181 }
@@ -207,26 +212,22 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
207 212
208 // ugly trick, but I want these zeroed in one go 213 // ugly trick, but I want these zeroed in one go
209 struct { 214 struct {
210 const struct in_addr null_ip;
211 const struct ether_addr null_addr; 215 const struct ether_addr null_addr;
212 struct in_addr ip;
213 struct ifreq ifr; 216 struct ifreq ifr;
217 uint32_t chosen_nip;
214 int timeout_ms; /* must be signed */ 218 int timeout_ms; /* must be signed */
215 unsigned conflicts; 219 unsigned conflicts;
216 unsigned nprobes; 220 unsigned nprobes;
217 unsigned nclaims; 221 unsigned nclaims;
218 int ready;
219 int verbose; 222 int verbose;
220 } L; 223 } L;
221#define null_ip (L.null_ip )
222#define null_addr (L.null_addr ) 224#define null_addr (L.null_addr )
223#define ip (L.ip ) 225#define chosen_nip (L.chosen_nip)
224#define ifr (L.ifr ) 226#define ifr (L.ifr )
225#define timeout_ms (L.timeout_ms) 227#define timeout_ms (L.timeout_ms)
226#define conflicts (L.conflicts ) 228#define conflicts (L.conflicts )
227#define nprobes (L.nprobes ) 229#define nprobes (L.nprobes )
228#define nclaims (L.nclaims ) 230#define nclaims (L.nclaims )
229#define ready (L.ready )
230#define verbose (L.verbose ) 231#define verbose (L.verbose )
231 232
232 memset(&L, 0, sizeof(L)); 233 memset(&L, 0, sizeof(L));
@@ -264,11 +265,13 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
264 G.localnet_ip = ntohl(net.s_addr); 265 G.localnet_ip = ntohl(net.s_addr);
265 } 266 }
266 if (opts & 4) { // -r n.n.n.n 267 if (opts & 4) { // -r n.n.n.n
268 struct in_addr ip;
267 if (inet_aton(r_opt, &ip) == 0 269 if (inet_aton(r_opt, &ip) == 0
268 || (ntohl(ip.s_addr) & IN_CLASSB_NET) != G.localnet_ip 270 || (ntohl(ip.s_addr) & IN_CLASSB_NET) != G.localnet_ip
269 ) { 271 ) {
270 bb_error_msg_and_die("invalid link address"); 272 bb_error_msg_and_die("invalid link address");
271 } 273 }
274 chosen_nip = ip.s_addr;
272 } 275 }
273 argv += optind - 1; 276 argv += optind - 1;
274 277
@@ -282,23 +285,23 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
282 xsetenv("interface", argv_intf); 285 xsetenv("interface", argv_intf);
283 286
284 // initialize the interface (modprobe, ifup, etc) 287 // initialize the interface (modprobe, ifup, etc)
285 if (run(argv, "init", NULL)) 288 if (run(argv, "init", 0))
286 return EXIT_FAILURE; 289 return EXIT_FAILURE;
287 290
288 // initialize saddr 291 // initialize G.iface_sockaddr
289 // saddr is: { u16 sa_family; u8 sa_data[14]; } 292 // G.iface_sockaddr is: { u16 sa_family; u8 sa_data[14]; }
290 //memset(&saddr, 0, sizeof(saddr)); 293 //memset(&G.iface_sockaddr, 0, sizeof(G.iface_sockaddr));
291 //TODO: are we leaving sa_family == 0 (AF_UNSPEC)?! 294 //TODO: are we leaving sa_family == 0 (AF_UNSPEC)?!
292 safe_strncpy(saddr.sa_data, argv_intf, sizeof(saddr.sa_data)); 295 safe_strncpy(G.iface_sockaddr.sa_data, argv_intf, sizeof(G.iface_sockaddr.sa_data));
293 296
294 // bind to the interface's ARP socket 297 // bind to the interface's ARP socket
295 xbind(sock_fd, &saddr, sizeof(saddr)); 298 xbind(sock_fd, &G.iface_sockaddr, sizeof(G.iface_sockaddr));
296 299
297 // get the interface's ethernet address 300 // get the interface's ethernet address
298 //memset(&ifr, 0, sizeof(ifr)); 301 //memset(&ifr, 0, sizeof(ifr));
299 strncpy_IFNAMSIZ(ifr.ifr_name, argv_intf); 302 strncpy_IFNAMSIZ(ifr.ifr_name, argv_intf);
300 xioctl(sock_fd, SIOCGIFHWADDR, &ifr); 303 xioctl(sock_fd, SIOCGIFHWADDR, &ifr);
301 memcpy(&eth_addr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN); 304 memcpy(&G.eth_addr, &ifr.ifr_hwaddr.sa_data, ETH_ALEN);
302 305
303 // start with some stable ip address, either a function of 306 // start with some stable ip address, either a function of
304 // the hardware address or else the last address we used. 307 // the hardware address or else the last address we used.
@@ -308,11 +311,11 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
308 // depending on when we detect conflicts. 311 // depending on when we detect conflicts.
309 { 312 {
310 uint32_t t; 313 uint32_t t;
311 move_from_unaligned32(t, ((char *)&eth_addr + 2)); 314 move_from_unaligned32(t, ((char *)&G.eth_addr + 2));
312 srand(t); 315 srand(t);
313 } 316 }
314 if (ip.s_addr == 0) 317 if (chosen_nip == 0)
315 ip.s_addr = pick_nip(); 318 chosen_nip = pick_nip();
316 319
317 // FIXME cases to handle: 320 // FIXME cases to handle:
318 // - zcip already running! 321 // - zcip already running!
@@ -331,7 +334,9 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
331 // - start with some address we want to try 334 // - start with some address we want to try
332 // - short random delay 335 // - short random delay
333 // - arp probes to see if another host uses it 336 // - arp probes to see if another host uses it
337 // 00:04:e2:64:23:c2 > ff:ff:ff:ff:ff:ff, ARP (0x0806): arp who-has 169.254.194.171 tell 0.0.0.0
334 // - arp announcements that we're claiming it 338 // - arp announcements that we're claiming it
339 // 00:04:e2:64:23:c2 > ff:ff:ff:ff:ff:ff, ARP (0x0806): arp who-has 169.254.194.171 (00:04:e2:64:23:c2) tell 169.254.194.171
335 // - use it 340 // - use it
336 // - defend it, within limits 341 // - defend it, within limits
337 // exit if: 342 // exit if:
@@ -382,78 +387,47 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
382 if (nprobes < PROBE_NUM) { 387 if (nprobes < PROBE_NUM) {
383 nprobes++; 388 nprobes++;
384 VDBG("probe/%u %s@%s\n", 389 VDBG("probe/%u %s@%s\n",
385 nprobes, argv_intf, inet_ntoa(ip)); 390 nprobes, argv_intf, nip_to_a(chosen_nip));
386 timeout_ms = PROBE_MIN * 1000; 391 timeout_ms = PROBE_MIN * 1000;
387 timeout_ms += random_delay_ms(PROBE_MAX - PROBE_MIN); 392 timeout_ms += random_delay_ms(PROBE_MAX - PROBE_MIN);
388 arp(/* ARPOP_REQUEST, */ 393 arp(/* ARPOP_REQUEST, */
389 /* &eth_addr, */ null_ip, 394 /* &G.eth_addr, */ 0,
390 &null_addr, ip); 395 &null_addr, chosen_nip);
391 } 396 break;
392 else {
393 // Switch to announce state.
394 state = ANNOUNCE;
395 nclaims = 0;
396 VDBG("announce/%u %s@%s\n",
397 nclaims, argv_intf, inet_ntoa(ip));
398 timeout_ms = ANNOUNCE_INTERVAL * 1000;
399 arp(/* ARPOP_REQUEST, */
400 /* &eth_addr, */ ip,
401 &eth_addr, ip);
402 } 397 }
403 break; 398 // Switch to announce state.
404 case RATE_LIMIT_PROBE:
405 // timeouts in the RATE_LIMIT_PROBE state mean no conflicting ARP packets
406 // have been received, so we can move immediately to the announce state
407 state = ANNOUNCE;
408 nclaims = 0; 399 nclaims = 0;
409 VDBG("announce/%u %s@%s\n", 400 state = ANNOUNCE;
410 nclaims, argv_intf, inet_ntoa(ip)); 401 goto send_announce;
411 timeout_ms = ANNOUNCE_INTERVAL * 1000;
412 arp(/* ARPOP_REQUEST, */
413 /* &eth_addr, */ ip,
414 &eth_addr, ip);
415 break;
416 case ANNOUNCE: 402 case ANNOUNCE:
417 // timeouts in the ANNOUNCE state mean no conflicting ARP packets 403 // timeouts in the ANNOUNCE state mean no conflicting ARP packets
418 // have been received, so we can progress through the states 404 // have been received, so we can progress through the states
419 if (nclaims < ANNOUNCE_NUM) { 405 if (nclaims < ANNOUNCE_NUM) {
406 send_announce:
420 nclaims++; 407 nclaims++;
421 VDBG("announce/%u %s@%s\n", 408 VDBG("announce/%u %s@%s\n",
422 nclaims, argv_intf, inet_ntoa(ip)); 409 nclaims, argv_intf, nip_to_a(chosen_nip));
423 timeout_ms = ANNOUNCE_INTERVAL * 1000; 410 timeout_ms = ANNOUNCE_INTERVAL * 1000;
424 arp(/* ARPOP_REQUEST, */ 411 arp(/* ARPOP_REQUEST, */
425 /* &eth_addr, */ ip, 412 /* &G.eth_addr, */ chosen_nip,
426 &eth_addr, ip); 413 &G.eth_addr, chosen_nip);
427 } 414 break;
428 else {
429 // Switch to monitor state.
430 state = MONITOR;
431 // link is ok to use earlier
432 // FIXME update filters
433 run(argv, "config", &ip);
434 ready = 1;
435 conflicts = 0;
436 timeout_ms = -1; // Never timeout in the monitor state.
437
438 // NOTE: all other exit paths
439 // should deconfig ...
440 if (QUIT)
441 return EXIT_SUCCESS;
442 } 415 }
416 // Switch to monitor state.
417 // FIXME update filters
418 run(argv, "config", chosen_nip);
419 // NOTE: all other exit paths should deconfig...
420 if (QUIT)
421 return EXIT_SUCCESS;
422 conflicts = 0;
423 timeout_ms = -1; // Never timeout in the monitor state.
424 state = MONITOR;
443 break; 425 break;
444 case DEFEND: 426 case DEFEND:
445 // We won! No ARP replies, so just go back to monitor. 427 // Defend period ended with no ARP replies - we won.
446 state = MONITOR;
447 timeout_ms = -1;
448 conflicts = 0; 428 conflicts = 0;
449 break; 429 timeout_ms = -1;
450 default: 430 state = MONITOR;
451 // Invalid, should never happen. Restart the whole protocol.
452 state = PROBE;
453 ip.s_addr = pick_nip();
454 timeout_ms = 0;
455 nprobes = 0;
456 nclaims = 0;
457 break; 431 break;
458 } // switch (state) 432 } // switch (state)
459 break; // case 0 (timeout) 433 break; // case 0 (timeout)
@@ -466,13 +440,10 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
466 unsigned diff = deadline_us - MONOTONIC_US(); 440 unsigned diff = deadline_us - MONOTONIC_US();
467 if ((int)(diff) < 0) { 441 if ((int)(diff) < 0) {
468 // Current time is greater than the expected timeout time. 442 // Current time is greater than the expected timeout time.
469 // Should never happen. 443 diff = 0;
470 VDBG("missed an expected timeout\n");
471 timeout_ms = 0;
472 } else {
473 VDBG("adjusting timeout\n");
474 timeout_ms = (diff / 1000) | 1; /* never 0 */
475 } 444 }
445 VDBG("adjusting timeout\n");
446 timeout_ms = (diff / 1000) | 1; /* never 0 */
476 } 447 }
477 448
478 if ((fds[0].revents & POLLIN) == 0) { 449 if ((fds[0].revents & POLLIN) == 0) {
@@ -480,8 +451,9 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
480 // FIXME: links routinely go down; 451 // FIXME: links routinely go down;
481 // this shouldn't necessarily exit. 452 // this shouldn't necessarily exit.
482 bb_error_msg("iface %s is down", argv_intf); 453 bb_error_msg("iface %s is down", argv_intf);
483 if (ready) { 454 if (state >= MONITOR) {
484 run(argv, "deconfig", &ip); 455 /* only if we are in MONITOR or DEFEND */
456 run(argv, "deconfig", chosen_nip);
485 } 457 }
486 return EXIT_FAILURE; 458 return EXIT_FAILURE;
487 } 459 }
@@ -492,8 +464,14 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
492 if (safe_read(sock_fd, &p, sizeof(p)) < 0) { 464 if (safe_read(sock_fd, &p, sizeof(p)) < 0) {
493 bb_perror_msg_and_die(bb_msg_read_error); 465 bb_perror_msg_and_die(bb_msg_read_error);
494 } 466 }
467
495 if (p.eth.ether_type != htons(ETHERTYPE_ARP)) 468 if (p.eth.ether_type != htons(ETHERTYPE_ARP))
496 continue; 469 continue;
470 if (p.arp.arp_op != htons(ARPOP_REQUEST)
471 && p.arp.arp_op != htons(ARPOP_REPLY)
472 ) {
473 continue;
474 }
497#ifdef DEBUG 475#ifdef DEBUG
498 { 476 {
499 struct ether_addr *sha = (struct ether_addr *) p.arp.arp_sha; 477 struct ether_addr *sha = (struct ether_addr *) p.arp.arp_sha;
@@ -511,23 +489,17 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
511 inet_ntoa(*tpa)); 489 inet_ntoa(*tpa));
512 } 490 }
513#endif 491#endif
514 if (p.arp.arp_op != htons(ARPOP_REQUEST)
515 && p.arp.arp_op != htons(ARPOP_REPLY)
516 ) {
517 continue;
518 }
519
520 source_ip_conflict = 0; 492 source_ip_conflict = 0;
521 target_ip_conflict = 0; 493 target_ip_conflict = 0;
522 494
523 if (memcmp(&p.arp.arp_sha, &eth_addr, ETH_ALEN) != 0) { 495 if (memcmp(&p.arp.arp_sha, &G.eth_addr, ETH_ALEN) != 0) {
524 if (memcmp(p.arp.arp_spa, &ip.s_addr, sizeof(struct in_addr)) == 0) { 496 if (memcmp(p.arp.arp_spa, &chosen_nip, 4) == 0) {
525 /* A probe or reply with source_ip == chosen ip */ 497 /* A probe or reply with source_ip == chosen ip */
526 source_ip_conflict = 1; 498 source_ip_conflict = 1;
527 } 499 }
528 if (p.arp.arp_op == htons(ARPOP_REQUEST) 500 if (p.arp.arp_op == htons(ARPOP_REQUEST)
529 && memcmp(p.arp.arp_spa, &null_ip, sizeof(struct in_addr)) == 0 501 && memcmp(p.arp.arp_spa, &const_int_0, 4) == 0
530 && memcmp(p.arp.arp_tpa, &ip.s_addr, sizeof(struct in_addr)) == 0 502 && memcmp(p.arp.arp_tpa, &chosen_nip, 4) == 0
531 ) { 503 ) {
532 /* A probe with source_ip == 0.0.0.0, target_ip == chosen ip: 504 /* A probe with source_ip == 0.0.0.0, target_ip == chosen ip:
533 * another host trying to claim this ip! 505 * another host trying to claim this ip!
@@ -545,54 +517,39 @@ int zcip_main(int argc UNUSED_PARAM, char **argv)
545 // and other hosts doing ARP probes (target IP conflicts). 517 // and other hosts doing ARP probes (target IP conflicts).
546 if (source_ip_conflict || target_ip_conflict) { 518 if (source_ip_conflict || target_ip_conflict) {
547 conflicts++; 519 conflicts++;
548 if (conflicts >= MAX_CONFLICTS) { 520 timeout_ms = PROBE_MIN * 1000
549 VDBG("%s ratelimit\n", argv_intf); 521 + CONFLICT_MULTIPLIER * random_delay_ms(conflicts);
550 timeout_ms = RATE_LIMIT_INTERVAL * 1000; 522 chosen_nip = pick_nip();
551 state = RATE_LIMIT_PROBE;
552 }
553
554 // restart the whole protocol
555 ip.s_addr = pick_nip();
556 timeout_ms = 0;
557 nprobes = 0; 523 nprobes = 0;
558 nclaims = 0; 524 nclaims = 0;
525 state = PROBE;
559 } 526 }
560 break; 527 break;
561 case MONITOR: 528 case MONITOR:
562 // If a conflict, we try to defend with a single ARP probe. 529 // If a conflict, we try to defend with a single ARP probe.
563 if (source_ip_conflict) { 530 if (source_ip_conflict) {
564 VDBG("monitor conflict -- defending\n"); 531 VDBG("monitor conflict -- defending\n");
565 state = DEFEND;
566 timeout_ms = DEFEND_INTERVAL * 1000; 532 timeout_ms = DEFEND_INTERVAL * 1000;
533 state = DEFEND;
567 arp(/* ARPOP_REQUEST, */ 534 arp(/* ARPOP_REQUEST, */
568 /* &eth_addr, */ ip, 535 /* &G.eth_addr, */ chosen_nip,
569 &eth_addr, ip); 536 &G.eth_addr, chosen_nip);
570 } 537 }
571 break; 538 break;
572 case DEFEND: 539 case DEFEND:
573 // Well, we tried. Start over (on conflict). 540 // Well, we tried. Start over (on conflict).
574 if (source_ip_conflict) { 541 if (source_ip_conflict) {
575 state = PROBE;
576 VDBG("defend conflict -- starting over\n"); 542 VDBG("defend conflict -- starting over\n");
577 ready = 0; 543 run(argv, "deconfig", chosen_nip);
578 run(argv, "deconfig", &ip);
579 544
580 // restart the whole protocol 545 // restart the whole protocol
581 ip.s_addr = pick_nip();
582 timeout_ms = 0; 546 timeout_ms = 0;
547 chosen_nip = pick_nip();
583 nprobes = 0; 548 nprobes = 0;
584 nclaims = 0; 549 nclaims = 0;
550 state = PROBE;
585 } 551 }
586 break; 552 break;
587 default:
588 // Invalid, should never happen. Restart the whole protocol.
589 VDBG("invalid state -- starting over\n");
590 state = PROBE;
591 ip.s_addr = pick_nip();
592 timeout_ms = 0;
593 nprobes = 0;
594 nclaims = 0;
595 break;
596 } // switch state 553 } // switch state
597 break; // case 1 (packets arriving) 554 break; // case 1 (packets arriving)
598 } // switch poll 555 } // switch poll