]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
If we fail to send a packet start over.
authorRoy Marples <roy@marples.name>
Thu, 19 Feb 2009 21:15:25 +0000 (21:15 +0000)
committerRoy Marples <roy@marples.name>
Thu, 19 Feb 2009 21:15:25 +0000 (21:15 +0000)
We should have our own array of interfaces to start, as
interface order could change or be removed during start_interface.

dhcpcd.c

index 0db9ee638425ffd68ebb50628d30e914b7bae031..417146b1f47a4b0af367c54bea7c8b1cd196281e 100644 (file)
--- a/dhcpcd.c
+++ b/dhcpcd.c
@@ -311,7 +311,17 @@ send_message(struct interface *iface, int type,
        }
        free(dhcp);
        if (r == -1) {
-               stop_interface(iface);
+               /* We failed to send a packet?
+                * This should only happen if the link has gone down whilst
+                * we are working and managed to get here before we processed
+                * the link down message.
+                * Or we could be configured not to look at them or it's a
+                * buggy driver. Either way, we need to drop everything
+                * and start over. */
+               drop_config(iface, "STOP");
+               close_sockets(iface);
+               delete_timeout(NULL, iface);
+               add_timeout_sec(DHCP_ARP_FAIL, start_interface, iface);
        } else {
                if (callback)
                        add_timeout_tv(&tv, callback, iface);
@@ -1258,7 +1268,7 @@ int
 main(int argc, char **argv)
 {
        struct if_options *ifo;
-       struct interface *iface;
+       struct interface *iface, **ifs, **ifp;
        int opt, oi = 0, signal_fd, sig = 0, i, control_fd;
        size_t len;
        pid_t pid;
@@ -1486,11 +1496,23 @@ main(int argc, char **argv)
 
        if (options & DHCPCD_BACKGROUND)
                daemonise();
-       for (iface = ifaces; iface; iface = iface->next)
+       for (iface = ifaces, len = 0; iface; iface = iface->next, len++)
                init_state(iface, argc, argv);
        sort_interfaces();
-       for (iface = ifaces; iface; iface = iface->next)
-               start_interface(iface);
+       /* When we start an interface, it could be stopped right away or
+        * the order could change.
+        * We also don't want to start an interface more than once.
+        * So we store an array of ifaces instead of relying on ->next. */
+       if (len != 0) {
+               ifs = ifp = xmalloc(sizeof(*iface) * len);
+               for (iface = ifaces; iface; iface = iface->next)
+                       *ifp++ = iface;
+               ifp = ifs;
+               while (--len != 0)
+                       start_interface(*ifp++);
+               free(ifs);
+       }
+
        start_eloop();
        exit(EXIT_SUCCESS);
 }