From 5b82be8b00524cf85ad14a5f0e57f835d13c6938 Mon Sep 17 00:00:00 2001 From: "Nicholas J. Kain" Date: Sat, 14 Feb 2015 20:47:14 -0500 Subject: [PATCH] If ifchd interactions fail, terminate. Ideally we would pause and resume state, but for now just bail out. If ndhc is process-supervised, it will recover to the proper state quickly. --- src/arp.c | 8 +++++++- src/ndhc.c | 6 ++++-- src/state.c | 24 ++++++++++++++++++------ src/state.h | 2 +- 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/arp.c b/src/arp.c index 38049c0..e4086c6 100644 --- a/src/arp.c +++ b/src/arp.c @@ -468,7 +468,13 @@ void arp_success(struct client_state_t cs[static 1]) cs->init = 0; garp.last_conflict_ts = 0; garp.wake_ts[AS_COLLISION_CHECK] = -1; - ifchange_bind(cs, &garp.dhcp_packet); + if (ifchange_bind(cs, &garp.dhcp_packet) < 0) { + // XXX: Not ideal, but assuming that the DHCP process is supervised, + // it will recover. The correct thing to do would be to keep + // trying to set the configuration state. + suicide("%s: Failed to set the interface IP address and properties!", + client_config.interface); + } if (cs->arpPrevState == DS_RENEWING || cs->arpPrevState == DS_REBINDING) { arp_switch_state(cs, AS_DEFENSE); } else { diff --git a/src/ndhc.c b/src/ndhc.c index 55fad76..ddc88da 100644 --- a/src/ndhc.c +++ b/src/ndhc.c @@ -435,8 +435,10 @@ static void ndhc_main(void) { memset(chroot_dir, '\0', sizeof chroot_dir); nk_set_uidgid(ndhc_uid, ndhc_gid, NULL, 0); - if (cs.ifsPrevState != IFS_UP) - ifchange_deconfig(&cs); + if (cs.ifsPrevState != IFS_UP) { + if (ifchange_deconfig(&cs) < 0) + suicide("%s: can't deconfigure interface settings", __func__); + } do_ndhc_work(); } diff --git a/src/state.c b/src/state.c index 593125f..64c6143 100644 --- a/src/state.c +++ b/src/state.c @@ -107,9 +107,10 @@ static int delay_timeout(struct client_state_t cs[static 1], size_t numpackets) return to * 1000 + (nk_random_u32(&cs->rnd32_state) & 0x7fffffffu) % 1000; } -static void reinit_shared_deconfig(struct client_state_t cs[static 1]) +static int reinit_shared_deconfig(struct client_state_t cs[static 1]) { - ifchange_deconfig(cs); + if (ifchange_deconfig(cs) < 0) + return -1; arp_close_fd(cs); cs->clientAddr = 0; num_dhcp_requests = 0; @@ -118,22 +119,33 @@ static void reinit_shared_deconfig(struct client_state_t cs[static 1]) memset(&cs->routerArp, 0, sizeof cs->routerArp); memset(&cs->serverArp, 0, sizeof cs->serverArp); arp_reset_send_stats(); + return 0; } -void reinit_selecting(struct client_state_t cs[static 1], int timeout) +int reinit_selecting(struct client_state_t cs[static 1], int timeout) { - reinit_shared_deconfig(cs); + if (reinit_shared_deconfig(cs) < 0) { + // XXX: This should retry until it succeeds. + suicide("%s: (%s) deconfiguring interface failed", + client_config.interface, __func__); + } cs->dhcpState = DS_SELECTING; dhcp_wake_ts = curms() + timeout; start_dhcp_listen(cs); + return 0; } -static void set_released(struct client_state_t cs[static 1]) +static int set_released(struct client_state_t cs[static 1]) { - reinit_shared_deconfig(cs); + if (reinit_shared_deconfig(cs) < 0) { + // XXX: This should retry until it succeeds. + suicide("%s: (%s) deconfiguring interface failed", + client_config.interface, __func__); + } cs->dhcpState = DS_RELEASED; dhcp_wake_ts = -1; stop_dhcp_listen(cs); + return 0; } // Triggered after a DHCP lease request packet has been sent and no reply has diff --git a/src/state.h b/src/state.h index b196a0e..129219f 100644 --- a/src/state.h +++ b/src/state.h @@ -43,7 +43,7 @@ typedef enum { DS_NUM_STATES, } dhcp_states_t; -void reinit_selecting(struct client_state_t cs[static 1], int timeout); +int reinit_selecting(struct client_state_t cs[static 1], int timeout); void packet_action(struct client_state_t cs[static 1], struct dhcpmsg packet[static 1], uint8_t msgtype,