summaryrefslogtreecommitdiff
path: root/sbin/dhclient/dhclient.c
diff options
context:
space:
mode:
Diffstat (limited to 'sbin/dhclient/dhclient.c')
-rw-r--r--sbin/dhclient/dhclient.c99
1 files changed, 64 insertions, 35 deletions
diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c
index f20ffda2903..6a0c323e272 100644
--- a/sbin/dhclient/dhclient.c
+++ b/sbin/dhclient/dhclient.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: dhclient.c,v 1.338 2014/11/30 00:09:30 krw Exp $ */
+/* $OpenBSD: dhclient.c,v 1.339 2014/12/05 15:47:05 krw Exp $ */
/*
* Copyright 2004 Henning Brauer <henning@openbsd.org>
@@ -113,6 +113,7 @@ void add_classless_static_routes(int, struct option_data *, struct in_addr);
int compare_lease(struct client_lease *, struct client_lease *);
void set_lease_times(struct client_lease *);
+void state_preboot(void);
void state_reboot(void);
void state_init(void);
void state_selecting(void);
@@ -351,8 +352,10 @@ routehandler(void)
#endif
ifi->linkstat = linkstat;
if (ifi->linkstat) {
+ if (client->state == S_PREBOOT)
+ state_preboot();
client->state = S_REBOOTING;
- state_reboot();
+ set_timeout_interval(1, state_reboot);
} else if (strlen(path_option_db)) {
/* Let monitoring programs see link loss. */
write_file(path_option_db,
@@ -401,7 +404,7 @@ int
main(int argc, char *argv[])
{
struct stat sb;
- int ch, fd, i = 0, socket_fd[2];
+ int ch, fd, socket_fd[2];
extern char *__progname;
struct passwd *pw;
char *ignore_list = NULL;
@@ -503,41 +506,14 @@ main(int argc, char *argv[])
TAILQ_INIT(&client->leases);
TAILQ_INIT(&client->offered_leases);
- read_client_conf(); /* Needed for config->link_timeout below! */
+ read_client_conf();
- if (interface_status(ifi->name) == 0) {
- interface_link_forceup(ifi->name);
- /* Give it up to 4 seconds of silent grace to find link */
- i = -4;
- } else
- i = 0;
-
- while (!(ifi->linkstat = interface_status(ifi->name))) {
- if (i == 0)
- fprintf(stderr, "%s: no link ...", ifi->name);
- else if (i > 0)
- fprintf(stderr, ".");
- fflush(stderr);
- if (++i > config->link_timeout) {
- fprintf(stderr, " sleeping\n");
- goto dispatch;
- }
- sleep(1);
- }
- if (i > 0)
- fprintf(stderr, " got link\n");
-
- dispatch:
if ((nullfd = open(_PATH_DEVNULL, O_RDWR, 0)) == -1)
error("cannot open %s: %s", _PATH_DEVNULL, strerror(errno));
if ((pw = getpwnam("_dhcp")) == NULL)
error("no such user: _dhcp");
- /* Register the interface. */
- if_register_receive();
- if_register_send();
-
if (path_dhclient_db == NULL && asprintf(&path_dhclient_db, "%s.%s",
_PATH_DHCLIENT_DB, ifi->name) == -1)
error("asprintf");
@@ -596,6 +572,14 @@ main(int argc, char *argv[])
sizeof(ifi->rdomain)) == -1)
error("setsockopt(ROUTE_TABLEFILTER): %s", strerror(errno));
+ ifi->linkstat = interface_status(ifi->name);
+ if (ifi->linkstat == 0)
+ interface_link_forceup(ifi->name);
+
+ /* Register the interface. */
+ if_register_receive();
+ if_register_send();
+
if (chroot(_PATH_VAREMPTY) == -1)
error("chroot");
if (chdir("/") == -1)
@@ -612,11 +596,13 @@ main(int argc, char *argv[])
setproctitle("%s", ifi->name);
- client->state = S_REBOOTING;
- if (ifi->linkstat)
+ if (ifi->linkstat) {
+ client->state = S_REBOOTING;
state_reboot();
- else
- go_daemon();
+ } else {
+ client->state = S_PREBOOT;
+ state_preboot();
+ }
dispatch();
@@ -635,6 +621,49 @@ usage(void)
exit(1);
}
+void
+state_preboot(void)
+{
+ static int preamble;
+ time_t cur_time;
+ int interval;
+
+ time(&cur_time);
+
+ if (client->first_sending == 0)
+ client->first_sending = cur_time;
+
+ interval = (int)(cur_time - client->first_sending);
+
+ if (log_perror && interval > 3) {
+ if (!preamble) {
+ fprintf(stderr, "%s: no link ....", ifi->name);
+ fflush(stderr);
+ preamble = 1;
+ }
+ if (ifi->linkstat) {
+ fprintf(stderr, " got link\n");
+ fflush(stderr);
+ } else if (interval > config->link_timeout) {
+ fprintf(stderr, " sleeping\n");
+ fflush(stderr);
+ } else {
+ fprintf(stderr, ".");
+ fflush(stderr);
+ }
+ }
+
+ if (!ifi->linkstat) {
+ if (interval > config->link_timeout) {
+ go_daemon();
+ client->state = S_REBOOTING;
+ set_timeout_interval(config->retry_interval,
+ state_reboot);
+ } else
+ set_timeout_interval(1, state_preboot);
+ }
+}
+
/*
* Called when the interface link becomes active.
*/