From 778f78c3a67b888ded1ad21908570e674eea31e4 Mon Sep 17 00:00:00 2001 From: krw Date: Tue, 16 Aug 2016 21:57:51 +0000 Subject: [PATCH] Track SSID in leases file and only consider leases from the current SSID when starting up dhclient on wifi interfaces. In theory will preserve leases from other SSID's and speed up obtaining a lease by not wasting time attempting to re-acquire a lease from a different SSID. Experimental feature from n2k16 needing some real world testing before g2k16. --- sbin/dhclient/clparse.c | 16 +++++++++---- sbin/dhclient/conflex.c | 3 ++- sbin/dhclient/dhclient.c | 49 ++++++++++++++++++++++++++++++++++++++-- sbin/dhclient/dhcpd.h | 4 +++- sbin/dhclient/dhctoken.h | 3 ++- 5 files changed, 66 insertions(+), 9 deletions(-) diff --git a/sbin/dhclient/clparse.c b/sbin/dhclient/clparse.c index b64674615fd..ee20a16207f 100644 --- a/sbin/dhclient/clparse.c +++ b/sbin/dhclient/clparse.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clparse.c,v 1.96 2016/07/31 18:55:16 krw Exp $ */ +/* $OpenBSD: clparse.c,v 1.97 2016/08/16 21:57:51 krw Exp $ */ /* Parser for dhclient config and lease files. */ @@ -506,11 +506,13 @@ parse_client_lease_statement(FILE *cfile, int is_static) /* * The new lease will supersede a lease of the same type and for - * the same address. + * the same address or the same SSID. */ TAILQ_FOREACH_SAFE(lp, &client->leases, next, pl) { - if (lp->address.s_addr == lease->address.s_addr && - lp->is_static == is_static) { + if (lp->is_static != is_static) + continue; + if ((strcmp(lp->ssid, ifi->ssid) == 0) || + (lp->address.s_addr == lease->address.s_addr)) { TAILQ_REMOVE(&client->leases, lp, next); lp->is_static = 0; /* Else it won't be freed. */ free_client_lease(lp); @@ -585,6 +587,12 @@ parse_client_lease_declaration(FILE *cfile, struct client_lease *lease) case TOK_SERVER_NAME: lease->server_name = parse_string(cfile); return; + case TOK_SSID: + val = parse_string(cfile); + if (val) + strlcpy(lease->ssid, val, sizeof(lease->ssid)); + free(val); + return; case TOK_RENEW: lease->renewal = parse_date(cfile); return; diff --git a/sbin/dhclient/conflex.c b/sbin/dhclient/conflex.c index 92622b13d5c..4cf3c1440da 100644 --- a/sbin/dhclient/conflex.c +++ b/sbin/dhclient/conflex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: conflex.c,v 1.33 2016/02/06 19:30:52 krw Exp $ */ +/* $OpenBSD: conflex.c,v 1.34 2016/08/16 21:57:51 krw Exp $ */ /* Lexical scanner for dhclient config file. */ @@ -356,6 +356,7 @@ static const struct keywords { { "select-timeout", TOK_SELECT_TIMEOUT }, { "send", TOK_SEND }, { "server-name", TOK_SERVER_NAME }, + { "ssid", TOK_SSID }, { "supersede", TOK_SUPERSEDE }, { "timeout", TOK_TIMEOUT } }; diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c index d2592cf4f88..eb1ee5049ea 100644 --- a/sbin/dhclient/dhclient.c +++ b/sbin/dhclient/dhclient.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dhclient.c,v 1.379 2016/07/23 15:53:19 stsp Exp $ */ +/* $OpenBSD: dhclient.c,v 1.380 2016/08/16 21:57:51 krw Exp $ */ /* * Copyright 2004 Henning Brauer @@ -66,6 +66,9 @@ #include #include +#include +#include + #include #include @@ -423,13 +426,15 @@ char **saved_argv; int main(int argc, char *argv[]) { + struct ifreq ifr; + struct ieee80211_nwid nwid; struct stat sb; int ch, fd, socket_fd[2]; extern char *__progname; struct passwd *pw; char *ignore_list = NULL; ssize_t tailn; - int rtfilter, tailfd; + int rtfilter, sock, tailfd; saved_argv = argv; @@ -498,6 +503,19 @@ main(int argc, char *argv[]) tzset(); + /* Get the ssid if present. */ + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) + error("Can't create socket to get ssid"); + memset(&ifr, 0, sizeof(ifr)); + memset(&nwid, 0, sizeof(nwid)); + ifr.ifr_data = (caddr_t)&nwid; + strlcpy(ifr.ifr_name, ifi->name, sizeof(ifr.ifr_name)); + if (ioctl(sock, SIOCG80211NWID, (caddr_t)&ifr) == 0) { + memset(ifi->ssid, 0, sizeof(ifi->ssid)); + memcpy(ifi->ssid, nwid.i_nwid, nwid.i_len); + } + close(sock); + /* Put us into the correct rdomain */ ifi->rdomain = get_rdomain(ifi->name); if (setrtable(ifi->rdomain) == -1) @@ -741,6 +759,8 @@ state_reboot(void) /* Run through the list of leases and see if one can be used. */ TAILQ_FOREACH(lp, &client->leases, next) { + if (strcmp(lp->ssid, ifi->ssid) != 0) + continue; if (addressinuse(lp->address, ifname) && strncmp(ifname, ifi->name, IF_NAMESIZE) != 0) continue; @@ -907,6 +927,7 @@ dhcpack(struct in_addr client_addr, struct option_data *options, char *info) } client->new = lease; + memcpy(client->new->ssid, ifi->ssid, sizeof(client->new->ssid)); /* Stop resending DHCPREQUEST. */ cancel_timeout(); @@ -1034,6 +1055,9 @@ newlease: TAILQ_FOREACH_SAFE(lease, &client->leases, next, pl) { if (lease->is_static) break; + if (client->active && strcmp(client->active->ssid, + lease->ssid) != 0) + continue; if (client->active == lease) seen = 1; else if (lease->expiry <= cur_time || lease->address.s_addr == @@ -1422,6 +1446,8 @@ state_panic(void) /* Run through the list of leases and see if one can be used. */ time(&cur_time); TAILQ_FOREACH(lp, &client->leases, next) { + if (strcmp(lp->ssid, ifi->ssid) != 0) + continue; if (addressinuse(lp->address, ifname) && strncmp(ifname, ifi->name, IF_NAMESIZE) != 0) continue; @@ -1919,6 +1945,24 @@ lease_as_string(char *type, struct client_lease *lease) p += rslt; sz -= rslt; } + if (strlen(lease->ssid)) { + rslt = snprintf(p, sz, " ssid "); + if (rslt == -1 || rslt >= sz) + return (NULL); + p += rslt; + sz -= rslt; + rslt = pretty_print_string(p, sz, lease->ssid, + strlen(lease->ssid), 1); + if (rslt == -1 || rslt >= sz) + return (NULL); + p += rslt; + sz -= rslt; + rslt = snprintf(p, sz, ";\n"); + if (rslt == -1 || rslt >= sz) + return (NULL); + p += rslt; + sz -= rslt; + } for (i = 0; i < 256; i++) { if (i == DHO_DHCP_CLIENT_IDENTIFIER) { @@ -2421,6 +2465,7 @@ clone_lease(struct client_lease *oldlease) newlease->is_bootp = oldlease->is_bootp; newlease->address = oldlease->address; newlease->next_server = oldlease->next_server; + memcpy(newlease->ssid, oldlease->ssid, sizeof(newlease->ssid)); if (oldlease->server_name) { newlease->server_name = strdup(oldlease->server_name); diff --git a/sbin/dhclient/dhcpd.h b/sbin/dhclient/dhcpd.h index d47674254a7..38fb8222d56 100644 --- a/sbin/dhclient/dhcpd.h +++ b/sbin/dhclient/dhcpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dhcpd.h,v 1.154 2016/02/06 19:30:52 krw Exp $ */ +/* $OpenBSD: dhcpd.h,v 1.155 2016/08/16 21:57:51 krw Exp $ */ /* * Copyright (c) 2004 Henning Brauer @@ -69,6 +69,7 @@ struct client_lease { char *server_name; char *filename; char *resolv_conf; + char ssid[33]; unsigned int is_static; unsigned int is_bootp; unsigned int is_invalid; @@ -143,6 +144,7 @@ struct client_state { struct interface_info { struct ether_addr hw_address; char name[IFNAMSIZ]; + char ssid[33]; int bfdesc; /* bpf - reading & broadcast writing*/ int ufdesc; /* udp - unicast writing */ unsigned char *rbuf; diff --git a/sbin/dhclient/dhctoken.h b/sbin/dhclient/dhctoken.h index 2c962b9fe42..c10d1526628 100644 --- a/sbin/dhclient/dhctoken.h +++ b/sbin/dhclient/dhctoken.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dhctoken.h,v 1.9 2013/12/05 22:31:35 krw Exp $ */ +/* $OpenBSD: dhctoken.h,v 1.10 2016/08/16 21:57:51 krw Exp $ */ /* Tokens for config file lexer and parser. */ @@ -78,6 +78,7 @@ #define TOK_REJECT 292 #define TOK_LINK_TIMEOUT 294 #define TOK_IGNORE 295 +#define TOK_SSID 296 #define is_identifier(x) ((x) >= TOK_FIRST_TOKEN && \ (x) != TOK_STRING && \ -- 2.20.1