diff --git a/ndhc/arp.c b/ndhc/arp.c index 8052383..c24a8c7 100644 --- a/ndhc/arp.c +++ b/ndhc/arp.c @@ -85,13 +85,14 @@ out: return -1; } -void arp_close_fd(struct client_state_t *cs) +int arp_close_fd(struct client_state_t *cs) { if (cs->arpFd == -1) - return; + return 0; epoll_del(cs, cs->arpFd); close(cs->arpFd); cs->arpFd = -1; + return 1; } // Returns 0 on success, -1 on failure. diff --git a/ndhc/arp.h b/ndhc/arp.h index c661a88..5197321 100644 --- a/ndhc/arp.h +++ b/ndhc/arp.h @@ -49,7 +49,7 @@ struct arpMsg { uint8_t pad[18]; /* 2a pad for min. ethernet payload (60 bytes) */ }; -void arp_close_fd(struct client_state_t *cs); +int arp_close_fd(struct client_state_t *cs); int arp_check(struct client_state_t *cs, struct dhcpmsg *packet); int arp_gw_check(struct client_state_t *cs); int arp_get_gw_hwaddr(struct client_state_t *cs); diff --git a/ndhc/state.c b/ndhc/state.c index 498bf20..f614000 100644 --- a/ndhc/state.c +++ b/ndhc/state.c @@ -260,31 +260,32 @@ static void frelease(struct client_state_t *cs) cs->timeout = -1; } -// XXX: DS_ARP_CHECK_GW? Also split this up? static void frenew(struct client_state_t *cs) { log_line("Forcing a DHCP renew..."); retry: switch (cs->dhcpState) { case DS_BOUND: + case DS_BOUND_GW_CHECK: + arp_close_fd(cs); + cs->dhcpState = DS_RENEWING; change_listen_mode(cs, LM_KERNEL); + send_renew(cs->xid, cs->serverAddr, cs->requestedIP); + break; case DS_ARP_CHECK: // Cancel arp ping in progress and treat as previous state. - epoll_del(cs, cs->arpFd); - close(cs->arpFd); - cs->arpFd = -1; - cs->dhcpState = cs->arpPrevState; + if (arp_close_fd(cs)) + cs->dhcpState = cs->arpPrevState; goto retry; - case DS_REQUESTING: case DS_RELEASED: change_listen_mode(cs, LM_RAW); cs->dhcpState = DS_SELECTING; break; case DS_RENEWING: case DS_REBINDING: - case DS_SELECTING: - default: break; + default: + return; } cs->packetNum = 0; cs->timeout = 0;