summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoy Marples <roy@marples.name>2009-02-19 21:15:25 +0000
committerRoy Marples <roy@marples.name>2009-02-19 21:15:25 +0000
commit8e96267bac58a9d37c5a7cb0ebbf7ad0e120db34 (patch)
treea081d43b0351cc9605c6180b4945b3d7874d3fb3
parent2d775a6758c247e2ab22e8c7f9252e818217736e (diff)
downloaddhcpcd-8e96267bac58a9d37c5a7cb0ebbf7ad0e120db34.tar.xz
If we fail to send a packet start over.
We should have our own array of interfaces to start, as interface order could change or be removed during start_interface.
-rw-r--r--dhcpcd.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/dhcpcd.c b/dhcpcd.c
index 0db9ee63..417146b1 100644
--- 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);
}