diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2008-05-09 05:19:15 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2008-05-09 05:19:15 +0000 |
commit | 02db58fa9d0c3680d164ba2017cdba712d977365 (patch) | |
tree | a94df6006f7d3f9695e84fe8fa904d458f55654c /sbin/dhclient/dhclient.c | |
parent | d79fe0902bd789511d7ab7d040d668007459034f (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/dhclient/dhclient.c')
-rw-r--r-- | sbin/dhclient/dhclient.c | 42 |
1 files changed, 27 insertions, 15 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(); |