From e9e834fd166b925156cf8a7bb45bafaee984e454 Mon Sep 17 00:00:00 2001 From: krw Date: Wed, 6 Dec 2017 13:57:27 +0000 Subject: [PATCH] Disentangle dhclient.conf static lease handling from dynamic lease handling. Simplifies code and makes it easier to consider excising this 'feature'. --- sbin/dhclient/dhclient.c | 95 +++++++++++++++++++++++++--------------- sbin/dhclient/dhcpd.h | 3 +- 2 files changed, 61 insertions(+), 37 deletions(-) diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c index efbe1c76797..6506668b331 100644 --- a/sbin/dhclient/dhclient.c +++ b/sbin/dhclient/dhclient.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dhclient.c,v 1.535 2017/12/05 14:57:14 krw Exp $ */ +/* $OpenBSD: dhclient.c,v 1.536 2017/12/06 13:57:27 krw Exp $ */ /* * Copyright 2004 Henning Brauer @@ -168,6 +168,7 @@ void append_statement(char *, size_t, char *, char *); time_t lease_expiry(struct client_lease *); time_t lease_renewal(struct client_lease *); time_t lease_rebind(struct client_lease *); +int lease_is_static(struct client_lease *); struct client_lease *packet_to_lease(struct interface_info *, struct option_data *); @@ -176,6 +177,7 @@ int rdaemon(int); void take_charge(struct interface_info *, int); void set_default_client_identifier(struct interface_info *); struct client_lease *get_recorded_lease(struct interface_info *); +struct client_lease *get_static_lease(struct interface_info *); #define ROUNDUP(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) @@ -427,7 +429,6 @@ main(int argc, char *argv[]) const char *tail_path = "/etc/resolv.conf.tail"; struct interface_info *ifi; struct passwd *pw; - struct client_lease *lp, *nlp; char *ignore_list = NULL; ssize_t tailn; int fd, socket_fd[2]; @@ -628,13 +629,6 @@ main(int argc, char *argv[]) rewrite_client_leases(ifi); close(fd); - /* Add the static leases to the end of the list of available leases. */ - TAILQ_FOREACH_SAFE(lp, &config->static_leases, next, nlp) { - TAILQ_REMOVE(&config->static_leases, lp, next); - lp->is_static = 1; - TAILQ_INSERT_TAIL(&ifi->leases, lp, next); - } - if (strlen(path_option_db) != 0) { /* * Open 'a' so file is not truncated. The truncation @@ -971,10 +965,8 @@ dhcpnak(struct interface_info *ifi, struct option_data *options, char *info) delete_address(ifi->active->address); /* XXX Do we really want to remove a NAK'd lease from the database? */ - if (ifi->active->is_static == 0) { - TAILQ_REMOVE(&ifi->leases, ifi->active, next); - free_client_lease(ifi->active); - } + TAILQ_REMOVE(&ifi->leases, ifi->active, next); + free_client_lease(ifi->active); ifi->active = NULL; @@ -1066,8 +1058,6 @@ newlease: */ seen = 0; TAILQ_FOREACH_SAFE(lease, &ifi->leases, next, pl) { - if (lease->is_static != 0) - break; if (ifi->active == NULL) continue; if (ifi->ssid_len != lease->ssid_len) @@ -1083,7 +1073,7 @@ newlease: free_client_lease(lease); } } - if (ifi->active->is_static == 0 && seen == 0) + if (lease_is_static(ifi->active) == 0 && seen == 0) TAILQ_INSERT_HEAD(&ifi->leases, ifi->active, next); /* Write out new leases file. */ @@ -1369,6 +1359,9 @@ state_panic(struct interface_info *ifi) log_info("%s: no acceptable DHCPOFFERS received", log_procname); ifi->offer = get_recorded_lease(ifi); + if (ifi->offer == NULL) + ifi->offer = get_static_lease(ifi); + if (ifi->offer != NULL) { ifi->state = S_REQUESTING; bind_lease(ifi); @@ -1724,7 +1717,7 @@ free_client_lease(struct client_lease *lease) int i; /* Static leases are forever. */ - if (lease == NULL || lease->is_static) + if (lease == NULL || lease_is_static(lease)) return; free(lease->interface); @@ -1758,9 +1751,6 @@ rewrite_client_leases(struct interface_info *ifi) */ time(&cur_time); TAILQ_FOREACH_REVERSE(lp, &ifi->leases, client_lease_tq, next) { - /* Don't write out static leases from dhclient.conf. */ - if (lp->is_static != 0) - continue; if (lease_expiry(lp) < cur_time) continue; leasestr = lease_as_string(ifi->name, "lease", lp); @@ -2349,10 +2339,8 @@ apply_defaults(struct client_lease *lease) return newlease; cleanup: - if (newlease != NULL) { - newlease->is_static = 0; - free_client_lease(newlease); - } + + free_client_lease(newlease); fatalx("unable to apply defaults"); /* NOTREACHED */ @@ -2371,7 +2359,6 @@ clone_lease(struct client_lease *oldlease) goto cleanup; newlease->epoch = oldlease->epoch; - newlease->is_static = oldlease->is_static; newlease->address = oldlease->address; newlease->next_server = oldlease->next_server; memcpy(newlease->ssid, oldlease->ssid, sizeof(newlease->ssid)); @@ -2403,10 +2390,7 @@ clone_lease(struct client_lease *oldlease) return newlease; cleanup: - if (newlease != NULL) { - newlease->is_static = 0; - free_client_lease(newlease); - } + free_client_lease(newlease); return NULL; } @@ -2535,9 +2519,6 @@ get_recorded_lease(struct interface_info *ifi) if (lease_expiry(lp) <= cur_time) continue; - if (lp->is_static != 0) - lp->epoch = 0; - break; } @@ -2546,6 +2527,40 @@ get_recorded_lease(struct interface_info *ifi) return lp; } +struct client_lease * +get_static_lease(struct interface_info *ifi) +{ + char ifname[IF_NAMESIZE]; + time_t cur_time; + struct client_lease *lp; + int i; + + time(&cur_time); + + /* Run through the list of leases and see if one can be used. */ + i = DHO_DHCP_CLIENT_IDENTIFIER; + TAILQ_FOREACH(lp, &config->static_leases, next) { + if (lp->ssid_len != ifi->ssid_len) + continue; + if (memcmp(lp->ssid, ifi->ssid, lp->ssid_len) != 0) + continue; + if ((lp->options[i].len != 0) && ((lp->options[i].len != + config->send_options[i].len) || + memcmp(lp->options[i].data, config->send_options[i].data, + lp->options[i].len))) + continue; + if (addressinuse(ifi->name, lp->address, ifname) != 0 && + strncmp(ifname, ifi->name, IF_NAMESIZE) != 0) + continue; + + break; + } + + if (lp != NULL) + time(&lp->epoch); + + return lp; +} void set_default_client_identifier(struct interface_info *ifi) @@ -2577,9 +2592,6 @@ lease_expiry(struct client_lease *lease) { uint32_t expiry; - if (lease->is_static != 0) - return LLONG_MAX; - expiry = 43200; /* Default to 12 hours */ if (lease->options[DHO_DHCP_LEASE_TIME].len == sizeof(expiry)) { memcpy(&expiry, lease->options[DHO_DHCP_LEASE_TIME].data, @@ -2636,3 +2648,16 @@ lease_rebind(struct client_lease *lease) return lease->epoch + rebind; } + +int +lease_is_static(struct client_lease *lease) +{ + struct client_lease *lp; + + TAILQ_FOREACH(lp, &config->static_leases, next) { + if (lp == lease) + return 1; + } + + return 0; +} diff --git a/sbin/dhclient/dhcpd.h b/sbin/dhclient/dhcpd.h index e0185f70126..b3510425ab2 100644 --- a/sbin/dhclient/dhcpd.h +++ b/sbin/dhclient/dhcpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dhcpd.h,v 1.238 2017/12/03 20:53:28 krw Exp $ */ +/* $OpenBSD: dhcpd.h,v 1.239 2017/12/06 13:57:27 krw Exp $ */ /* * Copyright (c) 2004 Henning Brauer @@ -64,7 +64,6 @@ struct client_lease { char *filename; char ssid[32]; uint8_t ssid_len; - unsigned int is_static; struct option_data options[DHO_COUNT]; }; #define BOOTP_LEASE(l) ((l)->options[DHO_DHCP_MESSAGE_TYPE].len == 0) -- 2.20.1