Use a helper to ensure xid always changes when we advance it.

The purpose of the changing xid is to prevent misinterpreting
delayed messages, and the rare chance where it's randomly the
same breaks this sequence-id property.
This commit is contained in:
Nicholas J. Kain 2022-08-28 04:41:11 -04:00
parent 9b8e2facbf
commit 4d739acbdd
No known key found for this signature in database
3 changed files with 11 additions and 4 deletions

2
dhcp.c
View File

@ -413,7 +413,7 @@ static void init_packet(struct dhcpmsg *packet, uint8_t type)
ssize_t send_discover(struct client_state_t *cs) ssize_t send_discover(struct client_state_t *cs)
{ {
cs->xid = nk_random_u32(&cs->rnd_state); advance_xid(cs);
struct dhcpmsg packet = {.xid = cs->xid}; struct dhcpmsg packet = {.xid = cs->xid};
init_packet(&packet, DHCPDISCOVER); init_packet(&packet, DHCPDISCOVER);
if (cs->clientAddr) if (cs->clientAddr)

7
ndhc.h
View File

@ -86,5 +86,12 @@ void signal_exit(int status);
int get_clientid_string(const char *str, size_t slen); int get_clientid_string(const char *str, size_t slen);
void print_version(void); void print_version(void);
static inline void advance_xid(struct client_state_t *cs) {
uint32_t o = cs->xid;
do {
cs->xid = nk_random_u32(&cs->rnd_state);
} while (cs->xid == o);
}
#endif #endif

View File

@ -53,7 +53,7 @@ static int delay_timeout(struct client_state_t *cs, size_t numpackets)
static void reinit_shared_deconfig(struct client_state_t *cs) static void reinit_shared_deconfig(struct client_state_t *cs)
{ {
nk_random_init(&cs->rnd_state); nk_random_init(&cs->rnd_state);
cs->xid = nk_random_u32(&cs->rnd_state); advance_xid(cs);
cs->clientAddr = 0; cs->clientAddr = 0;
cs->num_dhcp_requests = 0; cs->num_dhcp_requests = 0;
cs->num_dhcp_renews = 0; cs->num_dhcp_renews = 0;
@ -224,7 +224,7 @@ static int extend_packet(struct client_state_t *cs,
clibuf, sizeof clibuf); clibuf, sizeof clibuf);
log_line("%s: Server is now offering IP %s. Validating...", log_line("%s: Server is now offering IP %s. Validating...",
client_config.interface, clibuf); client_config.interface, clibuf);
cs->xid = nk_random_u32(&cs->rnd_state); advance_xid(cs);
return ANP_CHECK_IP; return ANP_CHECK_IP;
} else { } else {
log_line("%s: Lease refreshed to %u seconds.", log_line("%s: Lease refreshed to %u seconds.",
@ -233,7 +233,7 @@ static int extend_packet(struct client_state_t *cs,
log_line("%s: Failed to create ARP defense socket.", log_line("%s: Failed to create ARP defense socket.",
client_config.interface); client_config.interface);
stop_dhcp_listen(cs); stop_dhcp_listen(cs);
cs->xid = nk_random_u32(&cs->rnd_state); advance_xid(cs);
return ANP_SUCCESS; return ANP_SUCCESS;
} }
} else if (msgtype == DHCPNAK) { } else if (msgtype == DHCPNAK) {