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:
parent
3196ad750e
commit
3205f823d9
24
ndhc/arp.c
24
ndhc/arp.c
@ -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) {
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
12
ndhc/state.c
12
ndhc/state.c
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user