Make renew and rebinding directly track whether DHCPREQUEST was sent.

Before it was inferred by examining timeouts.  Also, simplify
the associated timeout code so that there are no longer effectively
two redundant paths.
This commit is contained in:
Nicholas J. Kain 2020-10-19 06:05:47 -04:00
parent 4df035ced3
commit f4365897bc
2 changed files with 16 additions and 36 deletions

View File

@ -53,7 +53,8 @@ struct client_state_t {
uint32_t lease, xid;
uint8_t routerArp[6], serverArp[6];
enum arp_state server_arp_state, router_arp_state;
bool using_dhcp_bpf, arp_is_defense, check_fingerprint, program_init;
bool using_dhcp_bpf, arp_is_defense, check_fingerprint, program_init,
sent_renew_or_rebind;
bool sent_gw_query, sent_first_announce, sent_second_announce,
init_fingerprint_inprogress;
};

View File

@ -83,6 +83,7 @@ static void reinit_shared_deconfig(struct client_state_t cs[static 1])
cs->server_arp_state = ARP_QUERY;
cs->router_arp_state = ARP_QUERY;
cs->check_fingerprint = false;
cs->sent_renew_or_rebind = false;
cs->sent_gw_query = false;
cs->sent_first_announce = false;
cs->sent_second_announce = false;
@ -120,22 +121,8 @@ static int requesting_timeout(struct client_state_t cs[static 1],
return REQ_SUCCESS;
}
static bool is_renewing(struct client_state_t cs[static 1], long long nowts)
{
long long rnt = cs->leaseStartTime + cs->renewTime * 1000;
return nowts >= rnt;
}
static bool is_rebinding(struct client_state_t cs[static 1], long long nowts)
{
long long rbt = cs->leaseStartTime + cs->rebindTime * 1000;
return nowts >= rbt;
}
// Triggered when a DHCP rebind request has been sent and no reply has been
// received within the response wait time. Check to see if the lease is still
// valid, and if it is, send a broadcast DHCP renew packet. If it is not, then
// change to the SELECTING state to get a new lease.
// Called by renewing_timeout() to try to renew the lease. If all
// timeouts expire, then expire the lease and notify the caller.
static int rebinding_timeout(struct client_state_t cs[static 1],
long long nowts)
{
@ -152,17 +139,13 @@ static int rebinding_timeout(struct client_state_t cs[static 1],
client_config.interface);
return BTO_HARDFAIL;
}
cs->sent_renew_or_rebind = true;
long long ts0 = nowts + (50 + nk_random_u32(&cs->rnd_state) % 20) * 1000;
cs->dhcp_wake_ts = ts0 < elt ? ts0 : elt;
return BTO_WAIT;
}
// Triggered when a DHCP renew request has been sent and no reply has been
// received within the response wait time. This function is also directly
// called by bound_timeout() when it is time to renew a lease before it
// expires. Check to see if the lease is still valid, and if it is, send
// a unicast DHCP renew packet. If it is not, then change to the REBINDING
// state to send broadcast queries.
// Called by bound_timeout() to try to renew the lease.
static int renewing_timeout(struct client_state_t cs[static 1],
long long nowts)
{
@ -175,13 +158,14 @@ static int renewing_timeout(struct client_state_t cs[static 1],
client_config.interface);
return BTO_HARDFAIL;
}
cs->sent_renew_or_rebind = true;
long long ts0 = nowts + (50 + nk_random_u32(&cs->rnd_state) % 20) * 1000;
cs->dhcp_wake_ts = ts0 < rbt ? ts0 : rbt;
return BTO_WAIT;
}
// Triggered when the lease has been held for a significant fraction of its
// total time, and it is time to renew the lease so that it is not lost.
// Called to handle dhcp state timeouts, such as when RENEW or REBIND
// DHCPREQUESTs must be sent. Can return BTO_(WAIT|EXPIRED|HARDFAIL).
static int bound_timeout(struct client_state_t cs[static 1], long long nowts)
{
long long rnt = cs->leaseStartTime + cs->renewTime * 1000;
@ -245,6 +229,7 @@ static int extend_packet(struct client_state_t cs[static 1],
if (msgtype == DHCPACK) {
if (!validate_serverid(cs, packet, "a DHCP ACK"))
return ANP_IGNORE;
cs->sent_renew_or_rebind = false;
get_leasetime(cs, packet);
// Did we receive a lease with a different IP than we had before?
@ -267,6 +252,7 @@ static int extend_packet(struct client_state_t cs[static 1],
} else if (msgtype == DHCPNAK) {
if (!validate_serverid(cs, packet, "a DHCP NAK"))
return ANP_IGNORE;
cs->sent_renew_or_rebind = false;
log_line("%s: Our request was rejected. Searching for a new lease...",
client_config.interface);
reinit_selecting(cs, 3000);
@ -595,7 +581,7 @@ skip_to_requesting:
}
}
}
if (sev_dhcp && is_renewing(cs, nowts)) {
if (sev_dhcp && cs->sent_renew_or_rebind) {
int r = extend_packet(cs, dhcp_packet, dhcp_msgtype, dhcp_srcaddr);
if (r == ANP_SUCCESS || r == ANP_IGNORE) {
} else if (r == ANP_REJECTED) {
@ -701,14 +687,7 @@ skip_to_requesting:
} else BAD_STATE();
}
if (dhcp_timeout) {
int r;
if (is_rebinding(cs, nowts)) {
r = rebinding_timeout(cs, nowts);
} else if (is_renewing(cs, nowts)) {
r = renewing_timeout(cs, nowts);
} else {
r = bound_timeout(cs, nowts);
}
int r = bound_timeout(cs, nowts);
if (r == BTO_WAIT) {
} else if (r == BTO_EXPIRED) {
sev_dhcp = false;