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
*
* 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.
*
* Redistribution and use in source and binary forms, with or without
@ -53,10 +53,10 @@
#define ARP_RETRANS_DELAY 5000 // ms
// From RFC5227
#define PROBE_WAIT 1000 // initial random delay
#define PROBE_NUM 3 // number of probe packets
#define PROBE_MIN 1000 // minimum delay until repeated probe
#define PROBE_MAX 2000 // maximum delay until repeated probe
int arp_probe_wait = 1000; // initial random delay (ms)
int arp_probe_num = 3; // number of probe packets
int arp_probe_min = 1000; // minimum delay until repeated probe (ms)
int arp_probe_max = 2000; // maximum delay until repeated probe (ms)
#define ANNOUNCE_WAIT 2000 // delay before announcing
#define ANNOUNCE_NUM 2 // number of Announcement packets
#define ANNOUNCE_INTERVAL 2000 // time between Announcement packets
@ -64,6 +64,7 @@
#define RATE_LIMIT_INTERVAL 60000 // delay between successive attempts
#define DEFEND_INTERVAL 10000 // minimum interval between defensive ARPs
typedef enum {
AS_NONE = 0, // Nothing to react to wrt ARP
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->dhcpState = DS_COLLISION_CHECK;
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;
return 0;
}
@ -561,7 +562,7 @@ static int arp_is_query_reply(struct arpMsg *am)
static int arp_gen_probe_wait(void)
{
// 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)
@ -626,7 +627,7 @@ static void arp_collision_timeout(struct client_state_t *cs, long long nowts)
arp_defense_timeout(cs, nowts);
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);
return;
}

View File

@ -53,6 +53,10 @@ struct arpMsg {
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;
void arp_reset_send_stats(void);

View File

@ -1,6 +1,6 @@
/* 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.
*
* 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"
" -d, --relentless-defense Never back off in defending IP against\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"
);
exit(EXIT_SUCCESS);
@ -324,6 +328,10 @@ int main(int argc, char **argv)
{"user", required_argument, 0, 'u'},
{"chroot", required_argument, 0, 'C'},
{"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'},
{"help", no_argument, 0, '?'},
{0, 0, 0, 0}
@ -331,8 +339,8 @@ int main(int argc, char **argv)
while (1) {
int option_index = 0;
c = getopt_long(argc, argv, "c:fbp:h:i:np:l:qr:V:u:C:dv", arg_options,
&option_index);
c = getopt_long(argc, argv, "c:fbp:h:i:np:l:qr:V:u:C:dw:W:m:M:v",
arg_options, &option_index);
if (c == -1) break;
switch (c) {
@ -389,9 +397,34 @@ int main(int argc, char **argv)
case 'd':
arp_relentless_def = 1;
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':
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"
"Redistribution and use in source and binary forms, with or without\n"
"modification, are permitted provided that the following conditions are met:\n\n"