Improve WPA interaction by allowing the fd to persist in the status cb
authorRoy Marples <roy@marples.name>
Tue, 12 May 2015 21:19:41 +0000 (21:19 +0000)
committerRoy Marples <roy@marples.name>
Tue, 12 May 2015 21:19:41 +0000 (21:19 +0000)
so it can be closed before actually enforcing it's closure internally.

src/dhcpcd-curses/dhcpcd-curses.c
src/libdhcpcd/dhcpcd.c
src/libdhcpcd/dhcpcd.h
src/libdhcpcd/wpa.c

index 6b7bd0cd90bfc69ba1bb4c6a9475e7b0d8eedb09..65ea1d0c34f048218d15f6794c847e2112f3bea3 100644 (file)
@@ -192,14 +192,6 @@ dispatch(void *arg)
 {
        struct ctx *ctx = arg;
 
-       if (dhcpcd_get_fd(ctx->con) == -1) {
-               warning(ctx, _("dhcpcd connection lost"));
-               eloop_event_delete(ctx->eloop, ctx->fd, 0);
-               eloop_timeout_add_msec(ctx->eloop, DHCPCD_RETRYOPEN,
-                   try_open, ctx);
-               return;
-       }
-
        dhcpcd_dispatch(ctx->con);
 }
 
@@ -244,8 +236,10 @@ status_cb(DHCPCD_CONNECTION *con,
        set_status(ctx, status_msg);
 
        if (status == DHC_DOWN) {
-               eloop_event_delete(ctx->eloop, ctx->fd, 0);
-               ctx->fd = -1;
+               int fd;
+
+               fd = dhcpcd_get_fd(ctx->con);
+               eloop_event_delete(ctx->eloop, fd, 0);
                ctx->online = ctx->carrier = false;
                eloop_timeout_delete(ctx->eloop, NULL, ctx);
                set_summary(ctx, NULL);
@@ -319,8 +313,7 @@ wpa_scan_cb(DHCPCD_WPA *wpa, void *arg)
                debug(ctx, "%s (%p)", _("no fd for WPA"), wpa);
                return;
        }
-       eloop_event_add(ctx->eloop,
-           dhcpcd_wpa_get_fd(wpa), wpa_dispatch, wpa, NULL, NULL);
+       eloop_event_add(ctx->eloop, fd, wpa_dispatch, wpa, NULL, NULL);
 
        i = dhcpcd_wpa_if(wpa);
        if (i == NULL) {
@@ -395,8 +388,6 @@ wpa_scan_cb(DHCPCD_WPA *wpa, void *arg)
        }
 }
 
-/*
- * XXXX Fixme, ideally in the wpa_dispatch
 static void
 wpa_status_cb(DHCPCD_WPA *wpa,
     unsigned int status, const char *status_msg, void *arg)
@@ -408,7 +399,11 @@ wpa_status_cb(DHCPCD_WPA *wpa,
        i = dhcpcd_wpa_if(wpa);
        debug(ctx, _("%s: WPA status %s"), i->ifname, status_msg);
        if (status == DHC_DOWN) {
-               eloop_event_delete(ctx->eloop, -1, NULL, wpa, 0);
+               int fd;
+
+               fd = dhcpcd_wpa_get_fd(wpa);
+               eloop_event_delete(ctx->eloop, fd, 0);
+               dhcpcd_wpa_close(wpa);
                TAILQ_FOREACH_SAFE(w, &ctx->wi_scans, next, wn) {
                        if (w->interface == i) {
                                TAILQ_REMOVE(&ctx->wi_scans, w, next);
@@ -418,7 +413,6 @@ wpa_status_cb(DHCPCD_WPA *wpa,
                }
        }
 }
-*/
 
 static void
 bg_scan(void *arg)
@@ -464,7 +458,7 @@ signal_cb(int sig, void *arg)
                debug(ctx, ("SIGHUP caught, ignoring"));
                break;
        case SIGPIPE:
-               debug(ctx, ("SIGPIPE caught, ignoring"));
+               /* ignore and don't report */
                break;
        }
 }
@@ -539,7 +533,7 @@ main(void)
        dhcpcd_set_status_callback(ctx.con, status_cb, &ctx);
        dhcpcd_set_if_callback(ctx.con, if_cb, &ctx);
        dhcpcd_wpa_set_scan_callback(ctx.con, wpa_scan_cb, &ctx);
-       //dhcpcd_wpa_set_status_callback(ctx.con, wpa_status_cb, &ctx);
+       dhcpcd_wpa_set_status_callback(ctx.con, wpa_status_cb, &ctx);
 
        eloop_timeout_add_sec(ctx.eloop, 0, try_open, &ctx);
        eloop_timeout_add_msec(ctx.eloop, DHCPCD_WPA_SCAN_SHORT,
index 73f0ee4ea64a979f3d0b132fadff9604953ddfca..4f5635bc42f22cda579cfd56a5053658bc03608e 100644 (file)
@@ -68,7 +68,7 @@
 #define iswhite(c)     (c == ' ' || c == '\t' || c == '\n')
 #endif
 
-static const char * const dhcpcd_cstates[DHC_MAX] = {
+const char * const dhcpcd_cstates[DHC_MAX] = {
        "unknown",
        "down",
        "opened",
@@ -1105,7 +1105,13 @@ dhcpcd_close(DHCPCD_CONNECTION *con)
 
        assert(con);
 
-       con->open = false;
+       if (con->open) {
+               if (con->command_fd != -1)
+                       shutdown(con->command_fd, SHUT_RDWR);
+               if (con->listen_fd != -1)
+                       shutdown(con->listen_fd, SHUT_RDWR);
+               con->open = false;
+       }
 
        /* Shut down WPA listeners as they aren't much good without dhcpcd.
         * They'll be restarted anyway when dhcpcd comes back up. */
@@ -1128,11 +1134,6 @@ dhcpcd_close(DHCPCD_CONNECTION *con)
                con->interfaces = nif;
        }
 
-       if (con->command_fd != -1)
-               shutdown(con->command_fd, SHUT_RDWR);
-       if (con->listen_fd != -1)
-               shutdown(con->listen_fd, SHUT_RDWR);
-
        update_status(con, DHC_DOWN);
 
        if (con->command_fd != -1) {
index 6cfc2579f63d3623a5f1120cfa2da112f539b8a2..35234c4cdcd9cef9e173082c9583345e7faf59cf 100644 (file)
@@ -75,6 +75,7 @@ extern "C" {
 #define DHC_CONNECTING          5
 #define DHC_CONNECTED           6
 #define DHC_MAX                         7
+extern const char * const dhcpcd_cstates[];
 
 #define DHT_UNKNOWN             0
 #define DHT_LINK                1
@@ -186,7 +187,7 @@ typedef struct dhcpcd_wi_hist {
 typedef struct dhcpcd_wpa {
        struct dhcpcd_wpa *next;
        char ifname[IF_NAMESIZE];
-       bool open;
+       unsigned int status;
        int command_fd;
        char *command_path;
        int listen_fd;
@@ -297,6 +298,7 @@ bool dhcpcd_wpa_set_network(DHCPCD_WPA *, int, const char *, const char *);
 int dhcpcd_wpa_find_network_new(DHCPCD_WPA *, const char *);
 bool dhcpcd_wpa_command(DHCPCD_WPA *, const char *);
 bool dhcpcd_wpa_command_arg(DHCPCD_WPA *, const char *, const char *);
+unsigned int dhcpcd_wpa_status(DHCPCD_WPA *, const char **);
 
 bool dhcpcd_wpa_ping(DHCPCD_WPA *);
 bool dhcpcd_wpa_can_background_scan(DHCPCD_WPA *);
index 282a26921eadc3bed2dda9ee7e1507d2fb267827..7be1b2538a112b62eaccecba49f0d006e914a6d0 100644 (file)
@@ -131,6 +131,19 @@ dhcpcd_wpa_command(DHCPCD_WPA *wpa, const char *cmd)
            strcmp(buf, "OK\n")) ? false : true;
 }
 
+static void
+dhcpcd_wpa_update_status(DHCPCD_WPA *wpa, unsigned int status)
+{
+
+       if (wpa->status != status) {
+               wpa->status = status;
+               if (wpa->con->wpa_status_cb)
+                       wpa->con->wpa_status_cb(wpa,
+                           wpa->status, dhcpcd_cstates[wpa->status],
+                           wpa->con->wpa_status_context);
+       }
+}
+
 bool
 dhcpcd_wpa_ping(DHCPCD_WPA *wpa)
 {
@@ -844,18 +857,16 @@ dhcpcd_wpa_close(DHCPCD_WPA *wpa)
 
        assert(wpa);
 
-       if (wpa->command_fd == -1 || !wpa->open)
+       if (wpa->command_fd == -1)
                return;
 
-       wpa->open = false;
        dhcpcd_attach_detach(wpa, false);
-       shutdown(wpa->command_fd, SHUT_RDWR);
-       shutdown(wpa->listen_fd, SHUT_RDWR);
 
-       if (wpa->con->wpa_status_cb)
-               wpa->con->wpa_status_cb(wpa,
-                   DHC_DOWN, "down",
-                   wpa->con->wpa_status_context);
+       if (wpa->status != DHC_DOWN) {
+               shutdown(wpa->command_fd, SHUT_RDWR);
+               shutdown(wpa->listen_fd, SHUT_RDWR);
+               dhcpcd_wpa_update_status(wpa, DHC_DOWN);
+       }
 
        close(wpa->command_fd);
        wpa->command_fd = -1;
@@ -891,12 +902,13 @@ dhcpcd_wpa_new(DHCPCD_CONNECTION *con, const char *ifname)
        if (wpa)
                return wpa;
 
-       wpa = malloc(sizeof(*wpa));
+       wpa = calloc(1, sizeof(*wpa));
        if (wpa == NULL)
                return NULL;
 
        wpa->con = con;
        strlcpy(wpa->ifname, ifname, sizeof(wpa->ifname));
+       wpa->status = DHC_DOWN;
        wpa->command_fd = wpa->listen_fd = -1;
        wpa->command_path = wpa->listen_path = NULL;
        wpa->next = con->wpa;
@@ -927,11 +939,10 @@ dhcpcd_wpa_open(DHCPCD_WPA *wpa)
        char *cmd_path = NULL, *list_path = NULL;
 
        if (wpa->listen_fd != -1) {
-               if (!wpa->open) {
-                       errno = EISCONN;
-                       return -1;
-               }
-               return wpa->listen_fd;
+               if (wpa->status == DHC_CONNECTED)
+                       return wpa->listen_fd;
+               errno = EISCONN;
+               return -1;
        }
 
        cmd_fd = wpa_open(wpa->ifname, &cmd_path);
@@ -942,7 +953,7 @@ dhcpcd_wpa_open(DHCPCD_WPA *wpa)
        if (list_fd == -1)
                goto fail;
 
-       wpa->open = true;
+       wpa->status = DHC_CONNECTING;
        wpa->attached = false;
        wpa->command_fd = cmd_fd;
        wpa->command_path = cmd_path;
@@ -953,6 +964,7 @@ dhcpcd_wpa_open(DHCPCD_WPA *wpa)
                return -1;
        }
 
+       dhcpcd_wpa_update_status(wpa, DHC_CONNECTED);
        if (wpa->con->wi_scanresults_cb)
                wpa->con->wi_scanresults_cb(wpa,
                    wpa->con->wi_scanresults_context);
@@ -972,12 +984,22 @@ fail:
        return -1;
 }
 
+unsigned int
+dhcpcd_wpa_status(DHCPCD_WPA *wpa, const char **status_msg)
+{
+
+       assert(wpa);
+       if (status_msg)
+               *status_msg = dhcpcd_cstates[wpa->status];
+       return wpa->status;
+}
+
 int
 dhcpcd_wpa_get_fd(DHCPCD_WPA *wpa)
 {
 
        assert(wpa);
-       return wpa->open ? wpa->listen_fd : -1;
+       return wpa->listen_fd;
 }
 
 void