struct timeval start;
struct timeval timeout;
struct timeval stop;
+ struct timeval exit;
int state;
int messages;
time_t nakoff;
*state->pid_fd = -1;
}
- sigprocmask(SIG_SETMASK, &old, NULL);
-
state->state = STATE_BOUND;
+ timerclear(&state->exit);
+ sigprocmask(SIG_SETMASK, &old, NULL);
if (pid == 0) {
state->options |= DHCPCD_DAEMONISED;
return 0;
}
-
state->options |= DHCPCD_PERSISTENT | DHCPCD_FORKED;
return -1;
}
state->nakoff = 1;
state->options = options->options;
timerclear(&tv);
+ get_time(&state->start);
if (options->request_address.s_addr == 0 &&
(options->options & DHCPCD_INFORM ||
state->state = STATE_BOUND;
tv.tv_sec = state->lease.renewaltime;
#endif
- get_time(&state->timeout);
- timeradd(&state->timeout, &tv, &state->timeout);
+ timeradd(&state->start, &tv, &state->timeout);
}
#endif
} else {
#endif
if (state->options & DHCPCD_LINK) {
open_link_socket(iface);
- if (carrier_status(iface->name) == 0) {
- if (!(state->options & DHCPCD_BACKGROUND))
- logger(LOG_INFO, "waiting for carrier");
+ if (carrier_status(iface->name) == 0)
state->state = STATE_CARRIER;
- tv.tv_sec = options->timeout;
- tv.tv_usec = 0;
- get_time(&state->start);
- timeradd(&state->start, &tv, &state->stop);
- }
}
+ if (options->timeout > 0 &&
+ state->options & DHCPCD_DAEMONISE &&
+ !(state->options & DHCPCD_BACKGROUND))
+ {
+ tv.tv_sec = options->timeout;
+ tv.tv_usec = 0;
+ timeradd(&state->start, &tv, &state->exit);
+ }
return 0;
}
}
ref = NULL;
+ if (timerisset(&state->exit) &&
+ timercmp(&state->exit, &now, >))
+ ref = &state->exit;
if (timerisset(&state->stop) &&
- timercmp(&state->stop, &now, >))
+ timercmp(&state->stop, &now, >) &&
+ (!ref || timercmp(&state->stop, ref, <)))
ref = &state->stop;
if (timerisset(&state->timeout) &&
timercmp(&state->timeout, &now, >) &&
if (state->lease.leasetime == ~0U &&
state->state == STATE_BOUND)
{
- logger(LOG_DEBUG, "waiting for infinity");
+ if (last_stop_sec != INFTIM)
+ logger(LOG_DEBUG, "waiting for infinity");
timeout = INFTIM;
- } else if (state->state == STATE_CARRIER && !ref)
+ } else if (state->state == STATE_CARRIER && !ref) {
+ if (last_stop_sec != INFTIM)
+ logger(LOG_DEBUG, "waiting for carrier");
timeout = INFTIM;
- else {
+ } else {
if (state->interface->raw_fd != -1) {
fds[nfds].fd = state->interface->raw_fd;
fds[nfds].events = POLLIN;
wait_again:
get_time(&now);
- if (timeout != INFTIM) {
+ if (timeout == INFTIM)
+ last_stop_sec = INFTIM;
+ else {
if (!ref)
return 0;
timersub(ref, &now, &d);
}
#endif
+ if (timerisset(&state->exit)) {
+ get_time(&tv);
+ if (timercmp(&tv, &state->exit, >))
+ return handle_timeout_fail(state, options);
+ }
if (timerisset(&state->stop)) {
- get_time(&state->timeout);
- if (timercmp(&state->timeout, &state->stop, >))
+ get_time(&tv);
+ if (timercmp(&tv, &state->stop, >))
return handle_timeout_fail(state, options);
}
timerclear(&tv);
switch(state->state) {
case STATE_CARRIER:
- logger(LOG_INFO, "waiting for carrier");
- get_time(&state->start);
- tv.tv_sec = options->timeout;
- timeradd(&state->start, &tv, &state->stop);
+ if (timerisset(&state->exit))
+ logger(LOG_INFO, "waiting for carrier");
+ timerclear(&state->timeout);
return 0;
case STATE_INIT:
if (!(state->state && DHCPCD_DAEMONISED) &&
case STATE_RENEWING:
case STATE_REBINDING:
if (!(state->options & DHCPCD_INFORM)) {
- saddr.s_addr = dhcp->yiaddr;
- logger(LOG_INFO, "lease of %s acknowledged",
- inet_ntoa(saddr));
+ addr = xstrdup(inet_ntoa(lease->addr));
+ r = get_option_addr(&lease->server.s_addr,
+ dhcp, DHCP_SERVERID);
+ if (dhcp->servername[0] && r == 0)
+ logger(LOG_INFO, "acknowledged %s from %s `%s'",
+ addr, inet_ntoa(lease->server),
+ dhcp->servername);
+ else if (r == 0)
+ logger(LOG_INFO, "acknowledged %s from %s",
+ addr, inet_ntoa(lease->server));
+ else
+ logger(LOG_INFO, "acknowledged %s", addr);
+ free(addr);
}
break;
default:
{
struct interface *iface;
struct if_state *state = NULL;
- int retval = -1;
+ int retval = 0;
int sig;
iface = read_interface(options->interface, options->metric);
goto eexit;
for (;;) {
- retval = wait_for_packet(state);
-
/* We should always handle our signals first */
if ((sig = (signal_read(state->signal_fd))) != -1) {
retval = handle_signal(sig, state, options);
/* The interupt will be handled above */
retval = 0;
} else if (retval > 0) {
- if (fd_hasdata(iface->link_fd) == 1)
+ if (fd_hasdata(iface->link_fd) == 1) {
retval = handle_link(state);
- else if (fd_hasdata(iface->raw_fd) == 1)
+ if (retval == 0 &&
+ state->state == STATE_RENEW_REQUESTED)
+ /* Fallthrough to handle_timeout */
+ continue;
+ } else if (fd_hasdata(iface->raw_fd) == 1) {
retval = handle_dhcp_packet(state, options);
+ if (retval == 0 &&
+ state->state == STATE_REQUESTING)
+ /* Fallthrough to handle_timeout */
+ continue;
#ifdef ENABLE_ARP
- else if (fd_hasdata(iface->arp_fd) == 1) {
+ } else if (fd_hasdata(iface->arp_fd) == 1) {
retval = handle_arp_packet(state);
if (retval == -1)
retval = handle_arp_fail(state, options);
else
retval = 0;
}
-
if (retval != 0)
break;
+ retval = wait_for_packet(state);
}
eexit: