Handle DS_REBINDING and DS_RENEWING states just like DS_BOUND when the

hardware link returns after having been lost.

Make the timeout action for DS_BOUND_GW_CHECK perform ARP retransmissions
rather than just sending a single query.
This commit is contained in:
Nicholas J. Kain 2011-07-05 15:57:11 -04:00
parent 3196ad750e
commit 3205f823d9
3 changed files with 25 additions and 14 deletions

View File

@ -1,5 +1,5 @@
/* arp.c - arp ping checking /* arp.c - arp ping checking
* Time-stamp: <2011-07-05 15:37:02 njk> * Time-stamp: <2011-07-05 15:54:06 njk>
* *
* Copyright 2010-2011 Nicholas J. Kain <njkain@gmail.com> * Copyright 2010-2011 Nicholas J. Kain <njkain@gmail.com>
* *
@ -408,17 +408,21 @@ static void arp_failed(struct client_state_t *cs)
0 : RATE_LIMIT_INTERVAL); 0 : RATE_LIMIT_INTERVAL);
} }
void arp_gw_failed(struct client_state_t *cs) static void arp_gw_failed(struct client_state_t *cs)
{
log_line("arp: Gateway appears to have changed, getting new lease.");
arp_close_fd(cs);
cs->oldTimeout = 0;
reinit_selecting(cs, 0);
}
static int act_if_arp_gw_failed(struct client_state_t *cs)
{ {
if (arp_send_stats[ASEND_GW_PING].count >= gw_check_init_pingcount + 3) { if (arp_send_stats[ASEND_GW_PING].count >= gw_check_init_pingcount + 3) {
log_line("arp: Gateway appears to have changed, getting new lease"); arp_gw_failed(cs);
arp_close_fd(cs); return 1;
cs->oldTimeout = 0;
reinit_selecting(cs, 0);
return;
} }
cs->timeout = ARP_RETRANS_DELAY + 250; return 0;
arp_retransmit(cs);
} }
void arp_success(struct client_state_t *cs) void arp_success(struct client_state_t *cs)
@ -535,6 +539,8 @@ void arp_retransmit(struct client_state_t *cs)
} }
} }
if (arpState == AS_GW_CHECK || arpState == AS_GW_QUERY) { if (arpState == AS_GW_CHECK || arpState == AS_GW_QUERY) {
if (arpState == AS_GW_CHECK && act_if_arp_gw_failed(cs))
return;
long long cms = curms(); long long cms = curms();
long long rtts = arp_send_stats[ASEND_GW_PING].ts + ARP_RETRANS_DELAY; long long rtts = arp_send_stats[ASEND_GW_PING].ts + ARP_RETRANS_DELAY;
if (cms < rtts) { if (cms < rtts) {

View File

@ -1,5 +1,5 @@
/* arp.h - functions to call the interface change daemon /* arp.h - functions to call the interface change daemon
* Time-stamp: <2011-07-05 13:49:59 njk> * Time-stamp: <2011-07-05 15:54:33 njk>
* *
* Copyright 2010-2011 Nicholas J. Kain <njkain@gmail.com> * Copyright 2010-2011 Nicholas J. Kain <njkain@gmail.com>
* *
@ -52,7 +52,6 @@ int arp_close_fd(struct client_state_t *cs);
int arp_check(struct client_state_t *cs, struct dhcpmsg *packet); int arp_check(struct client_state_t *cs, struct dhcpmsg *packet);
int arp_gw_check(struct client_state_t *cs); int arp_gw_check(struct client_state_t *cs);
void arp_success(struct client_state_t *cs); void arp_success(struct client_state_t *cs);
void arp_gw_failed(struct client_state_t *cs);
void arp_retransmit(struct client_state_t *cs); void arp_retransmit(struct client_state_t *cs);
void handle_arp_response(struct client_state_t *cs); void handle_arp_response(struct client_state_t *cs);

View File

@ -23,6 +23,7 @@ static void renewing_timeout(struct client_state_t *cs);
static void rebinding_timeout(struct client_state_t *cs); static void rebinding_timeout(struct client_state_t *cs);
static void released_timeout(struct client_state_t *cs); static void released_timeout(struct client_state_t *cs);
static void collision_check_timeout(struct client_state_t *cs); static void collision_check_timeout(struct client_state_t *cs);
static void bound_gw_check_timeout(struct client_state_t *cs);
static void anfrelease(struct client_state_t *cs); static void anfrelease(struct client_state_t *cs);
static void nfrelease(struct client_state_t *cs); static void nfrelease(struct client_state_t *cs);
static void frelease(struct client_state_t *cs); static void frelease(struct client_state_t *cs);
@ -42,7 +43,7 @@ dhcp_state_t dhcp_states[] = {
{ 0, bound_timeout, frenew, nfrelease}, // BOUND { 0, bound_timeout, frenew, nfrelease}, // BOUND
{ an_packet, renewing_timeout, frenew, nfrelease}, // RENEWING { an_packet, renewing_timeout, frenew, nfrelease}, // RENEWING
{ an_packet, rebinding_timeout, frenew, nfrelease}, // REBINDING { an_packet, rebinding_timeout, frenew, nfrelease}, // REBINDING
{ 0, arp_gw_failed, frenew, anfrelease}, // BOUND_GW_CHECK { 0, bound_gw_check_timeout, frenew, anfrelease}, // BOUND_GW_CHECK
{ 0, collision_check_timeout, frenew, anfrelease}, // COLLISION_CHECK { 0, collision_check_timeout, frenew, anfrelease}, // COLLISION_CHECK
{ 0, released_timeout, frenew, frelease}, // RELEASED { 0, released_timeout, frenew, frelease}, // RELEASED
{ 0, 0, 0, 0}, // NUM_STATES { 0, 0, 0, 0}, // NUM_STATES
@ -162,6 +163,11 @@ static void collision_check_timeout(struct client_state_t *cs)
arp_retransmit(cs); arp_retransmit(cs);
} }
static void bound_gw_check_timeout(struct client_state_t *cs)
{
arp_retransmit(cs);
}
static void an_packet(struct client_state_t *cs, struct dhcpmsg *packet, static void an_packet(struct client_state_t *cs, struct dhcpmsg *packet,
uint8_t *message) uint8_t *message)
{ {
@ -294,8 +300,8 @@ void ifup_action(struct client_state_t *cs)
{ {
// If we have a lease, check to see if our gateway is still valid via ARP. // If we have a lease, check to see if our gateway is still valid via ARP.
// If it fails, state -> SELECTING. // If it fails, state -> SELECTING.
// XXX what about RENEWING and REBINDING?? if (cs->dhcpState == DS_BOUND || cs->dhcpState == DS_RENEWING ||
if (cs->dhcpState == DS_BOUND) { cs->dhcpState == DS_REBINDING) {
if (arp_gw_check(cs) == -1) if (arp_gw_check(cs) == -1)
log_warning("nl: arp_gw_check could not make arp socket, assuming lease is still OK"); log_warning("nl: arp_gw_check could not make arp socket, assuming lease is still OK");
else else