From: Roy Marples Date: Thu, 19 Feb 2009 21:15:25 +0000 (+0000) Subject: If we fail to send a packet start over. X-Git-Tag: v5.0.0~71 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8e96267bac58a9d37c5a7cb0ebbf7ad0e120db34;p=thirdparty%2Fdhcpcd.git 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. --- 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); }