From ed44a901147057a606d8b172c46a3346f1c04f7f Mon Sep 17 00:00:00 2001 From: "Nicholas J. Kain" Date: Mon, 10 Apr 2017 09:57:52 -0400 Subject: [PATCH] state: Faster recovery when carrier lost during DHCP init. If carrier is lost before network fingerprinting is complete, we have a few problems; first, we don't know whether the network has changed underneath us. Second, we've not yet configured the interface properties, and it is not unlikely that doing so will fail as the underlying network device may have been destroyed and recreated during this time (eg, if ethtool has been run at start-up time). Thus, the safest reaction is to terminate and force a supervisor respawn. It is best to do this once carrier recovers, not when the carrier is lost, as it is more likely to minimize delays. --- src/arp.c | 1 + src/ndhc.h | 3 ++- src/state.c | 8 +++++++- 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/arp.c b/src/arp.c index 334888c..21e93c9 100644 --- a/src/arp.c +++ b/src/arp.c @@ -558,6 +558,7 @@ int arp_query_gateway(struct client_state_t cs[static 1]) return ARPR_FAIL; } cs->sent_gw_query = true; + cs->init_fingerprint_inprogress = true; garp.wake_ts[AS_QUERY_GW_SEND] = -1; return ARPR_OK; } diff --git a/src/ndhc.h b/src/ndhc.h index cd527ce..caf025a 100644 --- a/src/ndhc.h +++ b/src/ndhc.h @@ -47,7 +47,8 @@ struct client_state_t { uint8_t routerArp[6], serverArp[6]; bool using_dhcp_bpf, got_router_arp, got_server_arp, arp_is_defense, check_fingerprint, program_init; - bool sent_gw_query, sent_first_announce, sent_second_announce; + bool sent_gw_query, sent_first_announce, sent_second_announce, + init_fingerprint_inprogress; }; struct client_config_t { diff --git a/src/state.c b/src/state.c index 7d4ec66..3ee7963 100644 --- a/src/state.c +++ b/src/state.c @@ -83,6 +83,7 @@ static void reinit_shared_deconfig(struct client_state_t cs[static 1]) cs->sent_gw_query = false; cs->sent_first_announce = false; cs->sent_second_announce = false; + cs->init_fingerprint_inprogress = false; memset(&cs->routerArp, 0, sizeof cs->routerArp); memset(&cs->serverArp, 0, sizeof cs->serverArp); arp_reset_state(cs); @@ -416,6 +417,10 @@ static int frenew(struct client_state_t cs[static 1], bool is_bound) static int ifup_action(struct client_state_t cs[static 1]) { if (cs->routerAddr && cs->serverAddr) { + if (cs->init_fingerprint_inprogress) { + suicide("%s: Carrier lost during initial fingerprint. Forcing restart.", + client_config.interface); + } if (arp_gw_check(cs) >= 0) { log_line("%s: Interface is back. Revalidating lease...", client_config.interface); @@ -621,7 +626,8 @@ skip_to_requesting: r = arp_do_gw_query(cs); if (r == ARPR_OK) { } else if (r == ARPR_FREE) { - // We got both ARP addresses. + log_line("%s: Network fingerprinting complete.", client_config.interface); + cs->init_fingerprint_inprogress = false; } else if (r == ARPR_FAIL) { ret = COR_ERROR; scrReturn(ret);