From 02db58fa9d0c3680d164ba2017cdba712d977365 Mon Sep 17 00:00:00 2001 From: Reyk Floeter Date: Fri, 9 May 2008 05:19:15 +0000 Subject: - don't give up when the link is not available on startup: dhclient goes to background and listens on the routing socket for link to come up before it retries. - renew the lease whenever the link was lost and becomes active again. - listen for link state changes on non-ethernet devices like wireless, the link state becomes active when the wireless has been associated to the AP and becomes active. this helps to automatically renew the lease when the user is roaming. ok beck@, deraadt@ --- sbin/dhclient/dhclient.c | 42 +++++++++++++++++++++++++++--------------- sbin/dhclient/dhcpd.h | 3 ++- sbin/dhclient/dispatch.c | 30 +++++++++++++----------------- 3 files changed, 42 insertions(+), 33 deletions(-) (limited to 'sbin') diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c index 512a478e7c0..15dfcf1b1e5 100644 --- a/sbin/dhclient/dhclient.c +++ b/sbin/dhclient/dhclient.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dhclient.c,v 1.117 2008/03/12 13:31:22 hugh Exp $ */ +/* $OpenBSD: dhclient.c,v 1.118 2008/05/09 05:19:14 reyk Exp $ */ /* * Copyright 2004 Henning Brauer @@ -154,6 +154,7 @@ struct iaddr defaddr = { 4 }; void routehandler(void) { + int linkstat; char msg[2048]; struct rt_msghdr *rtm; struct if_msghdr *ifm; @@ -216,6 +217,19 @@ routehandler(void) break; if ((rtm->rtm_flags & RTF_UP) == 0) goto die; + + linkstat = + LINK_STATE_IS_UP(ifm->ifm_data.ifi_link_state) ? 1 : 0; + if (linkstat != ifi->linkstat) { + debug("link state %s -> %s", + ifi->linkstat ? "up" : "down", + linkstat ? "up" : "down"); + ifi->linkstat = interface_link_status(ifi->name); + if (ifi->linkstat) { + client->state = S_INIT; + state_reboot(); + } + } break; case RTM_IFANNOUNCE: ifan = (struct if_announcemsghdr *)rtm; @@ -305,32 +319,27 @@ main(int argc, char *argv[]) read_client_conf(); - if (!interface_link_status(ifi->name)) { - int linkstat = interface_link_forceup(ifi->name); - + if (!(ifi->linkstat = interface_link_status(ifi->name))) { fprintf(stderr, "%s: no link ...", ifi->name); if (config->link_timeout == 0) { - fprintf(stderr, " giving up\n"); - if (linkstat == 0) - interface_link_forcedown(ifi->name); - exit(1); + fprintf(stderr, " sleeping\n"); + goto dispatch; } fflush(stderr); sleep(1); - while (!interface_link_status(ifi->name)) { + while (!(ifi->linkstat = interface_link_status(ifi->name))) { fprintf(stderr, "."); fflush(stderr); if (++i > config->link_timeout) { - fprintf(stderr, " giving up\n"); - if (linkstat == 0) - interface_link_forcedown(ifi->name); - exit(1); + fprintf(stderr, " sleeping\n"); + goto dispatch; } sleep(1); } fprintf(stderr, " got link\n"); } + dispatch: if ((nullfd = open(_PATH_DEVNULL, O_RDWR, 0)) == -1) error("cannot open %s: %m", _PATH_DEVNULL); @@ -383,8 +392,11 @@ main(int argc, char *argv[]) setproctitle("%s", ifi->name); - client->state = S_INIT; - state_reboot(); + if (ifi->linkstat) { + client->state = S_INIT; + state_reboot(); + } else + go_daemon(); dispatch(); diff --git a/sbin/dhclient/dhcpd.h b/sbin/dhclient/dhcpd.h index 3ad7564b1de..b3427c5f16c 100644 --- a/sbin/dhclient/dhcpd.h +++ b/sbin/dhclient/dhcpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: dhcpd.h,v 1.65 2007/02/25 16:27:20 stevesk Exp $ */ +/* $OpenBSD: dhcpd.h,v 1.66 2008/05/09 05:19:14 reyk Exp $ */ /* * Copyright (c) 2004 Henning Brauer @@ -189,6 +189,7 @@ struct interface_info { int noifmedia; int errors; u_int16_t index; + int linkstat; }; struct timeout { diff --git a/sbin/dhclient/dispatch.c b/sbin/dhclient/dispatch.c index f02aabead3c..182c08c81b9 100644 --- a/sbin/dhclient/dispatch.c +++ b/sbin/dhclient/dispatch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dispatch.c,v 1.40 2007/11/12 10:14:40 dlg Exp $ */ +/* $OpenBSD: dispatch.c,v 1.41 2008/05/09 05:19:14 reyk Exp $ */ /* * Copyright 2004 Henning Brauer @@ -133,6 +133,9 @@ dispatch(void) * a timeout registered, time out the select call then. */ another: + if (!ifi->linkstat) + interfaces_invalidated = 0; + if (timeouts) { struct timeout *t; @@ -181,7 +184,8 @@ another: } if ((fds[0].revents & (POLLIN | POLLHUP))) { - if (ifi && ifi->rfdesc != -1) + if (ifi->linkstat && + ifi && ifi->rfdesc != -1) got_one(); } if ((fds[1].revents & (POLLIN | POLLHUP))) { @@ -321,16 +325,10 @@ interface_status(void) goto active; } if (ifmr.ifm_status & IFM_AVALID) { - switch (ifmr.ifm_active & IFM_NMASK) { - case IFM_ETHER: - if (ifmr.ifm_status & IFM_ACTIVE) - goto active; - else - goto inactive; - break; - default: + if (ifmr.ifm_status & IFM_ACTIVE) + goto active; + else goto inactive; - } } inactive: return (0); @@ -442,12 +440,10 @@ interface_link_status(char *ifname) close(sock); if (ifmr.ifm_status & IFM_AVALID) { - if ((ifmr.ifm_active & IFM_NMASK) == IFM_ETHER) { - if (ifmr.ifm_status & IFM_ACTIVE) - return (1); - else - return (0); - } + if (ifmr.ifm_status & IFM_ACTIVE) + return (1); + else + return (0); } return (1); } -- cgit v1.2.3