summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2008-05-09 05:19:15 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2008-05-09 05:19:15 +0000
commit02db58fa9d0c3680d164ba2017cdba712d977365 (patch)
treea94df6006f7d3f9695e84fe8fa904d458f55654c /sbin
parentd79fe0902bd789511d7ab7d040d668007459034f (diff)
- 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@
Diffstat (limited to 'sbin')
-rw-r--r--sbin/dhclient/dhclient.c42
-rw-r--r--sbin/dhclient/dhcpd.h3
-rw-r--r--sbin/dhclient/dispatch.c30
3 files changed, 42 insertions, 33 deletions
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 <henning@openbsd.org>
@@ -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 <henning@openbsd.org>
@@ -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 <henning@openbsd.org>
@@ -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);
}