PROG= dhcpcd
SRCS= common.c control.c dhcpcd.c duid.c eloop.c
-SRCS+= if-options.c if-pref.c net.c script.c signals.c
+SRCS+= if-options.c if-pref.c net.c script.c
SRCS+= dhcp-common.c
CFLAGS?= -O2
if (state == NULL) {
ifp->if_data[IF_DATA_DHCP] = calloc(1, sizeof(*state));
state = D_STATE(ifp);
+ if (state == NULL)
+ return -1;
+ /* 0 is a valid fd, so init to -1 */
+ state->raw_fd = state->udp_fd = state->arp_fd = -1;
}
- if (state == NULL)
- return -1;
state->state = DHS_INIT;
state->reason = "PREINIT";
state->nakoff = 0;
snprintf(state->leasefile, sizeof(state->leasefile),
LEASEFILE, ifp->name);
- /* 0 is a valid fd, so init to -1 */
- state->raw_fd = state->udp_fd = state->arp_fd = -1;
ifo = ifp->options;
/* We need to drop the leasefile so that start_interface
return;
}
+ /* Close any pre-existing sockets as we're starting over */
+ dhcp_close(ifp);
+
state = D_STATE(ifp);
state->start_uptime = uptime();
free(state->offer);
return 0;
}
+void
+dhcp6_reboot(struct interface *ifp)
+{
+ struct dhcp6_state *state;
+
+ state = D6_STATE(ifp);
+ if (state && state->state == DH6S_BOUND)
+ dhcp6_startrebind(ifp);
+}
+
static void
dhcp6_freedrop(struct interface *ifp, int drop, const char *reason)
{
int dhcp6_addrexists(const struct ipv6_addr *);
int dhcp6_find_delegates(struct interface *);
int dhcp6_start(struct interface *, enum DH6S);
+void dhcp6_reboot(struct interface *);
ssize_t dhcp6_env(char **, const char *, const struct interface *,
const struct dhcp6_message *, ssize_t);
void dhcp6_free(struct interface *);
#define dhcp6_addrexists(a)
#define dhcp6_find_delegates(a);
#define dhcp6_start(a, b) 0
+#define dhcp6_reboot(a)
#define dhcp6_env(a, b, c, d, e)
#define dhcp6_free(a)
#define dhcp6_drop(a, b)
#include "net.h"
#include "platform.h"
#include "script.h"
-#include "signals.h"
struct if_head *ifaces = NULL;
char vendor[VENDORCLASSID_MAX_LEN];
char **ifdv = NULL;
sigset_t dhcpcd_sigset;
+const int handle_sigs[] = {
+ SIGALRM,
+ SIGHUP,
+ SIGINT,
+ SIGPIPE,
+ SIGTERM,
+ SIGUSR1,
+ 0
+};
static char *cffile;
static char *pidfile;
oldopts = ifp->options->options;
configure_interface(ifp, argc, argv);
dhcp_reboot_newopts(ifp, oldopts);
+ dhcp6_reboot(ifp);
start_interface(ifp);
}
ipv4_applyaddr(ifn);
free_interface(ifp);
} else {
- TAILQ_INSERT_TAIL(ifaces, ifp, next);
init_state(ifp, argc, argv);
+ TAILQ_INSERT_TAIL(ifaces, ifp, next);
start_interface(ifp);
}
}
/* ARGSUSED */
static void
-sig_reboot(__unused void *arg)
+sig_reboot(void *arg)
{
+ siginfo_t *siginfo = arg;
struct if_options *ifo;
int i;
+ syslog(LOG_INFO, "received SIGALRM from PID %d, rebinding",
+ (int)siginfo->si_pid);
+
for (i = 0; i < ifac; i++)
free(ifav[i]);
free(ifav);
}
static void
-sig_reconf(__unused void *arg)
+sig_reconf(void *arg)
{
+ siginfo_t *siginfo = arg;
struct interface *ifp;
+ syslog(LOG_INFO, "received SIGUSR from PID %d, reconfiguring",
+ (int)siginfo->si_pid);
TAILQ_FOREACH(ifp, ifaces, next) {
ipv4_applyaddr(ifp);
}
}
-void
-handle_signal(int sig)
+static void
+handle_signal(int sig, siginfo_t *siginfo, __unused void *context)
{
struct interface *ifp;
int do_release;
do_release = 0;
switch (sig) {
case SIGINT:
- syslog(LOG_INFO, "received SIGINT, stopping");
+ syslog(LOG_INFO, "received SIGINT from PID %d, stopping",
+ (int)siginfo->si_pid);
break;
case SIGTERM:
- syslog(LOG_INFO, "received SIGTERM, stopping");
+ syslog(LOG_INFO, "received SIGTERM from PID %d, stopping",
+ (int)siginfo->si_pid);
break;
case SIGALRM:
- syslog(LOG_INFO, "received SIGALRM, rebinding");
- eloop_timeout_add_now(sig_reboot, NULL);
+ eloop_timeout_add_now(sig_reboot, siginfo);
return;
case SIGHUP:
- syslog(LOG_INFO, "received SIGHUP, releasing");
+ syslog(LOG_INFO, "received SIGHUP from PID %d, releasing",
+ (int)siginfo->si_pid);
do_release = 1;
break;
case SIGUSR1:
- syslog(LOG_INFO, "received SIGUSR, reconfiguring");
- eloop_timeout_add_now(sig_reconf, NULL);
+ eloop_timeout_add_now(sig_reconf, siginfo);
return;
case SIGPIPE:
syslog(LOG_WARNING, "received SIGPIPE");
return;
default:
syslog(LOG_ERR,
- "received signal %d, but don't know what to do with it",
- sig);
+ "received signal %d from PID %d, "
+ "but don't know what to do with it",
+ sig, (int)siginfo->si_pid);
return;
}
return 0;
}
+static int
+signal_init(void (*func)(int, siginfo_t *, void *), sigset_t *oldset)
+{
+ unsigned int i;
+ struct sigaction sa;
+ sigset_t newset;
+
+ sigfillset(&newset);
+ if (sigprocmask(SIG_SETMASK, &newset, oldset) == -1)
+ return -1;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_sigaction = func;
+ sa.sa_flags = SA_SIGINFO;
+ sigemptyset(&sa.sa_mask);
+
+ for (i = 0; handle_sigs[i]; i++) {
+ if (sigaction(handle_sigs[i], &sa, NULL) == -1)
+ return -1;
+ }
+ return 0;
+}
+
int
main(int argc, char **argv)
{
extern char **ifdv;
extern struct if_options *if_options;
+extern const int handle_sigs[];
+
pid_t daemonise(void);
struct interface *find_interface(const char *);
int handle_args(struct fd_list *, int, char **);
void handle_carrier(int, int, const char *);
void handle_interface(int, const char *);
void handle_hwaddr(const char *, unsigned char *, size_t);
-void handle_signal(int);
void drop_interface(struct interface *, const char *);
int select_profile(struct interface *, const char *);
const struct sockaddr_ll *sll;
#endif
-
-
if (getifaddrs(&ifaddrs) == -1)
return NULL;
continue;
p = argv[i];
} else {
+ p = ifa->ifa_name;
/* -1 means we're discovering against a specific
* interface, but we still need the below rules
* to apply. */
if (argc == -1 && strcmp(argv[0], ifa->ifa_name) != 0)
continue;
- for (i = 0; i < ifdc; i++)
- if (!fnmatch(ifdv[i], ifa->ifa_name, 0))
- break;
- if (i < ifdc)
- continue;
- for (i = 0; i < ifac; i++)
- if (!fnmatch(ifav[i], ifa->ifa_name, 0))
- break;
- if (ifac && i == ifac)
- continue;
- p = ifa->ifa_name;
}
+ for (i = 0; i < ifdc; i++)
+ if (!fnmatch(ifdv[i], p, 0))
+ break;
+ if (i < ifdc)
+ continue;
+ for (i = 0; i < ifac; i++)
+ if (!fnmatch(ifav[i], p, 0))
+ break;
+ if (ifac && i == ifac)
+ continue;
ifp = calloc(1, sizeof(*ifp));
if (ifp == NULL)
#include "ipv6rs.h"
#include "net.h"
#include "script.h"
-#include "signals.h"
#define DEFAULT_PATH "PATH=/usr/bin:/usr/sbin:/bin:/sbin"
+++ /dev/null
-/*
- * dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2013 Roy Marples <roy@marples.name>
- * All rights reserved
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <errno.h>
-#include <signal.h>
-#include <string.h>
-#include <syslog.h>
-#include <unistd.h>
-
-#include "common.h"
-#include "eloop.h"
-#include "signals.h"
-
-static int signal_pipe[2];
-static void (*signal_callback)(int);
-
-const int handle_sigs[] = {
- SIGALRM,
- SIGHUP,
- SIGINT,
- SIGPIPE,
- SIGTERM,
- SIGUSR1,
- 0
-};
-
-static void
-signal_handler(int sig)
-{
- int serrno = errno;
-
- if (write(signal_pipe[1], &sig, sizeof(sig)) != sizeof(sig))
- syslog(LOG_ERR, "%s: write: %m", __func__);
- errno = serrno;
-}
-
-/* ARGSUSED */
-static void
-signal_read(__unused void *arg)
-{
- int sig = -1;
- char buf[16];
- ssize_t bytes;
-
- memset(buf, 0, sizeof(buf));
- bytes = read(signal_pipe[0], buf, sizeof(buf));
- if (signal_callback && bytes >= 0 && (size_t)bytes >= sizeof(sig)) {
- memcpy(&sig, buf, sizeof(sig));
- signal_callback(sig);
- }
-}
-
-static int
-signal_handle(void (*func)(int))
-{
- unsigned int i;
- struct sigaction sa;
-
- memset(&sa, 0, sizeof(sa));
- sa.sa_handler = func;
- sigemptyset(&sa.sa_mask);
-
- for (i = 0; handle_sigs[i]; i++) {
- if (sigaction(handle_sigs[i], &sa, NULL) == -1)
- return -1;
- }
- return 0;
-}
-
-int
-signal_setup(void)
-{
-
- return signal_handle(signal_handler);
-}
-
-int
-signal_reset(void)
-{
-
- return signal_handle(SIG_DFL);
-}
-
-int
-signal_init(void (*func)(int), sigset_t *oldset)
-{
- sigset_t newset;
-
- if (pipe(signal_pipe) == -1)
- return -1;
- if (set_nonblock(signal_pipe[0]) == -1)
- return -1;
- if (set_cloexec(signal_pipe[0]) == -1 ||
- set_cloexec(signal_pipe[1] == -1))
- return -1;
-
- sigfillset(&newset);
- if (sigprocmask(SIG_SETMASK, &newset, oldset) == -1)
- return -1;
-
- /* Because functions we need to reboot/reconf out interfaces
- * are not async signal safe, we need to setup a signal pipe
- * so that the actual handler is executed in our event loop. */
- signal_callback = func;
- eloop_event_add(signal_pipe[0], signal_read, NULL);
- return signal_setup();
-}
+++ /dev/null
-/*
- * dhcpcd - DHCP client daemon
- * Copyright (c) 2006-2013 Roy Marples <roy@marples.name>
- * All rights reserved
-
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef SIGNALS_H
-#define SIGNALS_H
-
-extern const int handle_sigs[];
-
-int signal_setup(void);
-int signal_reset(void);
-int signal_init(void (*)(int), sigset_t *);
-
-#endif