Skip to content

Commit

Permalink
dhcp4: cleanup retransmissions and state changes
Browse files Browse the repository at this point in the history
Also do not calculate retransmission times using unrelated
defer and acquire timeouts and fix the lease acquired time
(transmit start) vs secs (start time) in offer request.
  • Loading branch information
mtomaschewski committed Oct 6, 2022
1 parent a1ee804 commit 3f0c42b
Show file tree
Hide file tree
Showing 4 changed files with 337 additions and 224 deletions.
29 changes: 9 additions & 20 deletions src/dhcp4/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,6 @@ ni_dhcp4_acquire(ni_dhcp4_device_t *dev, const ni_dhcp4_request_t *info)

config = xcalloc(1, sizeof(*config));

/* RFC 2131 4.1 suggests these values */
config->capture_retry_timeout = NI_DHCP4_RESEND_TIMEOUT_INIT;
config->capture_max_timeout = NI_DHCP4_RESEND_TIMEOUT_MAX;

config->dry_run = info->dry_run;
config->start_delay = info->start_delay;
config->defer_timeout = info->defer_timeout;
Expand Down Expand Up @@ -347,9 +343,10 @@ ni_dhcp4_acquire(ni_dhcp4_device_t *dev, const ni_dhcp4_request_t *info)

if (ni_log_facility(NI_TRACE_DHCP)) {
ni_trace("Received request:");
ni_trace(" start-delay %s", ni_sprint_timeout(config->start_delay));
ni_trace(" defer-timeout %s", ni_sprint_timeout(config->defer_timeout));
ni_trace(" acquire-timeout %s", ni_sprint_timeout(config->acquire_timeout));
ni_trace(" max lease-time %s", ni_sprint_timeout(config->max_lease_time));
ni_trace(" start-delay %s", ni_sprint_timeout(config->start_delay));
ni_trace(" hostname %s", config->hostname[0]? config->hostname : "<none>");
if (config->fqdn.enabled == NI_TRISTATE_ENABLE) {
ni_trace(" fqdn update %s, encode %s, qualify %s",
Expand Down Expand Up @@ -382,7 +379,6 @@ ni_dhcp4_acquire(ni_dhcp4_device_t *dev, const ni_dhcp4_request_t *info)
if (config->client_id.len && !ni_opaque_eq(&config->client_id, &dev->lease->dhcp4.client_id)) {
ni_debug_dhcp("%s: lease doesn't match request", dev->ifname);
ni_dhcp4_device_drop_lease(dev);
dev->notify = 1;
} else {
/* Lease may be good */
dev->fsm.state = NI_DHCP4_STATE_REBOOT;
Expand Down Expand Up @@ -642,7 +638,6 @@ ni_dhcp4_device_start(ni_dhcp4_device_t *dev)
unsigned int sec;

ni_dhcp4_device_drop_buffer(dev);
dev->failed = 0;

nc = ni_global_state_handle(0);
if(!nc || !(ifp = ni_netdev_by_index(nc, dev->link.ifindex))) {
Expand Down Expand Up @@ -703,7 +698,6 @@ ni_dhcp4_device_prepare_message(void *data)
int
ni_dhcp4_device_send_message_broadcast(ni_dhcp4_device_t *dev, unsigned int msg_code, ni_addrconf_lease_t *lease)
{
ni_timeout_param_t timeout;
int rv;

dev->transmit.msg_code = msg_code;
Expand All @@ -730,16 +724,9 @@ ni_dhcp4_device_send_message_broadcast(ni_dhcp4_device_t *dev, unsigned int msg_
case DHCP4_DISCOVER:
case DHCP4_REQUEST:
case DHCP4_INFORM:
memset(&timeout, 0, sizeof(timeout));
timeout.timeout = dev->config->capture_retry_timeout;
timeout.increment = -1;
timeout.max_timeout = dev->config->capture_timeout;
timeout.nretries = -1;
timeout.jitter.min = -1;/* add a random jitter of +/-1 sec */
timeout.jitter.max = 1;
timeout.timeout_callback = ni_dhcp4_device_prepare_message;
timeout.timeout_data = dev;
rv = ni_capture_send(dev->capture, &dev->message, &timeout);
dev->transmit.params.timeout_callback = ni_dhcp4_device_prepare_message;
dev->transmit.params.timeout_data = dev;
rv = ni_capture_send(dev->capture, &dev->message, &dev->transmit.params);
break;

default:
Expand Down Expand Up @@ -787,14 +774,16 @@ ni_dhcp4_device_send_message_unicast(ni_dhcp4_device_t *dev, unsigned int msg_co
void
ni_dhcp4_device_disarm_retransmit(ni_dhcp4_device_t *dev)
{
/* Clear transmit struct except of transmit.start */
dev->transmit.msg_code = 0;
memset(&dev->transmit.params, 0, sizeof(dev->transmit.params));
ni_addrconf_lease_drop(&dev->transmit.lease);

/* Clear retransmit timer */
/* Clear capture retransmit timer params */
if (dev->capture)
ni_capture_disarm_retransmit(dev->capture);

/* Drop the message buffer */
/* Drop the (raw) message buffer content */
ni_dhcp4_device_drop_buffer(dev);
}

Expand Down
12 changes: 5 additions & 7 deletions src/dhcp4/dhcp4.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,9 @@ typedef struct ni_dhcp4_device {
ni_capture_t * capture;
int listen_fd; /* for DHCP4 only */

unsigned int failed : 1,
notify : 1;

struct {
struct timeval start;
ni_timeout_param_t params;
unsigned int msg_code;
ni_addrconf_lease_t * lease;
} transmit;
Expand Down Expand Up @@ -94,7 +93,10 @@ typedef struct ni_dhcp4_device {
#define NI_DHCP4_START_DELAY_MAX 10 /* seconds */
#define NI_DHCP4_RESEND_TIMEOUT_INIT 4 /* seconds */
#define NI_DHCP4_RESEND_TIMEOUT_MAX 64 /* seconds */
#define NI_DHCP4_DISCOVER_RESTART (NI_DHCP4_RESEND_TIMEOUT_MAX<<1)
#define NI_DHCP4_REQUEST_TIMEOUT 60 /* seconds */
#define NI_DHCP4_REBOOT_TIMEOUT NI_DHCP4_REQUEST_TIMEOUT
#define NI_DHCP4_DECLINE_BACKOFF 10 /* seconds */
#define NI_DHCP4_NAK_BACKOFF_MAX 60 /* seconds */
#define NI_DHCP4_ARP_TIMEOUT 200 /* msec */

Expand Down Expand Up @@ -199,10 +201,6 @@ struct ni_dhcp4_config {

unsigned int start_delay;
unsigned int defer_timeout;
unsigned int capture_retry_timeout; /* timeout for first request */
unsigned int capture_max_timeout; /* timeout for the capture */
unsigned int capture_timeout; /* timeout for actual capture, then fsm restarts */
unsigned int elapsed_timeout; /* elapsed time within fsm */
unsigned int acquire_timeout; /* 0 means retry forever */

/* A combination of DHCP4_DO_* flags above */
Expand Down
Loading

0 comments on commit 3f0c42b

Please sign in to comment.