Make the ARP-based lease address collision checks configurable in delay times

and number of probes.
This commit is contained in:
Nicholas J. Kain 2013-02-09 00:30:19 -05:00
parent b8c77a45e8
commit f807e10e76
3 changed files with 50 additions and 12 deletions

View File

@ -1,6 +1,6 @@
/* arp.c - arp ping checking /* arp.c - arp ping checking
* *
* Copyright (c) 2010-2011 Nicholas J. Kain <njkain at gmail dot com> * Copyright (c) 2010-2013 Nicholas J. Kain <njkain at gmail dot com>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -53,10 +53,10 @@
#define ARP_RETRANS_DELAY 5000 // ms #define ARP_RETRANS_DELAY 5000 // ms
// From RFC5227 // From RFC5227
#define PROBE_WAIT 1000 // initial random delay int arp_probe_wait = 1000; // initial random delay (ms)
#define PROBE_NUM 3 // number of probe packets int arp_probe_num = 3; // number of probe packets
#define PROBE_MIN 1000 // minimum delay until repeated probe int arp_probe_min = 1000; // minimum delay until repeated probe (ms)
#define PROBE_MAX 2000 // maximum delay until repeated probe int arp_probe_max = 2000; // maximum delay until repeated probe (ms)
#define ANNOUNCE_WAIT 2000 // delay before announcing #define ANNOUNCE_WAIT 2000 // delay before announcing
#define ANNOUNCE_NUM 2 // number of Announcement packets #define ANNOUNCE_NUM 2 // number of Announcement packets
#define ANNOUNCE_INTERVAL 2000 // time between Announcement packets #define ANNOUNCE_INTERVAL 2000 // time between Announcement packets
@ -64,6 +64,7 @@
#define RATE_LIMIT_INTERVAL 60000 // delay between successive attempts #define RATE_LIMIT_INTERVAL 60000 // delay between successive attempts
#define DEFEND_INTERVAL 10000 // minimum interval between defensive ARPs #define DEFEND_INTERVAL 10000 // minimum interval between defensive ARPs
typedef enum { typedef enum {
AS_NONE = 0, // Nothing to react to wrt ARP AS_NONE = 0, // Nothing to react to wrt ARP
AS_COLLISION_CHECK, // Checking to see if another host has our IP before AS_COLLISION_CHECK, // Checking to see if another host has our IP before
@ -383,7 +384,7 @@ int arp_check(struct client_state_t *cs, struct dhcpmsg *packet)
cs->arpPrevState = cs->dhcpState; cs->arpPrevState = cs->dhcpState;
cs->dhcpState = DS_COLLISION_CHECK; cs->dhcpState = DS_COLLISION_CHECK;
arp_check_start_ts = arp_send_stats[ASEND_COLLISION_CHECK].ts; arp_check_start_ts = arp_send_stats[ASEND_COLLISION_CHECK].ts;
probe_wait_time = PROBE_WAIT; probe_wait_time = arp_probe_wait;
arp_wake_ts[AS_COLLISION_CHECK] = arp_check_start_ts + probe_wait_time; arp_wake_ts[AS_COLLISION_CHECK] = arp_check_start_ts + probe_wait_time;
return 0; return 0;
} }
@ -561,7 +562,7 @@ static int arp_is_query_reply(struct arpMsg *am)
static int arp_gen_probe_wait(void) static int arp_gen_probe_wait(void)
{ {
// This is not a uniform distribution but it doesn't matter here. // This is not a uniform distribution but it doesn't matter here.
return PROBE_MIN + rand() % (PROBE_MAX - PROBE_MIN); return arp_probe_min + rand() % (arp_probe_max - arp_probe_min);
} }
static void arp_defense_timeout(struct client_state_t *cs, long long nowts) static void arp_defense_timeout(struct client_state_t *cs, long long nowts)
@ -626,7 +627,7 @@ static void arp_collision_timeout(struct client_state_t *cs, long long nowts)
arp_defense_timeout(cs, nowts); arp_defense_timeout(cs, nowts);
if (nowts >= arp_check_start_ts + ANNOUNCE_WAIT || if (nowts >= arp_check_start_ts + ANNOUNCE_WAIT ||
arp_send_stats[ASEND_COLLISION_CHECK].count >= PROBE_NUM) { arp_send_stats[ASEND_COLLISION_CHECK].count >= arp_probe_num) {
arp_success(cs); arp_success(cs);
return; return;
} }

View File

@ -53,6 +53,10 @@ struct arpMsg {
uint8_t pad[18]; // 2a pad for min. ethernet payload (60 bytes) uint8_t pad[18]; // 2a pad for min. ethernet payload (60 bytes)
}; };
extern int arp_probe_wait;
extern int arp_probe_num;
extern int arp_probe_min;
extern int arp_probe_max;
extern int arp_relentless_def; extern int arp_relentless_def;
void arp_reset_send_stats(void); void arp_reset_send_stats(void);

View File

@ -1,6 +1,6 @@
/* ndhc.c - DHCP client /* ndhc.c - DHCP client
* *
* Copyright (c) 2004-2012 Nicholas J. Kain <njkain at gmail dot com> * Copyright (c) 2004-2013 Nicholas J. Kain <njkain at gmail dot com>
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -107,6 +107,10 @@ static void show_usage(void)
" -C, --chroot=DIR Chroot to this directory\n" " -C, --chroot=DIR Chroot to this directory\n"
" -d, --relentless-defense Never back off in defending IP against\n" " -d, --relentless-defense Never back off in defending IP against\n"
" conflicting hosts (servers only)\n" " conflicting hosts (servers only)\n"
" -w, --arp-probe-wait Time to delay before first ARP probe\n"
" -W, --arp-probe-num Number of ARP probes before lease is ok\n"
" -m, --arp-probe-min Min ms to wait for ARP response\n"
" -M, --arp-probe-max Max ms to wait for ARP response\n"
" -v, --version Display version\n" " -v, --version Display version\n"
); );
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
@ -324,6 +328,10 @@ int main(int argc, char **argv)
{"user", required_argument, 0, 'u'}, {"user", required_argument, 0, 'u'},
{"chroot", required_argument, 0, 'C'}, {"chroot", required_argument, 0, 'C'},
{"relentless-defense", no_argument, 0, 'd'}, {"relentless-defense", no_argument, 0, 'd'},
{"arp-probe-wait", required_argument, 0, 'w'},
{"arp-probe-num", required_argument, 0, 'W'},
{"arp-probe-min", required_argument, 0, 'm'},
{"arp-probe-max", required_argument, 0, 'M'},
{"version", no_argument, 0, 'v'}, {"version", no_argument, 0, 'v'},
{"help", no_argument, 0, '?'}, {"help", no_argument, 0, '?'},
{0, 0, 0, 0} {0, 0, 0, 0}
@ -331,8 +339,8 @@ int main(int argc, char **argv)
while (1) { while (1) {
int option_index = 0; int option_index = 0;
c = getopt_long(argc, argv, "c:fbp:h:i:np:l:qr:V:u:C:dv", arg_options, c = getopt_long(argc, argv, "c:fbp:h:i:np:l:qr:V:u:C:dw:W:m:M:v",
&option_index); arg_options, &option_index);
if (c == -1) break; if (c == -1) break;
switch (c) { switch (c) {
@ -389,9 +397,34 @@ int main(int argc, char **argv)
case 'd': case 'd':
arp_relentless_def = 1; arp_relentless_def = 1;
break; break;
case 'w':
case 'W': {
int t = atoi(optarg);
if (t < 0)
break;
if (c == 'w')
arp_probe_wait = t;
else
arp_probe_num = t;
break;
}
case 'm':
case 'M': {
int t = atoi(optarg);
if (c == 'm')
arp_probe_min = t;
else
arp_probe_max = t;
if (arp_probe_min > arp_probe_max) {
t = arp_probe_max;
arp_probe_max = arp_probe_min;
arp_probe_min = t;
}
break;
}
case 'v': case 'v':
printf("ndhc %s, dhcp client.\n", NDHC_VERSION); printf("ndhc %s, dhcp client.\n", NDHC_VERSION);
printf("Copyright (c) 2004-2012 Nicholas J. Kain\n" printf("Copyright (c) 2004-2013 Nicholas J. Kain\n"
"All rights reserved.\n\n" "All rights reserved.\n\n"
"Redistribution and use in source and binary forms, with or without\n" "Redistribution and use in source and binary forms, with or without\n"
"modification, are permitted provided that the following conditions are met:\n\n" "modification, are permitted provided that the following conditions are met:\n\n"