From 8af6bee46d6e7bd52863fd8fd4bb869770a8c27f Mon Sep 17 00:00:00 2001 From: "Nicholas J. Kain" Date: Sun, 6 Apr 2014 05:51:52 -0400 Subject: [PATCH] arp_switch_state() was far too confusing and buggy. Pass the target state as an argument, and only switch the global state after a change is successfully made. --- ndhc/arp.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/ndhc/arp.c b/ndhc/arp.c index b0a610d..31f4f29 100644 --- a/ndhc/arp.c +++ b/ndhc/arp.c @@ -158,12 +158,18 @@ static int get_arp_defense_socket(struct client_state_t *cs) return fd; } -static int arp_open_fd(struct client_state_t *cs) +static int arp_open_fd(struct client_state_t *cs, arp_state_t state) { - if (cs->arpFd != -1) + if (cs->arpFd >= 0) { + log_warning("%s: (%s) called but fd already exists", + client_config.interface, __func__); + return 0; + } + switch (state) { + default: + log_warning("%s: (%s) called for 'default' state", + client_config.interface, __func__); return 0; - switch (arpState) { - default: cs->arpFd = -1; arpState = AS_NONE; return -1; case AS_COLLISION_CHECK: case AS_GW_QUERY: case AS_GW_CHECK: cs->arpFd = get_arp_basic_socket(); break; @@ -190,22 +196,21 @@ static void arp_min_close_fd(struct client_state_t *cs) static void arp_switch_state(struct client_state_t *cs, arp_state_t state) { - arp_state_t prev_state = arpState; if (arpState == state || arpState >= AS_MAX) return; - arpState = state; - if (arpState == AS_NONE) { + if (state == AS_NONE) { arp_close_fd(cs); return; } - bool force_reopen = arpState == AS_DEFENSE || prev_state == AS_DEFENSE; + bool force_reopen = state == AS_DEFENSE || arpState == AS_DEFENSE; if (force_reopen) arp_min_close_fd(cs); - if (cs->arpFd == -1 || force_reopen) { - if (arp_open_fd(cs) == -1) + if (cs->arpFd < 0 || force_reopen) { + if (arp_open_fd(cs, state) < 0) suicide("arp: Failed to open arpFd when changing state %u -> %u", - prev_state, arpState); + arpState, state); } + arpState = state; } void arp_close_fd(struct client_state_t *cs)