Track SSID in leases file and only consider leases from the current SSID when
authorkrw <krw@openbsd.org>
Tue, 16 Aug 2016 21:57:51 +0000 (21:57 +0000)
committerkrw <krw@openbsd.org>
Tue, 16 Aug 2016 21:57:51 +0000 (21:57 +0000)
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
sbin/dhclient/conflex.c
sbin/dhclient/dhclient.c
sbin/dhclient/dhcpd.h
sbin/dhclient/dhctoken.h

index b646746..ee20a16 100644 (file)
@@ -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;
index 92622b1..4cf3c14 100644 (file)
@@ -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 }
 };
index d2592cf..eb1ee50 100644 (file)
@@ -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 <henning@openbsd.org>
@@ -66,6 +66,9 @@
 #include <netinet/in.h>
 #include <netinet/if_ether.h>
 
+#include <net80211/ieee80211.h>
+#include <net80211/ieee80211_ioctl.h>
+
 #include <arpa/inet.h>
 
 #include <ctype.h>
@@ -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);
index d476742..38fb822 100644 (file)
@@ -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 <henning@openbsd.org>
@@ -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;
index 2c962b9..c10d152 100644 (file)
@@ -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 &&   \