Track pending events in time by using absolute times rather than relative
timeouts.
This commit is contained in:
parent
9b3e1872cb
commit
83594bce4a
70
ndhc/arp.c
70
ndhc/arp.c
@ -67,7 +67,7 @@ typedef enum {
|
|||||||
AS_MAX,
|
AS_MAX,
|
||||||
} arp_state_t;
|
} arp_state_t;
|
||||||
|
|
||||||
static int arp_timeout[AS_MAX] = { -1, -1, -1, -1, -1 };
|
static long long arp_wake_ts[AS_MAX] = { -1, -1, -1, -1, -1 };
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ASEND_COLLISION_CHECK,
|
ASEND_COLLISION_CHECK,
|
||||||
@ -273,7 +273,7 @@ int arp_close_fd(struct client_state_t *cs)
|
|||||||
{
|
{
|
||||||
arp_min_close_fd(cs);
|
arp_min_close_fd(cs);
|
||||||
for (int i = 0; i < AS_MAX; ++i)
|
for (int i = 0; i < AS_MAX; ++i)
|
||||||
arp_timeout[i] = -1;
|
arp_wake_ts[i] = -1;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,7 +372,8 @@ int arp_check(struct client_state_t *cs, struct dhcpmsg *packet)
|
|||||||
cs->arpPrevState = cs->dhcpState;
|
cs->arpPrevState = cs->dhcpState;
|
||||||
cs->dhcpState = DS_COLLISION_CHECK;
|
cs->dhcpState = DS_COLLISION_CHECK;
|
||||||
arp_check_start_ts = arp_send_stats[ASEND_COLLISION_CHECK].ts;
|
arp_check_start_ts = arp_send_stats[ASEND_COLLISION_CHECK].ts;
|
||||||
arp_timeout[AS_COLLISION_CHECK] = probe_wait_time = PROBE_WAIT;
|
probe_wait_time = PROBE_WAIT;
|
||||||
|
arp_wake_ts[AS_COLLISION_CHECK] = arp_check_start_ts + probe_wait_time;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,7 +388,8 @@ int arp_gw_check(struct client_state_t *cs)
|
|||||||
arp_switch_state(cs, AS_GW_CHECK);
|
arp_switch_state(cs, AS_GW_CHECK);
|
||||||
cs->arpPrevState = cs->dhcpState;
|
cs->arpPrevState = cs->dhcpState;
|
||||||
cs->dhcpState = DS_BOUND_GW_CHECK;
|
cs->dhcpState = DS_BOUND_GW_CHECK;
|
||||||
arp_timeout[AS_GW_CHECK] = ARP_RETRANS_DELAY + 250;
|
arp_wake_ts[AS_GW_CHECK] =
|
||||||
|
arp_send_stats[ASEND_GW_PING].ts + ARP_RETRANS_DELAY + 250;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,7 +401,8 @@ static int arp_get_gw_hwaddr(struct client_state_t *cs)
|
|||||||
log_line("arp: Searching for gw address...");
|
log_line("arp: Searching for gw address...");
|
||||||
if (arp_ping(cs, cs->routerAddr) == -1)
|
if (arp_ping(cs, cs->routerAddr) == -1)
|
||||||
return -1;
|
return -1;
|
||||||
arp_timeout[AS_GW_QUERY] = ARP_RETRANS_DELAY + 250;
|
arp_wake_ts[AS_GW_QUERY] =
|
||||||
|
arp_send_stats[ASEND_GW_PING].ts + ARP_RETRANS_DELAY + 250;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -407,7 +410,7 @@ static void arp_failed(struct client_state_t *cs)
|
|||||||
{
|
{
|
||||||
log_line("arp: Offered address is in use -- declining");
|
log_line("arp: Offered address is in use -- declining");
|
||||||
send_decline(cs, arp_dhcp_packet.yiaddr);
|
send_decline(cs, arp_dhcp_packet.yiaddr);
|
||||||
arp_timeout[AS_COLLISION_CHECK] = -1;
|
arp_wake_ts[AS_COLLISION_CHECK] = -1;
|
||||||
reinit_selecting(cs, total_conflicts < MAX_CONFLICTS ?
|
reinit_selecting(cs, total_conflicts < MAX_CONFLICTS ?
|
||||||
0 : RATE_LIMIT_INTERVAL);
|
0 : RATE_LIMIT_INTERVAL);
|
||||||
}
|
}
|
||||||
@ -415,7 +418,7 @@ static void arp_failed(struct client_state_t *cs)
|
|||||||
static 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.");
|
log_line("arp: Gateway appears to have changed, getting new lease.");
|
||||||
arp_timeout[AS_GW_CHECK] = -1;
|
arp_wake_ts[AS_GW_CHECK] = -1;
|
||||||
reinit_selecting(cs, 0);
|
reinit_selecting(cs, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,8 +438,6 @@ void arp_set_defense_mode(struct client_state_t *cs)
|
|||||||
|
|
||||||
void arp_success(struct client_state_t *cs)
|
void arp_success(struct client_state_t *cs)
|
||||||
{
|
{
|
||||||
cs->dhcp_timeout = (cs->renewTime * 1000) - (curms() - cs->leaseStartTime);
|
|
||||||
|
|
||||||
struct in_addr temp_addr = {.s_addr = arp_dhcp_packet.yiaddr};
|
struct in_addr temp_addr = {.s_addr = arp_dhcp_packet.yiaddr};
|
||||||
log_line("arp: Lease of %s obtained, lease time %ld",
|
log_line("arp: Lease of %s obtained, lease time %ld",
|
||||||
inet_ntoa(temp_addr), cs->lease);
|
inet_ntoa(temp_addr), cs->lease);
|
||||||
@ -444,7 +445,7 @@ void arp_success(struct client_state_t *cs)
|
|||||||
cs->dhcpState = DS_BOUND;
|
cs->dhcpState = DS_BOUND;
|
||||||
cs->init = 0;
|
cs->init = 0;
|
||||||
last_conflict_ts = 0;
|
last_conflict_ts = 0;
|
||||||
arp_timeout[AS_COLLISION_CHECK] = -1;
|
arp_wake_ts[AS_COLLISION_CHECK] = -1;
|
||||||
ifchange_bind(&arp_dhcp_packet);
|
ifchange_bind(&arp_dhcp_packet);
|
||||||
if (cs->arpPrevState == DS_RENEWING || cs->arpPrevState == DS_REBINDING) {
|
if (cs->arpPrevState == DS_RENEWING || cs->arpPrevState == DS_REBINDING) {
|
||||||
arp_switch_state(cs, AS_DEFENSE);
|
arp_switch_state(cs, AS_DEFENSE);
|
||||||
@ -472,7 +473,7 @@ static void arp_gw_success(struct client_state_t *cs)
|
|||||||
arp_switch_state(cs, AS_DEFENSE);
|
arp_switch_state(cs, AS_DEFENSE);
|
||||||
arp_announcement(cs);
|
arp_announcement(cs);
|
||||||
|
|
||||||
arp_timeout[AS_GW_CHECK] = -1;
|
arp_wake_ts[AS_GW_CHECK] = -1;
|
||||||
cs->dhcpState = cs->arpPrevState;
|
cs->dhcpState = cs->arpPrevState;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -534,10 +535,10 @@ static int arp_gen_probe_wait(void)
|
|||||||
|
|
||||||
static void arp_defense_timeout(struct client_state_t *cs, long long nowts)
|
static void arp_defense_timeout(struct client_state_t *cs, long long nowts)
|
||||||
{
|
{
|
||||||
if (arp_timeout[AS_DEFENSE] != -1) {
|
if (arp_wake_ts[AS_DEFENSE] != -1) {
|
||||||
log_line("arp: Defending our lease IP.");
|
log_line("arp: Defending our lease IP.");
|
||||||
arp_announcement(cs);
|
arp_announcement(cs);
|
||||||
arp_timeout[AS_DEFENSE] = -1;
|
arp_wake_ts[AS_DEFENSE] = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -549,7 +550,7 @@ static void arp_check_timeout(struct client_state_t *cs, long long nowts)
|
|||||||
return;
|
return;
|
||||||
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 (nowts < rtts) {
|
if (nowts < rtts) {
|
||||||
arp_timeout[arpState] = rtts - nowts;
|
arp_wake_ts[arpState] = rtts;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
log_line(arpState == AS_GW_CHECK ?
|
log_line(arpState == AS_GW_CHECK ?
|
||||||
@ -557,7 +558,8 @@ static void arp_check_timeout(struct client_state_t *cs, long long nowts)
|
|||||||
"arp: Still looking for gateway hardware address...");
|
"arp: Still looking for gateway hardware address...");
|
||||||
if (arp_ping(cs, cs->routerAddr) == -1)
|
if (arp_ping(cs, cs->routerAddr) == -1)
|
||||||
log_warning("arp: Failed to send ARP ping in retransmission.");
|
log_warning("arp: Failed to send ARP ping in retransmission.");
|
||||||
arp_timeout[arpState] = ARP_RETRANS_DELAY;
|
arp_wake_ts[arpState] =
|
||||||
|
arp_send_stats[ASEND_GW_PING].ts + ARP_RETRANS_DELAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void arp_collision_timeout(struct client_state_t *cs, long long nowts)
|
static void arp_collision_timeout(struct client_state_t *cs, long long nowts)
|
||||||
@ -572,19 +574,21 @@ static void arp_collision_timeout(struct client_state_t *cs, long long nowts)
|
|||||||
long long rtts = arp_send_stats[ASEND_COLLISION_CHECK].ts +
|
long long rtts = arp_send_stats[ASEND_COLLISION_CHECK].ts +
|
||||||
probe_wait_time;
|
probe_wait_time;
|
||||||
if (nowts < rtts) {
|
if (nowts < rtts) {
|
||||||
arp_timeout[AS_COLLISION_CHECK] = rtts - nowts;
|
arp_wake_ts[AS_COLLISION_CHECK] = rtts;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (arp_ip_anon_ping(cs, arp_dhcp_packet.yiaddr) == -1)
|
if (arp_ip_anon_ping(cs, arp_dhcp_packet.yiaddr) == -1)
|
||||||
log_warning("arp: Failed to send ARP ping in retransmission.");
|
log_warning("arp: Failed to send ARP ping in retransmission.");
|
||||||
arp_timeout[AS_COLLISION_CHECK] = probe_wait_time = arp_gen_probe_wait();
|
probe_wait_time = arp_gen_probe_wait();
|
||||||
|
arp_wake_ts[AS_COLLISION_CHECK] =
|
||||||
|
arp_send_stats[ASEND_COLLISION_CHECK].ts + probe_wait_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void arp_do_defense(struct client_state_t *cs)
|
static void arp_do_defense(struct client_state_t *cs)
|
||||||
{
|
{
|
||||||
log_line("arp: detected a peer attempting to use our IP!");
|
log_line("arp: detected a peer attempting to use our IP!");
|
||||||
long long nowts = curms();
|
long long nowts = curms();
|
||||||
arp_timeout[AS_DEFENSE] = -1;
|
arp_wake_ts[AS_DEFENSE] = -1;
|
||||||
if (!last_conflict_ts ||
|
if (!last_conflict_ts ||
|
||||||
nowts - last_conflict_ts < DEFEND_INTERVAL) {
|
nowts - last_conflict_ts < DEFEND_INTERVAL) {
|
||||||
log_line("arp: Defending our lease IP.");
|
log_line("arp: Defending our lease IP.");
|
||||||
@ -594,8 +598,8 @@ static void arp_do_defense(struct client_state_t *cs)
|
|||||||
send_release(cs);
|
send_release(cs);
|
||||||
reinit_selecting(cs, 0);
|
reinit_selecting(cs, 0);
|
||||||
} else {
|
} else {
|
||||||
arp_timeout[AS_DEFENSE] =
|
arp_wake_ts[AS_DEFENSE] =
|
||||||
arp_send_stats[ASEND_ANNOUNCE].ts + DEFEND_INTERVAL - nowts;
|
arp_send_stats[ASEND_ANNOUNCE].ts + DEFEND_INTERVAL;
|
||||||
}
|
}
|
||||||
total_conflicts++;
|
total_conflicts++;
|
||||||
last_conflict_ts = nowts;
|
last_conflict_ts = nowts;
|
||||||
@ -605,7 +609,7 @@ static void arp_do_gw_query(struct client_state_t *cs)
|
|||||||
{
|
{
|
||||||
if (arp_is_query_reply(&arpreply) &&
|
if (arp_is_query_reply(&arpreply) &&
|
||||||
!memcmp(arpreply.sip4, &cs->routerAddr, 4)) {
|
!memcmp(arpreply.sip4, &cs->routerAddr, 4)) {
|
||||||
arp_timeout[AS_GW_QUERY] = -1;
|
arp_wake_ts[AS_GW_QUERY] = -1;
|
||||||
memcpy(cs->routerArp, arpreply.smac, 6);
|
memcpy(cs->routerArp, arpreply.smac, 6);
|
||||||
log_line("arp: Gateway hardware address %02x:%02x:%02x:%02x:%02x:%02x",
|
log_line("arp: Gateway hardware address %02x:%02x:%02x:%02x:%02x:%02x",
|
||||||
cs->routerArp[0], cs->routerArp[1],
|
cs->routerArp[0], cs->routerArp[1],
|
||||||
@ -714,27 +718,15 @@ void handle_arp_timeout(struct client_state_t *cs, long long nowts)
|
|||||||
arp_states[arpState].timeout_fn(cs, nowts);
|
arp_states[arpState].timeout_fn(cs, nowts);
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_arp_timeout(void)
|
long long arp_get_wake_ts(void)
|
||||||
{
|
{
|
||||||
int mt = INT_MAX;
|
long long mt = -1;
|
||||||
for (int i = 0; i < AS_MAX; ++i) {
|
for (int i = 0; i < AS_MAX; ++i) {
|
||||||
log_line("DEBUG: arp_timeout[%u] == %d", i, arp_timeout[i]);
|
if (arp_wake_ts[i] == -1)
|
||||||
if (arp_timeout[i] < mt && arp_timeout[i] >= 0)
|
continue;
|
||||||
mt = arp_timeout[i];
|
if (mt == -1 || mt > arp_wake_ts[i])
|
||||||
|
mt = arp_wake_ts[i];
|
||||||
}
|
}
|
||||||
if (mt == INT_MAX)
|
|
||||||
return -1;
|
|
||||||
return mt;
|
return mt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void arp_timeout_adj(int off)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < AS_MAX; ++i) {
|
|
||||||
if (arp_timeout[i] == -1)
|
|
||||||
continue;
|
|
||||||
arp_timeout[i] -= off;
|
|
||||||
if (arp_timeout[i] < 0)
|
|
||||||
arp_timeout[i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -55,7 +55,6 @@ void arp_set_defense_mode(struct client_state_t *cs);
|
|||||||
void arp_success(struct client_state_t *cs);
|
void arp_success(struct client_state_t *cs);
|
||||||
void handle_arp_response(struct client_state_t *cs);
|
void handle_arp_response(struct client_state_t *cs);
|
||||||
void handle_arp_timeout(struct client_state_t *cs, long long nowts);
|
void handle_arp_timeout(struct client_state_t *cs, long long nowts);
|
||||||
int get_arp_timeout(void);
|
long long arp_get_wake_ts(void);
|
||||||
void arp_timeout_adj(int off);
|
|
||||||
|
|
||||||
#endif /* ARP_H_ */
|
#endif /* ARP_H_ */
|
||||||
|
@ -30,7 +30,6 @@ struct client_state_t {
|
|||||||
int ifsPrevState;
|
int ifsPrevState;
|
||||||
int listenMode;
|
int listenMode;
|
||||||
int epollFd, signalFd, listenFd, arpFd, nlFd;
|
int epollFd, signalFd, listenFd, arpFd, nlFd;
|
||||||
int dhcp_timeout;
|
|
||||||
uint32_t clientAddr, serverAddr, routerAddr;
|
uint32_t clientAddr, serverAddr, routerAddr;
|
||||||
uint32_t lease, renewTime, rebindTime, xid;
|
uint32_t lease, renewTime, rebindTime, xid;
|
||||||
int using_dhcp_bpf;
|
int using_dhcp_bpf;
|
||||||
|
58
ndhc/ndhc.c
58
ndhc/ndhc.c
@ -161,8 +161,8 @@ static int get_clientid_mac_string(char *str, size_t slen)
|
|||||||
static void do_work(void)
|
static void do_work(void)
|
||||||
{
|
{
|
||||||
struct epoll_event events[3];
|
struct epoll_event events[3];
|
||||||
long long last_awake, nowts;
|
long long nowts;
|
||||||
int timeout, timeout_delta;
|
int timeout;
|
||||||
|
|
||||||
cs.epollFd = epoll_create1(0);
|
cs.epollFd = epoll_create1(0);
|
||||||
if (cs.epollFd == -1)
|
if (cs.epollFd == -1)
|
||||||
@ -174,7 +174,6 @@ static void do_work(void)
|
|||||||
goto jumpstart;
|
goto jumpstart;
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
log_line("DEBUG: before epoll_wait()");
|
|
||||||
int r = epoll_wait(cs.epollFd, events, 3, timeout);
|
int r = epoll_wait(cs.epollFd, events, 3, timeout);
|
||||||
if (r == -1) {
|
if (r == -1) {
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
@ -182,7 +181,6 @@ static void do_work(void)
|
|||||||
else
|
else
|
||||||
suicide("epoll_wait failed");
|
suicide("epoll_wait failed");
|
||||||
}
|
}
|
||||||
log_line("DEBUG: after epoll_wait()");
|
|
||||||
for (int i = 0; i < r; ++i) {
|
for (int i = 0; i < r; ++i) {
|
||||||
int fd = events[i].data.fd;
|
int fd = events[i].data.fd;
|
||||||
if (fd == cs.signalFd)
|
if (fd == cs.signalFd)
|
||||||
@ -197,39 +195,31 @@ static void do_work(void)
|
|||||||
suicide("epoll_wait: unknown fd");
|
suicide("epoll_wait: unknown fd");
|
||||||
}
|
}
|
||||||
|
|
||||||
nowts = curms();
|
for (;;) {
|
||||||
timeout_delta = nowts - last_awake;
|
nowts = curms();
|
||||||
|
long long arp_wake_ts = arp_get_wake_ts();
|
||||||
|
long long dhcp_wake_ts = dhcp_get_wake_ts();
|
||||||
|
if (arp_wake_ts == -1) {
|
||||||
|
if (dhcp_wake_ts != -1) {
|
||||||
|
timeout = dhcp_wake_ts - nowts;
|
||||||
|
if (timeout < 0)
|
||||||
|
timeout = 0;
|
||||||
|
} else
|
||||||
|
timeout = -1;
|
||||||
|
} else {
|
||||||
|
// If dhcp_wake_ts is -1 then we want to sleep anyway.
|
||||||
|
timeout = (arp_wake_ts < dhcp_wake_ts ?
|
||||||
|
arp_wake_ts : dhcp_wake_ts) - nowts;
|
||||||
|
if (timeout < 0)
|
||||||
|
timeout = 0;
|
||||||
|
}
|
||||||
|
|
||||||
cs.dhcp_timeout -= timeout_delta;
|
if (!timeout) {
|
||||||
if (cs.dhcp_timeout < 0)
|
|
||||||
cs.dhcp_timeout = 0;
|
|
||||||
arp_timeout_adj(timeout_delta);
|
|
||||||
|
|
||||||
int arp_timeout = get_arp_timeout();
|
|
||||||
log_line("DEBUG: arp_timeout = %d, dhcp_timeout = %d",
|
|
||||||
arp_timeout, cs.dhcp_timeout);
|
|
||||||
if (arp_timeout == -1)
|
|
||||||
timeout = cs.dhcp_timeout;
|
|
||||||
else if (arp_timeout < cs.dhcp_timeout)
|
|
||||||
timeout = arp_timeout;
|
|
||||||
else
|
|
||||||
timeout = cs.dhcp_timeout;
|
|
||||||
|
|
||||||
if (timeout <= 0) {
|
|
||||||
jumpstart:
|
jumpstart:
|
||||||
timeout_action(&cs, nowts);
|
timeout_action(&cs, nowts);
|
||||||
|
} else
|
||||||
int arp_timeout = get_arp_timeout();
|
break;
|
||||||
log_line("DEBUG: arp_timeout = %d, dhcp_timeout = %d",
|
|
||||||
arp_timeout, cs.dhcp_timeout);
|
|
||||||
if (arp_timeout == -1)
|
|
||||||
timeout = cs.dhcp_timeout;
|
|
||||||
else if (arp_timeout < cs.dhcp_timeout)
|
|
||||||
timeout = arp_timeout;
|
|
||||||
else
|
|
||||||
timeout = cs.dhcp_timeout;
|
|
||||||
}
|
}
|
||||||
last_awake = nowts;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
57
ndhc/state.c
57
ndhc/state.c
@ -12,6 +12,8 @@
|
|||||||
#include "sys.h"
|
#include "sys.h"
|
||||||
#include "random.h"
|
#include "random.h"
|
||||||
|
|
||||||
|
static long long dhcp_wake_ts = -1;
|
||||||
|
|
||||||
static void selecting_packet(struct client_state_t *cs, struct dhcpmsg *packet,
|
static void selecting_packet(struct client_state_t *cs, struct dhcpmsg *packet,
|
||||||
uint8_t *message);
|
uint8_t *message);
|
||||||
static void an_packet(struct client_state_t *cs, struct dhcpmsg *packet,
|
static void an_packet(struct client_state_t *cs, struct dhcpmsg *packet,
|
||||||
@ -62,7 +64,7 @@ void reinit_selecting(struct client_state_t *cs, int timeout)
|
|||||||
ifchange_deconfig();
|
ifchange_deconfig();
|
||||||
arp_close_fd(cs);
|
arp_close_fd(cs);
|
||||||
cs->dhcpState = DS_SELECTING;
|
cs->dhcpState = DS_SELECTING;
|
||||||
cs->dhcp_timeout = timeout;
|
dhcp_wake_ts = curms() + timeout;
|
||||||
cs->clientAddr = 0;
|
cs->clientAddr = 0;
|
||||||
num_dhcp_requests = 0;
|
num_dhcp_requests = 0;
|
||||||
arp_reset_send_stats();
|
arp_reset_send_stats();
|
||||||
@ -74,7 +76,7 @@ static void set_released(struct client_state_t *cs)
|
|||||||
ifchange_deconfig();
|
ifchange_deconfig();
|
||||||
arp_close_fd(cs);
|
arp_close_fd(cs);
|
||||||
cs->dhcpState = DS_RELEASED;
|
cs->dhcpState = DS_RELEASED;
|
||||||
cs->dhcp_timeout = -1;
|
dhcp_wake_ts = -1;
|
||||||
cs->clientAddr = 0;
|
cs->clientAddr = 0;
|
||||||
num_dhcp_requests = 0;
|
num_dhcp_requests = 0;
|
||||||
arp_reset_send_stats();
|
arp_reset_send_stats();
|
||||||
@ -89,7 +91,7 @@ static void requesting_timeout(struct client_state_t *cs, long long nowts)
|
|||||||
{
|
{
|
||||||
if (num_dhcp_requests < 5) {
|
if (num_dhcp_requests < 5) {
|
||||||
send_selecting(cs);
|
send_selecting(cs);
|
||||||
cs->dhcp_timeout = delay_timeout(num_dhcp_requests);
|
dhcp_wake_ts = nowts + delay_timeout(num_dhcp_requests);
|
||||||
num_dhcp_requests++;
|
num_dhcp_requests++;
|
||||||
} else
|
} else
|
||||||
reinit_selecting(cs, 0);
|
reinit_selecting(cs, 0);
|
||||||
@ -101,7 +103,7 @@ static void bound_timeout(struct client_state_t *cs, long long nowts)
|
|||||||
{
|
{
|
||||||
long long rnt = cs->leaseStartTime + cs->renewTime * 1000;
|
long long rnt = cs->leaseStartTime + cs->renewTime * 1000;
|
||||||
if (nowts < rnt) {
|
if (nowts < rnt) {
|
||||||
cs->dhcp_timeout = rnt - nowts;
|
dhcp_wake_ts = rnt;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cs->dhcpState = DS_RENEWING;
|
cs->dhcpState = DS_RENEWING;
|
||||||
@ -126,21 +128,17 @@ static void renewing_timeout(struct client_state_t *cs, long long nowts)
|
|||||||
{
|
{
|
||||||
long long rbt = cs->leaseStartTime + cs->rebindTime * 1000;
|
long long rbt = cs->leaseStartTime + cs->rebindTime * 1000;
|
||||||
if (nowts < rbt) {
|
if (nowts < rbt) {
|
||||||
long long wt = (rbt - nowts) / 2;
|
if (rbt - nowts < 30000) {
|
||||||
if (wt >= 30000)
|
dhcp_wake_ts = rbt;
|
||||||
send_renew(cs);
|
return;
|
||||||
else
|
}
|
||||||
wt = rbt - nowts;
|
send_renew(cs);
|
||||||
cs->dhcp_timeout = wt;
|
dhcp_wake_ts = nowts + ((rbt - nowts) / 2);
|
||||||
return;
|
} else {
|
||||||
}
|
|
||||||
long long elt = cs->leaseStartTime + cs->lease * 1000;
|
|
||||||
if (nowts < elt) {
|
|
||||||
cs->dhcpState = DS_REBINDING;
|
cs->dhcpState = DS_REBINDING;
|
||||||
cs->dhcp_timeout = (elt - nowts) / 2;
|
|
||||||
log_line("Entering rebinding state.");
|
log_line("Entering rebinding state.");
|
||||||
} else
|
rebinding_timeout(cs, nowts);
|
||||||
lease_timedout(cs);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Triggered when a DHCP rebind request has been sent and no reply has been
|
// Triggered when a DHCP rebind request has been sent and no reply has been
|
||||||
@ -151,19 +149,19 @@ static void rebinding_timeout(struct client_state_t *cs, long long nowts)
|
|||||||
{
|
{
|
||||||
long long elt = cs->leaseStartTime + cs->lease * 1000;
|
long long elt = cs->leaseStartTime + cs->lease * 1000;
|
||||||
if (nowts < elt) {
|
if (nowts < elt) {
|
||||||
long long wt = (elt - nowts) / 2;
|
if (elt - nowts < 30000) {
|
||||||
if (wt >= 30000)
|
dhcp_wake_ts = elt;
|
||||||
send_rebind(cs);
|
return;
|
||||||
else
|
}
|
||||||
wt = elt - nowts;
|
send_rebind(cs);
|
||||||
cs->dhcp_timeout = wt;
|
dhcp_wake_ts = nowts + ((elt - nowts) / 2);
|
||||||
} else
|
} else
|
||||||
lease_timedout(cs);
|
lease_timedout(cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void released_timeout(struct client_state_t *cs, long long nowts)
|
static void released_timeout(struct client_state_t *cs, long long nowts)
|
||||||
{
|
{
|
||||||
cs->dhcp_timeout = -1;
|
dhcp_wake_ts = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Can transition to DS_BOUND or DS_SELECTING.
|
// Can transition to DS_BOUND or DS_SELECTING.
|
||||||
@ -189,6 +187,7 @@ static void an_packet(struct client_state_t *cs, struct dhcpmsg *packet,
|
|||||||
// the remote server values, if they even exist, for sanity.
|
// the remote server values, if they even exist, for sanity.
|
||||||
cs->renewTime = cs->lease >> 1;
|
cs->renewTime = cs->lease >> 1;
|
||||||
cs->rebindTime = (cs->lease >> 3) * 0x7; // * 0.875
|
cs->rebindTime = (cs->lease >> 3) * 0x7; // * 0.875
|
||||||
|
dhcp_wake_ts = cs->leaseStartTime + cs->renewTime * 1000;
|
||||||
|
|
||||||
// Only check if we are either in the REQUESTING state, or if we
|
// Only check if we are either in the REQUESTING state, or if we
|
||||||
// have received a lease with a different IP than what we had before.
|
// have received a lease with a different IP than what we had before.
|
||||||
@ -200,7 +199,6 @@ static void an_packet(struct client_state_t *cs, struct dhcpmsg *packet,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cs->dhcpState = DS_BOUND;
|
cs->dhcpState = DS_BOUND;
|
||||||
cs->dhcp_timeout = cs->renewTime * 1000;
|
|
||||||
arp_set_defense_mode(cs);
|
arp_set_defense_mode(cs);
|
||||||
set_listen_none(cs);
|
set_listen_none(cs);
|
||||||
}
|
}
|
||||||
@ -222,7 +220,7 @@ static void selecting_packet(struct client_state_t *cs, struct dhcpmsg *packet,
|
|||||||
cs->xid = packet->xid;
|
cs->xid = packet->xid;
|
||||||
cs->clientAddr = packet->yiaddr;
|
cs->clientAddr = packet->yiaddr;
|
||||||
cs->dhcpState = DS_REQUESTING;
|
cs->dhcpState = DS_REQUESTING;
|
||||||
cs->dhcp_timeout = 0;
|
dhcp_wake_ts = curms();
|
||||||
num_dhcp_requests = 0;
|
num_dhcp_requests = 0;
|
||||||
} else {
|
} else {
|
||||||
log_line("No server ID in message");
|
log_line("No server ID in message");
|
||||||
@ -249,7 +247,7 @@ static void selecting_timeout(struct client_state_t *cs, long long nowts)
|
|||||||
if (num_dhcp_requests == 0)
|
if (num_dhcp_requests == 0)
|
||||||
cs->xid = libc_random_u32();
|
cs->xid = libc_random_u32();
|
||||||
send_discover(cs);
|
send_discover(cs);
|
||||||
cs->dhcp_timeout = delay_timeout(num_dhcp_requests);
|
dhcp_wake_ts = nowts + delay_timeout(num_dhcp_requests);
|
||||||
num_dhcp_requests++;
|
num_dhcp_requests++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -335,3 +333,8 @@ void force_release_action(struct client_state_t *cs)
|
|||||||
dhcp_states[cs->dhcpState].force_release_fn(cs);
|
dhcp_states[cs->dhcpState].force_release_fn(cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
long long dhcp_get_wake_ts(void)
|
||||||
|
{
|
||||||
|
return dhcp_wake_ts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ void force_release_action(struct client_state_t *cs);
|
|||||||
void ifup_action(struct client_state_t *cs);
|
void ifup_action(struct client_state_t *cs);
|
||||||
void ifnocarrier_action(struct client_state_t *cs);
|
void ifnocarrier_action(struct client_state_t *cs);
|
||||||
void ifdown_action(struct client_state_t *cs);
|
void ifdown_action(struct client_state_t *cs);
|
||||||
|
long long dhcp_get_wake_ts(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user