void ipv6ns_cancelprobeaddr(struct ipv6_addr *ap) { eloop_timeout_delete(ipv6ns_probeaddr, ap); if (ap->dadcallback) eloop_timeout_delete(ap->dadcallback, ap); }
pid_t daemonise(void) { #ifdef THERE_IS_NO_FORK return -1; #else pid_t pid; char buf = '\0'; int sidpipe[2], fd; eloop_timeout_delete(handle_exit_timeout, NULL); if (options & DHCPCD_DAEMONISED || !(options & DHCPCD_DAEMONISE)) return 0; /* Setup a signal pipe so parent knows when to exit. */ if (pipe(sidpipe) == -1) { syslog(LOG_ERR, "pipe: %m"); return -1; } syslog(LOG_DEBUG, "forking to background"); switch (pid = fork()) { case -1: syslog(LOG_ERR, "fork: %m"); exit(EXIT_FAILURE); /* NOTREACHED */ case 0: setsid(); /* Notify parent it's safe to exit as we've detached. */ close(sidpipe[0]); if (write(sidpipe[1], &buf, 1) == -1) syslog(LOG_ERR, "failed to notify parent: %m"); close(sidpipe[1]); if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { dup2(fd, STDIN_FILENO); dup2(fd, STDOUT_FILENO); dup2(fd, STDERR_FILENO); close(fd); } break; default: /* Wait for child to detach */ close(sidpipe[1]); if (read(sidpipe[0], &buf, 1) == -1) syslog(LOG_ERR, "failed to read child: %m"); close(sidpipe[0]); break; } /* Done with the fd now */ if (pid != 0) { syslog(LOG_INFO, "forked to background, child pid %d",pid); writepid(pidfd, pid); close(pidfd); pidfd = -1; options |= DHCPCD_FORKED; exit(EXIT_SUCCESS); } options |= DHCPCD_DAEMONISED; return pid; #endif }
static void stop_interface(struct interface *ifp) { syslog(LOG_INFO, "%s: removing interface", ifp->name); ifp->options->options |= DHCPCD_STOPPING; // Remove the interface from our list TAILQ_REMOVE(ifaces, ifp, next); dhcp6_drop(ifp, NULL); ipv6rs_drop(ifp); dhcp_drop(ifp, "STOP"); dhcp_close(ifp); eloop_timeout_delete(NULL, ifp); if (ifp->options->options & DHCPCD_DEPARTED) script_runreason(ifp, "DEPARTED"); free_interface(ifp); if (!(options & (DHCPCD_MASTER | DHCPCD_TEST))) exit(EXIT_FAILURE); }
void ipv4ll_start(void *arg) { struct interface *ifp = arg; struct dhcp_state *state = D_STATE(ifp); uint32_t addr; eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); state->probes = 0; state->claims = 0; if (state->addr.s_addr) { state->conflicts = 0; if (IN_LINKLOCAL(htonl(state->addr.s_addr))) { arp_announce(ifp); return; } } if (state->offer == NULL) addr = 0; else { addr = state->offer->yiaddr; free(state->offer); } /* We maybe rebooting an IPv4LL address. */ if (!IN_LINKLOCAL(htonl(addr))) { syslog(LOG_INFO, "%s: probing for an IPv4LL address", ifp->name); addr = 0; } if (addr == 0) state->offer = ipv4ll_find_lease(addr); else state->offer = ipv4ll_make_lease(addr); if (state->offer == NULL) syslog(LOG_ERR, "%s: %m", __func__); else { state->lease.frominfo = 0; arp_probe(ifp); } }
void ipv4ll_handle_failure(void *arg) { struct interface *ifp = arg; struct dhcp_state *state = D_STATE(ifp); time_t up; if (state->fail.s_addr == state->addr.s_addr) { /* RFC 3927 Section 2.5 */ up = uptime(); if (state->defend + DEFEND_INTERVAL > up) { syslog(LOG_WARNING, "%s: IPv4LL %d second defence failed", ifp->name, DEFEND_INTERVAL); dhcp_drop(ifp, "EXPIRE"); state->conflicts = -1; } else { syslog(LOG_DEBUG, "%s: defended IPv4LL address", ifp->name); state->defend = up; return; } } free(state->offer); state->offer = NULL; eloop_timeout_delete(ifp->ctx->eloop, NULL, ifp); if (++state->conflicts > MAX_CONFLICTS) { syslog(LOG_ERR, "%s: failed to acquire an IPv4LL address", ifp->name); if (ifp->options->options & DHCPCD_DHCP) { state->interval = RATE_LIMIT_INTERVAL / 2; dhcp_discover(ifp); } else eloop_timeout_add_sec(ifp->ctx->eloop, RATE_LIMIT_INTERVAL, ipv4ll_start, ifp); } else { eloop_timeout_add_sec(ifp->ctx->eloop, PROBE_WAIT, ipv4ll_start, ifp); } }