mirror of
https://github.com/rsmarples/dhcpcd.git
synced 2024-11-23 18:14:09 +08:00
Remove DEBUG_MEMORY guard and always free memory and resources.
Remove all atexit(3) and exit(3) calls, instead exiting via the eloop.
This commit is contained in:
parent
47ecfbd002
commit
a9d78def54
50
auth.c
50
auth.c
@ -78,7 +78,16 @@ void
|
||||
dhcp_auth_reset(struct authstate *state)
|
||||
{
|
||||
|
||||
state->replay = 0;
|
||||
if (state->token) {
|
||||
free(state->token->key);
|
||||
free(state->token->realm);
|
||||
free(state->token);
|
||||
state->token = NULL;
|
||||
}
|
||||
if (state->reconf) {
|
||||
free(state->reconf->key);
|
||||
free(state->reconf->realm);
|
||||
free(state->reconf);
|
||||
state->reconf = NULL;
|
||||
}
|
||||
@ -270,7 +279,11 @@ dhcp_auth_validate(struct authstate *state, const struct auth *auth,
|
||||
|
||||
gottoken:
|
||||
/* First message from the server */
|
||||
if (state->token && state->token != t) {
|
||||
if (state->token &&
|
||||
(state->token->secretid != t->secretid ||
|
||||
state->token->realm_len != t->realm_len ||
|
||||
memcmp(state->token->realm, t->realm, t->realm_len)))
|
||||
{
|
||||
errno = EPERM;
|
||||
return NULL;
|
||||
}
|
||||
@ -317,7 +330,40 @@ gottoken:
|
||||
finish:
|
||||
/* If we got here then authentication passed */
|
||||
state->replay = replay;
|
||||
state->token = t;
|
||||
if (state->token == NULL) {
|
||||
/* We cannot just save a pointer because a reconfigure will
|
||||
* recreate the token list. So we duplicate it. */
|
||||
state->token = malloc(sizeof(*state->token));
|
||||
if (state->token) {
|
||||
state->token->secretid = t->secretid;
|
||||
state->token->key = malloc(t->key_len);
|
||||
if (state->token->key) {
|
||||
state->token->key_len = t->key_len;
|
||||
memcpy(state->token->key, t->key, t->key_len);
|
||||
} else {
|
||||
free(state->token);
|
||||
state->token = NULL;
|
||||
}
|
||||
if (t->realm) {
|
||||
state->token->realm = malloc(t->realm_len);
|
||||
if (state->token->realm) {
|
||||
state->token->realm_len = t->realm_len;
|
||||
memcpy(state->token->realm, t->realm,
|
||||
t->realm_len);
|
||||
} else {
|
||||
free(state->token->key);
|
||||
free(state->token);
|
||||
state->token = NULL;
|
||||
}
|
||||
} else {
|
||||
state->token->realm = NULL;
|
||||
state->token->realm_len = 0;
|
||||
}
|
||||
}
|
||||
/* If we cannot save the token, we must invalidate */
|
||||
if (state->token == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
|
2
auth.h
2
auth.h
@ -67,7 +67,7 @@ struct auth {
|
||||
|
||||
struct authstate {
|
||||
uint64_t replay;
|
||||
const struct token *token;
|
||||
struct token *token;
|
||||
struct token *reconf;
|
||||
};
|
||||
|
||||
|
27
common.c
27
common.c
@ -64,18 +64,6 @@ static char hostname_buffer[HOSTNAME_MAX_LEN + 1];
|
||||
int clock_monotonic;
|
||||
static char *lbuf;
|
||||
static size_t lbuf_len;
|
||||
#ifdef DEBUG_MEMORY
|
||||
static char lbuf_set;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_MEMORY
|
||||
static void
|
||||
free_lbuf(void)
|
||||
{
|
||||
free(lbuf);
|
||||
lbuf = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Handy routine to read very long lines in text files.
|
||||
* This means we read the whole line and avoid any nasty buffer overflows.
|
||||
@ -88,13 +76,6 @@ get_line(FILE * __restrict fp)
|
||||
char *p;
|
||||
ssize_t bytes;
|
||||
|
||||
#ifdef DEBUG_MEMORY
|
||||
if (lbuf_set == 0) {
|
||||
atexit(free_lbuf);
|
||||
lbuf_set = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
do {
|
||||
bytes = getline(&lbuf, &lbuf_len, fp);
|
||||
if (bytes == -1)
|
||||
@ -107,6 +88,14 @@ get_line(FILE * __restrict fp)
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
get_line_free(void)
|
||||
{
|
||||
|
||||
free(lbuf);
|
||||
lbuf_len = 0;
|
||||
}
|
||||
|
||||
int
|
||||
set_cloexec(int fd)
|
||||
{
|
||||
|
1
common.h
1
common.h
@ -102,6 +102,7 @@
|
||||
int set_cloexec(int);
|
||||
int set_nonblock(int);
|
||||
char *get_line(FILE * __restrict);
|
||||
void get_line_free(void);
|
||||
const char *get_hostname(int);
|
||||
extern int clock_monotonic;
|
||||
int get_monotonic(struct timeval *);
|
||||
|
9
configure
vendored
9
configure
vendored
@ -293,21 +293,16 @@ for x in $INCLUDEDIR; do
|
||||
echo "CPPFLAGS+= -I$x" >>$CONFIG_MK
|
||||
done
|
||||
|
||||
if [ -n "$DEBUG" -a "$DEBUG" != no -a "$DEBUG" != false ]; then
|
||||
echo "Enabling memory debugging"
|
||||
echo "CPPFLAGS+= -DDEBUG_MEMORY" >>$CONFIG_MK
|
||||
echo "CFLAGS+= -g" >>$CONFIG_MK
|
||||
elif [ -z "$DEBUG" -a -f .fslckout ]; then
|
||||
if [ -z "$DEBUG" -a -f .fslckout ]; then
|
||||
printf "Found fossil checkout ... "
|
||||
DEBUG=yes
|
||||
echo "CFLAGS+= -g" >>$CONFIG_MK
|
||||
else
|
||||
DEBUG=no
|
||||
fi
|
||||
if [ "$DEBUG" != no -a "$DEBUG" != false ]; then
|
||||
echo "Adding debugging CFLAGS"
|
||||
cat <<EOF >>$CONFIG_MK
|
||||
CFLAGS+= -Wall -Wextra -Wimplicit -Wshadow -Wformat=2
|
||||
CFLAGS+= -g -Wall -Wextra -Wimplicit -Wshadow -Wformat=2
|
||||
CFLAGS+= -Wmissing-prototypes -Wmissing-declarations
|
||||
CFLAGS+= -Wmissing-noreturn -Wmissing-format-attribute
|
||||
CFLAGS+= -Wredundant-decls -Wnested-externs
|
||||
|
18
control.c
18
control.c
@ -48,21 +48,6 @@ static char *argvp[255];
|
||||
static struct sockaddr_un sun;
|
||||
struct fd_list *control_fds = NULL;
|
||||
|
||||
#ifdef DEBUG_MEMORY
|
||||
static void
|
||||
cleanup(void)
|
||||
{
|
||||
struct fd_list *f;
|
||||
|
||||
f = control_fds;
|
||||
while (f) {
|
||||
control_fds = f->next;
|
||||
free(f);
|
||||
f = control_fds;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
control_remove(void *arg)
|
||||
{
|
||||
@ -201,9 +186,6 @@ control_open(void)
|
||||
|
||||
if ((len = make_sock()) == -1)
|
||||
return -1;
|
||||
#ifdef DEBUG_MEMORY
|
||||
atexit(cleanup);
|
||||
#endif
|
||||
return connect(fd, (struct sockaddr *)&sun, len);
|
||||
}
|
||||
|
||||
|
7
dev.c
7
dev.c
@ -63,11 +63,12 @@ dev_listening(void)
|
||||
}
|
||||
|
||||
void
|
||||
dev_stop(void)
|
||||
dev_stop(int stop)
|
||||
{
|
||||
|
||||
if (dev) {
|
||||
syslog(LOG_DEBUG, "dev: unloaded %s", dev->name);
|
||||
if (stop)
|
||||
syslog(LOG_DEBUG, "dev: unloaded %s", dev->name);
|
||||
dev->stop();
|
||||
free(dev);
|
||||
dev = NULL;
|
||||
@ -168,7 +169,7 @@ dev_start(const char *plugin)
|
||||
if (fd != -1) {
|
||||
if (eloop_event_add(fd, dev_handle_data, NULL) == -1) {
|
||||
syslog(LOG_ERR, "%s: eloop_event_add: %m", __func__);
|
||||
dev_stop();
|
||||
dev_stop(1);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
2
dev.h
2
dev.h
@ -48,7 +48,7 @@ int dev_init(struct dev *, const struct dev_dhcpcd *);
|
||||
int dev_initialized(const char *);
|
||||
int dev_listening(void);
|
||||
int dev_start(const char *);
|
||||
void dev_stop(void);
|
||||
void dev_stop(int);
|
||||
#else
|
||||
#define dev_initialized(a) 1
|
||||
#define dev_listening() 0
|
||||
|
73
dhcp.c
73
dhcp.c
@ -143,16 +143,6 @@ dhcp_printoptions(void)
|
||||
printf("%03d %s\n", opt->option, opt->var);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MEMORY
|
||||
static void
|
||||
dhcp_cleanup(void)
|
||||
{
|
||||
|
||||
free(packet);
|
||||
free(opt_buffer);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define get_option_raw(dhcp, opt) get_option(dhcp, opt, NULL)
|
||||
static const uint8_t *
|
||||
get_option(const struct dhcp_message *dhcp, uint8_t opt, int *len)
|
||||
@ -1816,7 +1806,8 @@ dhcp_bind(void *arg)
|
||||
if (options & DHCPCD_TEST) {
|
||||
state->reason = "TEST";
|
||||
script_runreason(iface, state->reason);
|
||||
exit(EXIT_SUCCESS);
|
||||
eloop_exit(EXIT_SUCCESS);
|
||||
return;
|
||||
}
|
||||
if (state->reason == NULL) {
|
||||
if (state->old) {
|
||||
@ -1842,13 +1833,14 @@ dhcp_bind(void *arg)
|
||||
iface->name, lease->renewaltime, lease->rebindtime);
|
||||
}
|
||||
ipv4_applyaddr(iface);
|
||||
daemonise();
|
||||
if (!ipv4ll)
|
||||
arp_close(iface);
|
||||
state->state = DHS_BOUND;
|
||||
if (ifo->options & DHCPCD_ARP) {
|
||||
state->claims = 0;
|
||||
arp_announce(iface);
|
||||
if (daemonise() == 0) {
|
||||
if (!ipv4ll)
|
||||
arp_close(iface);
|
||||
state->state = DHS_BOUND;
|
||||
if (ifo->options & DHCPCD_ARP) {
|
||||
state->claims = 0;
|
||||
arp_announce(iface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2065,24 +2057,6 @@ dhcp_drop(struct interface *ifp, const char *reason)
|
||||
state->old = NULL;
|
||||
state->lease.addr.s_addr = 0;
|
||||
ifp->options->options &= ~ DHCPCD_CSR_WARNED;
|
||||
state->auth.token = NULL;
|
||||
state->auth.replay = 0;
|
||||
free(state->auth.reconf);
|
||||
state->auth.reconf = NULL;
|
||||
|
||||
/* If we don't have any more DHCP enabled interfaces,
|
||||
* close the global socket */
|
||||
if (ifaces) {
|
||||
TAILQ_FOREACH(ifp, ifaces, next) {
|
||||
if (D_STATE(ifp))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ifp == NULL && udp_fd != -1) {
|
||||
close(udp_fd);
|
||||
eloop_event_delete(udp_fd);
|
||||
udp_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@ -2373,7 +2347,8 @@ dhcp_handledhcp(struct interface *iface, struct dhcp_message **dhcpp,
|
||||
state->offer = NULL;
|
||||
state->reason = "TEST";
|
||||
script_runreason(iface, state->reason);
|
||||
exit(EXIT_SUCCESS);
|
||||
eloop_exit(EXIT_SUCCESS);
|
||||
return;
|
||||
}
|
||||
eloop_timeout_delete(send_discover, iface);
|
||||
/* We don't request BOOTP addresses */
|
||||
@ -2618,9 +2593,6 @@ dhcp_open(struct interface *ifp)
|
||||
syslog(LOG_ERR, "%s: %m", __func__);
|
||||
return -1;
|
||||
}
|
||||
#ifdef DEBUG_MEMORY
|
||||
atexit(dhcp_cleanup);
|
||||
#endif
|
||||
}
|
||||
|
||||
state = D_STATE(ifp);
|
||||
@ -2705,6 +2677,27 @@ dhcp_free(struct interface *ifp)
|
||||
free(state);
|
||||
ifp->if_data[IF_DATA_DHCP] = NULL;
|
||||
}
|
||||
|
||||
/* If we don't have any more DHCP enabled interfaces,
|
||||
* close the global socket and release resources */
|
||||
if (ifaces) {
|
||||
TAILQ_FOREACH(ifp, ifaces, next) {
|
||||
if (D_STATE(ifp))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ifp == NULL) {
|
||||
if (udp_fd != -1) {
|
||||
close(udp_fd);
|
||||
eloop_event_delete(udp_fd);
|
||||
udp_fd = -1;
|
||||
}
|
||||
|
||||
free(packet);
|
||||
free(opt_buffer);
|
||||
packet = NULL;
|
||||
opt_buffer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
|
39
dhcp6.c
39
dhcp6.c
@ -131,17 +131,6 @@ static const char * const dhcp6_statuses[] = {
|
||||
"Use Multicast"
|
||||
};
|
||||
|
||||
#if DEBUG_MEMORY
|
||||
static void
|
||||
dhcp6_cleanup(void)
|
||||
{
|
||||
|
||||
free(sndbuf);
|
||||
free(rcvbuf);
|
||||
free(status);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
dhcp6_printoptions(void)
|
||||
{
|
||||
@ -157,10 +146,6 @@ dhcp6_init(void)
|
||||
{
|
||||
int len;
|
||||
|
||||
#if DEBUG_MEMORY
|
||||
atexit(dhcp6_cleanup);
|
||||
#endif
|
||||
|
||||
len = CMSG_SPACE(sizeof(struct in6_pktinfo));
|
||||
sndbuf = calloc(1, len);
|
||||
if (sndbuf == NULL)
|
||||
@ -2481,10 +2466,7 @@ recv:
|
||||
(ifp->options->options & DHCPCD_INFORM &&
|
||||
!(options & DHCPCD_MASTER)))
|
||||
{
|
||||
#ifdef DEBUG_MEMORY
|
||||
dhcp6_free(ifp);
|
||||
#endif
|
||||
exit(EXIT_SUCCESS);
|
||||
eloop_exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2708,23 +2690,30 @@ dhcp6_freedrop(struct interface *ifp, int drop, const char *reason)
|
||||
free(state->recv);
|
||||
free(state->new);
|
||||
free(state->old);
|
||||
free(state->auth.reconf);
|
||||
free(state);
|
||||
ifp->if_data[IF_DATA_DHCP6] = NULL;
|
||||
}
|
||||
|
||||
/* If we don't have any more DHCP6 enabled interfaces,
|
||||
* close the global socket */
|
||||
* close the global socketo and release resources */
|
||||
if (ifaces) {
|
||||
TAILQ_FOREACH(ifp, ifaces, next) {
|
||||
if (D6_STATE(ifp))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ifp == NULL && sock != -1) {
|
||||
close(sock);
|
||||
eloop_event_delete(sock);
|
||||
sock = -1;
|
||||
if (ifp == NULL) {
|
||||
if (sock != -1) {
|
||||
close(sock);
|
||||
eloop_event_delete(sock);
|
||||
sock = -1;
|
||||
}
|
||||
free(sndbuf);
|
||||
free(rcvbuf);
|
||||
free(status);
|
||||
sndbuf = NULL;
|
||||
rcvbuf = NULL;
|
||||
status = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
203
dhcpcd.c
203
dhcpcd.c
@ -87,7 +87,6 @@ const int handle_sigs[] = {
|
||||
};
|
||||
|
||||
static char *cffile;
|
||||
static char *pidfile;
|
||||
static int linkfd = -1;
|
||||
static char **ifv;
|
||||
static int ifc;
|
||||
@ -95,7 +94,7 @@ static char **margv;
|
||||
static int margc;
|
||||
|
||||
static pid_t
|
||||
read_pid(void)
|
||||
read_pid(const char *pidfile)
|
||||
{
|
||||
FILE *fp;
|
||||
pid_t pid;
|
||||
@ -162,46 +161,6 @@ free_globals(void)
|
||||
free(vivso);
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup(void)
|
||||
{
|
||||
#ifdef DEBUG_MEMORY
|
||||
struct interface *ifp;
|
||||
|
||||
free(duid);
|
||||
free_options(if_options);
|
||||
|
||||
if (ifaces) {
|
||||
while ((ifp = TAILQ_FIRST(ifaces))) {
|
||||
TAILQ_REMOVE(ifaces, ifp, next);
|
||||
free_interface(ifp);
|
||||
}
|
||||
free(ifaces);
|
||||
}
|
||||
|
||||
free_globals();
|
||||
#endif
|
||||
|
||||
if (!(options & DHCPCD_FORKED))
|
||||
dev_stop();
|
||||
if (linkfd != -1)
|
||||
close(linkfd);
|
||||
if (pidfd > -1) {
|
||||
if (options & DHCPCD_MASTER) {
|
||||
if (control_stop() == -1)
|
||||
syslog(LOG_ERR, "control_stop: %m");
|
||||
}
|
||||
close(pidfd);
|
||||
unlink(pidfile);
|
||||
}
|
||||
#ifdef DEBUG_MEMORY
|
||||
free(pidfile);
|
||||
#endif
|
||||
|
||||
if (options & DHCPCD_STARTED && !(options & DHCPCD_FORKED))
|
||||
syslog(LOG_INFO, "exited");
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
handle_exit_timeout(__unused void *arg)
|
||||
@ -217,9 +176,9 @@ handle_exit_timeout(__unused void *arg)
|
||||
options &=
|
||||
~(DHCPCD_WAITIP | DHCPCD_WAITIP4 | DHCPCD_WAITIP6);
|
||||
daemonise();
|
||||
return;
|
||||
} else
|
||||
exit(EXIT_FAILURE);
|
||||
eloop_exit(EXIT_FAILURE);
|
||||
return;
|
||||
}
|
||||
options &= ~DHCPCD_TIMEOUT_IPV4LL;
|
||||
timeout = (PROBE_NUM * PROBE_MAX) + (PROBE_WAIT * 2);
|
||||
@ -231,6 +190,7 @@ pid_t
|
||||
daemonise(void)
|
||||
{
|
||||
#ifdef THERE_IS_NO_FORK
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#else
|
||||
pid_t pid;
|
||||
@ -297,7 +257,8 @@ daemonise(void)
|
||||
close(pidfd);
|
||||
pidfd = -1;
|
||||
options |= DHCPCD_FORKED;
|
||||
exit(EXIT_SUCCESS);
|
||||
eloop_exit(EXIT_SUCCESS);
|
||||
return pid;
|
||||
}
|
||||
options |= DHCPCD_DAEMONISED;
|
||||
return pid;
|
||||
@ -333,7 +294,7 @@ stop_interface(struct interface *ifp)
|
||||
script_runreason(ifp, "DEPARTED");
|
||||
free_interface(ifp);
|
||||
if (!(options & (DHCPCD_MASTER | DHCPCD_TEST)))
|
||||
exit(EXIT_FAILURE);
|
||||
eloop_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -904,23 +865,22 @@ handle_signal(int sig, siginfo_t *siginfo, __unused void *context)
|
||||
return;
|
||||
}
|
||||
|
||||
if (options & DHCPCD_TEST)
|
||||
exit(EXIT_FAILURE);
|
||||
|
||||
/* As drop_dhcp could re-arrange the order, we do it like this. */
|
||||
for (;;) {
|
||||
/* Be sane and drop the last config first */
|
||||
ifp = TAILQ_LAST(ifaces, if_head);
|
||||
if (ifp == NULL)
|
||||
break;
|
||||
if (do_release) {
|
||||
ifp->options->options |= DHCPCD_RELEASE;
|
||||
ifp->options->options &= ~DHCPCD_PERSISTENT;
|
||||
if (!(options & DHCPCD_TEST)) {
|
||||
/* drop_dhcp could change the order, so we do it like this. */
|
||||
for (;;) {
|
||||
/* Be sane and drop the last config first */
|
||||
ifp = TAILQ_LAST(ifaces, if_head);
|
||||
if (ifp == NULL)
|
||||
break;
|
||||
if (do_release) {
|
||||
ifp->options->options |= DHCPCD_RELEASE;
|
||||
ifp->options->options &= ~DHCPCD_PERSISTENT;
|
||||
}
|
||||
ifp->options->options |= DHCPCD_EXITING;
|
||||
stop_interface(ifp);
|
||||
}
|
||||
ifp->options->options |= DHCPCD_EXITING;
|
||||
stop_interface(ifp);
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
eloop_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
int
|
||||
@ -1093,15 +1053,17 @@ signal_init(void (*func)(int, siginfo_t *, void *), sigset_t *oldset)
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *pidfile;
|
||||
struct interface *ifp;
|
||||
uint16_t family = 0;
|
||||
int opt, oi = 0, sig = 0, i, control_fd;
|
||||
int opt, oi = 0, sig = 0, i;
|
||||
size_t len;
|
||||
pid_t pid;
|
||||
struct timespec ts;
|
||||
struct utsname utn;
|
||||
const char *platform;
|
||||
|
||||
pidfile = NULL;
|
||||
closefrom(3);
|
||||
openlog(PACKAGE, LOG_PERROR | LOG_PID, LOG_DAEMON);
|
||||
setlogmask(LOG_UPTO(LOG_INFO));
|
||||
@ -1110,10 +1072,10 @@ main(int argc, char **argv)
|
||||
if (argc > 1) {
|
||||
if (strcmp(argv[1], "--help") == 0) {
|
||||
usage();
|
||||
exit(EXIT_SUCCESS);
|
||||
return EXIT_SUCCESS;
|
||||
} else if (strcmp(argv[1], "--version") == 0) {
|
||||
printf(""PACKAGE" "VERSION"\n%s\n", dhcpcd_copyright);
|
||||
exit(EXIT_SUCCESS);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1163,7 +1125,7 @@ main(int argc, char **argv)
|
||||
break;
|
||||
case '?':
|
||||
usage();
|
||||
exit(EXIT_FAILURE);
|
||||
goto exit_failure;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1174,7 +1136,7 @@ main(int argc, char **argv)
|
||||
if (opt != 1) {
|
||||
if (opt == 0)
|
||||
usage();
|
||||
exit(EXIT_FAILURE);
|
||||
goto exit_failure;
|
||||
}
|
||||
if (i == 3) {
|
||||
printf("Interface options:\n");
|
||||
@ -1191,10 +1153,7 @@ main(int argc, char **argv)
|
||||
dhcp6_printoptions();
|
||||
}
|
||||
#endif
|
||||
#ifdef DEBUG_MEMORY
|
||||
cleanup();
|
||||
#endif
|
||||
exit(EXIT_SUCCESS);
|
||||
goto exit_success;
|
||||
}
|
||||
options = if_options->options;
|
||||
if (i != 0) {
|
||||
@ -1229,7 +1188,7 @@ main(int argc, char **argv)
|
||||
pidfile = malloc(len);
|
||||
if (pidfile == NULL) {
|
||||
syslog(LOG_ERR, "%s: %m", __func__);
|
||||
exit(EXIT_FAILURE);
|
||||
goto exit_failure;
|
||||
}
|
||||
if (optind == argc - 1)
|
||||
snprintf(pidfile, len, PIDFILE, "-", argv[optind]);
|
||||
@ -1241,30 +1200,29 @@ main(int argc, char **argv)
|
||||
|
||||
if (chdir("/") == -1)
|
||||
syslog(LOG_ERR, "chdir `/': %m");
|
||||
atexit(cleanup);
|
||||
|
||||
if (options & DHCPCD_DUMPLEASE) {
|
||||
if (optind != argc - 1) {
|
||||
syslog(LOG_ERR, "dumplease requires an interface");
|
||||
exit(EXIT_FAILURE);
|
||||
goto exit_failure;
|
||||
}
|
||||
if (dhcp_dump(argv[optind]) == -1)
|
||||
exit(EXIT_FAILURE);
|
||||
exit(EXIT_SUCCESS);
|
||||
goto exit_failure;
|
||||
goto exit_success;
|
||||
}
|
||||
|
||||
if (!(options & (DHCPCD_MASTER | DHCPCD_TEST))) {
|
||||
control_fd = control_open();
|
||||
if (control_fd != -1) {
|
||||
if ((i = control_open()) != -1) {
|
||||
syslog(LOG_INFO,
|
||||
"sending commands to master dhcpcd process");
|
||||
i = control_send(argc, argv);
|
||||
if (i > 0) {
|
||||
len = control_send(argc, argv);
|
||||
close(i);
|
||||
if (len > 0) {
|
||||
syslog(LOG_DEBUG, "send OK");
|
||||
exit(EXIT_SUCCESS);
|
||||
goto exit_success;
|
||||
} else {
|
||||
syslog(LOG_ERR, "failed to send commands");
|
||||
exit(EXIT_FAILURE);
|
||||
goto exit_failure;
|
||||
}
|
||||
} else {
|
||||
if (errno != ENOENT)
|
||||
@ -1277,7 +1235,7 @@ main(int argc, char **argv)
|
||||
PACKAGE " will not work correctly unless run as root");
|
||||
|
||||
if (sig != 0) {
|
||||
pid = read_pid();
|
||||
pid = read_pid(pidfile);
|
||||
if (pid != 0)
|
||||
syslog(LOG_INFO, "sending signal %d to pid %d",
|
||||
sig, pid);
|
||||
@ -1286,36 +1244,36 @@ main(int argc, char **argv)
|
||||
syslog(LOG_ERR, ""PACKAGE" not running");
|
||||
if (pid != 0 && errno != ESRCH) {
|
||||
syslog(LOG_ERR, "kill: %m");
|
||||
exit(EXIT_FAILURE);
|
||||
goto exit_failure;
|
||||
}
|
||||
unlink(pidfile);
|
||||
if (sig != SIGALRM)
|
||||
exit(EXIT_FAILURE);
|
||||
goto exit_failure;
|
||||
} else {
|
||||
if (sig == SIGALRM || sig == SIGUSR1)
|
||||
exit(EXIT_SUCCESS);
|
||||
goto exit_success;
|
||||
/* Spin until it exits */
|
||||
syslog(LOG_INFO, "waiting for pid %d to exit", pid);
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 100000000; /* 10th of a second */
|
||||
for(i = 0; i < 100; i++) {
|
||||
nanosleep(&ts, NULL);
|
||||
if (read_pid() == 0)
|
||||
exit(EXIT_SUCCESS);
|
||||
if (read_pid(pidfile) == 0)
|
||||
goto exit_success;
|
||||
}
|
||||
syslog(LOG_ERR, "pid %d failed to exit", pid);
|
||||
exit(EXIT_FAILURE);
|
||||
goto exit_failure;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(options & DHCPCD_TEST)) {
|
||||
if ((pid = read_pid()) > 0 &&
|
||||
if ((pid = read_pid(pidfile)) > 0 &&
|
||||
kill(pid, 0) == 0)
|
||||
{
|
||||
syslog(LOG_ERR, ""PACKAGE
|
||||
" already running on pid %d (%s)",
|
||||
pid, pidfile);
|
||||
exit(EXIT_FAILURE);
|
||||
goto exit_failure;
|
||||
}
|
||||
|
||||
/* Ensure we have the needed directories */
|
||||
@ -1332,10 +1290,10 @@ main(int argc, char **argv)
|
||||
* runs on an interface */
|
||||
if (flock(pidfd, LOCK_EX | LOCK_NB) == -1) {
|
||||
syslog(LOG_ERR, "flock `%s': %m", pidfile);
|
||||
exit(EXIT_FAILURE);
|
||||
goto exit_failure;
|
||||
}
|
||||
if (set_cloexec(pidfd) == -1)
|
||||
exit(EXIT_FAILURE);
|
||||
goto exit_failure;
|
||||
writepid(pidfd, getpid());
|
||||
}
|
||||
}
|
||||
@ -1343,14 +1301,10 @@ main(int argc, char **argv)
|
||||
syslog(LOG_INFO, "version " VERSION " starting");
|
||||
options |= DHCPCD_STARTED;
|
||||
|
||||
#ifdef DEBUG_MEMORY
|
||||
eloop_init();
|
||||
#endif
|
||||
|
||||
/* Save signal mask, block and redirect signals to our handler */
|
||||
if (signal_init(handle_signal, &dhcpcd_sigset) == -1) {
|
||||
syslog(LOG_ERR, "signal_setup: %m");
|
||||
exit(EXIT_FAILURE);
|
||||
goto exit_failure;
|
||||
}
|
||||
|
||||
if (options & DHCPCD_MASTER) {
|
||||
@ -1360,7 +1314,7 @@ main(int argc, char **argv)
|
||||
|
||||
if (open_sockets() == -1) {
|
||||
syslog(LOG_ERR, "open_sockets: %m");
|
||||
exit(EXIT_FAILURE);
|
||||
goto exit_failure;
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -1407,11 +1361,11 @@ main(int argc, char **argv)
|
||||
if (ifc == 0)
|
||||
syslog(LOG_ERR, "no valid interfaces found");
|
||||
else
|
||||
exit(EXIT_FAILURE);
|
||||
goto exit_failure;
|
||||
if (!(options & DHCPCD_LINK)) {
|
||||
syslog(LOG_ERR,
|
||||
"aborting as link detection is disabled");
|
||||
exit(EXIT_FAILURE);
|
||||
goto exit_failure;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1470,6 +1424,51 @@ main(int argc, char **argv)
|
||||
eloop_timeout_add_sec(0, start_interface, ifp);
|
||||
}
|
||||
|
||||
eloop_start(&dhcpcd_sigset);
|
||||
exit(EXIT_SUCCESS);
|
||||
i = eloop_start(&dhcpcd_sigset);
|
||||
goto exit1;
|
||||
|
||||
exit_success:
|
||||
i = EXIT_SUCCESS;
|
||||
goto exit1;
|
||||
|
||||
exit_failure:
|
||||
i = EXIT_FAILURE;
|
||||
|
||||
exit1:
|
||||
|
||||
if (ifaces) {
|
||||
while ((ifp = TAILQ_FIRST(ifaces))) {
|
||||
TAILQ_REMOVE(ifaces, ifp, next);
|
||||
free_interface(ifp);
|
||||
}
|
||||
free(ifaces);
|
||||
}
|
||||
|
||||
free(duid);
|
||||
free_options(if_options);
|
||||
free_globals();
|
||||
restore_kernel_ra();
|
||||
ipv4_free(NULL);
|
||||
ipv6_free(NULL);
|
||||
if_free();
|
||||
get_line_free();
|
||||
dev_stop(options & DHCPCD_DAEMONISED);
|
||||
if (linkfd != -1) {
|
||||
close(linkfd);
|
||||
linkfd = -1;
|
||||
}
|
||||
if (pidfd > -1) {
|
||||
if (options & DHCPCD_MASTER) {
|
||||
if (control_stop() == -1)
|
||||
syslog(LOG_ERR, "control_stop: %m");
|
||||
}
|
||||
close(pidfd);
|
||||
unlink(pidfile);
|
||||
pidfd = -1;
|
||||
}
|
||||
free(pidfile);
|
||||
|
||||
if (options & DHCPCD_STARTED && !(options & DHCPCD_FORKED))
|
||||
syslog(LOG_INFO, "exited");
|
||||
return i;
|
||||
}
|
||||
|
84
eloop.c
84
eloop.c
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
* Copyright (c) 2006-2013 Roy Marples <roy@marples.name>
|
||||
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
|
||||
* All rights reserved
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -74,6 +74,9 @@ static void *volatile timeout0_arg;
|
||||
static struct pollfd *fds;
|
||||
static size_t fds_len;
|
||||
|
||||
static int eloop_exitnow;
|
||||
static int eloop_exitcode;
|
||||
|
||||
static void
|
||||
eloop_event_setup_fds(void)
|
||||
{
|
||||
@ -94,6 +97,7 @@ int
|
||||
eloop_event_add(int fd, void (*callback)(void *), void *arg)
|
||||
{
|
||||
struct event *e;
|
||||
struct pollfd *nfds;
|
||||
|
||||
/* We should only have one callback monitoring the fd */
|
||||
TAILQ_FOREACH(e, &events, next) {
|
||||
@ -119,13 +123,16 @@ eloop_event_add(int fd, void (*callback)(void *), void *arg)
|
||||
events_len++;
|
||||
if (events_len > fds_len) {
|
||||
fds_len += 5;
|
||||
free(fds);
|
||||
fds = malloc(sizeof(*fds) * fds_len);
|
||||
if (fds == NULL) {
|
||||
nfds = malloc(sizeof(*fds) * (fds_len + 5));
|
||||
if (nfds == NULL) {
|
||||
syslog(LOG_ERR, "%s: %m", __func__);
|
||||
free(e);
|
||||
events_len--;
|
||||
TAILQ_INSERT_TAIL(&free_events, e, next);
|
||||
return -1;
|
||||
}
|
||||
fds_len += 5;
|
||||
free(fds);
|
||||
fds = nfds;
|
||||
}
|
||||
|
||||
/* Now populate the structure and add it to the list */
|
||||
@ -292,44 +299,15 @@ eloop_q_timeout_delete(int queue, void (*callback)(void *), void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MEMORY
|
||||
/* Define this to free all malloced memory.
|
||||
* Normally we don't do this as the OS will do it for us at exit,
|
||||
* but it's handy for debugging other leaks in valgrind. */
|
||||
static void
|
||||
eloop_cleanup(void)
|
||||
{
|
||||
struct event *e;
|
||||
struct timeout *t;
|
||||
|
||||
while ((e = TAILQ_FIRST(&events))) {
|
||||
TAILQ_REMOVE(&events, e, next);
|
||||
free(e);
|
||||
}
|
||||
while ((e = TAILQ_FIRST(&free_events))) {
|
||||
TAILQ_REMOVE(&free_events, e, next);
|
||||
free(e);
|
||||
}
|
||||
while ((t = TAILQ_FIRST(&timeouts))) {
|
||||
TAILQ_REMOVE(&timeouts, t, next);
|
||||
free(t);
|
||||
}
|
||||
while ((t = TAILQ_FIRST(&free_timeouts))) {
|
||||
TAILQ_REMOVE(&free_timeouts, t, next);
|
||||
free(t);
|
||||
}
|
||||
free(fds);
|
||||
}
|
||||
|
||||
void
|
||||
eloop_init(void)
|
||||
eloop_exit(int code)
|
||||
{
|
||||
|
||||
atexit(eloop_cleanup);
|
||||
eloop_exitcode = code;
|
||||
eloop_exitnow = 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
__dead void
|
||||
int
|
||||
eloop_start(const sigset_t *sigmask)
|
||||
{
|
||||
int n;
|
||||
@ -339,7 +317,11 @@ eloop_start(const sigset_t *sigmask)
|
||||
struct timespec ts, *tsp;
|
||||
void (*t0)(void *);
|
||||
|
||||
eloop_exitcode = EXIT_FAILURE;
|
||||
for (;;) {
|
||||
if (eloop_exitnow)
|
||||
break;
|
||||
|
||||
/* Run all timeouts first */
|
||||
if (timeout0) {
|
||||
t0 = timeout0;
|
||||
@ -364,7 +346,7 @@ eloop_start(const sigset_t *sigmask)
|
||||
|
||||
if (tsp == NULL && events_len == 0) {
|
||||
syslog(LOG_ERR, "nothing to do");
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
|
||||
n = pollts(fds, events_len, tsp, sigmask);
|
||||
@ -372,7 +354,7 @@ eloop_start(const sigset_t *sigmask)
|
||||
if (errno == EAGAIN || errno == EINTR)
|
||||
continue;
|
||||
syslog(LOG_ERR, "poll: %m");
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Process any triggered events. */
|
||||
@ -388,4 +370,26 @@ eloop_start(const sigset_t *sigmask)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Release our malloced resources */
|
||||
while ((e = TAILQ_FIRST(&events))) {
|
||||
TAILQ_REMOVE(&events, e, next);
|
||||
free(e);
|
||||
}
|
||||
while ((e = TAILQ_FIRST(&free_events))) {
|
||||
TAILQ_REMOVE(&free_events, e, next);
|
||||
free(e);
|
||||
}
|
||||
while ((t = TAILQ_FIRST(&timeouts))) {
|
||||
TAILQ_REMOVE(&timeouts, t, next);
|
||||
free(t);
|
||||
}
|
||||
while ((t = TAILQ_FIRST(&free_timeouts))) {
|
||||
TAILQ_REMOVE(&free_timeouts, t, next);
|
||||
free(t);
|
||||
}
|
||||
free(fds);
|
||||
fds_len = 0;
|
||||
|
||||
return eloop_exitcode;
|
||||
}
|
||||
|
9
eloop.h
9
eloop.h
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* dhcpcd - DHCP client daemon
|
||||
* Copyright (c) 2006-2013 Roy Marples <roy@marples.name>
|
||||
* Copyright (c) 2006-2014 Roy Marples <roy@marples.name>
|
||||
* All rights reserved
|
||||
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -34,6 +34,10 @@
|
||||
#define ELOOP_QUEUE 1
|
||||
#endif
|
||||
|
||||
/* EXIT_FAILURE is a non zero value and EXIT_SUCCESS is zero.
|
||||
* To add a CONTINUE definition, simply do the opposite of EXIT_FAILURE. */
|
||||
#define ELOOP_CONTINUE -EXIT_FAILURE
|
||||
|
||||
#define eloop_timeout_add_tv(a, b, c) \
|
||||
eloop_q_timeout_add_tv(ELOOP_QUEUE, a, b, c)
|
||||
#define eloop_timeout_add_sec(a, b, c) \
|
||||
@ -52,6 +56,7 @@ int eloop_timeout_add_now(void (*)(void *), void *);
|
||||
void eloop_q_timeout_delete(int, void (*)(void *), void *);
|
||||
void eloop_q_timeouts_delete(int, void *, void (*)(void *), ...);
|
||||
void eloop_init(void);
|
||||
void eloop_start(const sigset_t *);
|
||||
void eloop_exit(int);
|
||||
int eloop_start(const sigset_t *);
|
||||
|
||||
#endif
|
||||
|
20
if-bsd.c
20
if-bsd.c
@ -102,14 +102,19 @@ if_conf(__unused struct interface *iface)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MEMORY
|
||||
static void
|
||||
cleanup(void)
|
||||
void
|
||||
if_free(void)
|
||||
{
|
||||
|
||||
free(link_buf);
|
||||
if (r_fd != -1) {
|
||||
close(r_fd);
|
||||
r_fd = -1;
|
||||
}
|
||||
if (link_buflen) {
|
||||
free(link_buf);
|
||||
link_buflen = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
open_sockets(void)
|
||||
@ -128,11 +133,6 @@ open_link_socket(void)
|
||||
{
|
||||
int fd;
|
||||
|
||||
#ifdef DEBUG_MEMORY
|
||||
if (link_buf == NULL)
|
||||
atexit(cleanup);
|
||||
#endif
|
||||
|
||||
fd = socket(PF_ROUTE, SOCK_RAW, 0);
|
||||
if (fd != -1) {
|
||||
set_cloexec(fd);
|
||||
|
10
if-linux.c
10
if-linux.c
@ -112,6 +112,16 @@ if_conf(struct interface *iface)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
if_free(void)
|
||||
{
|
||||
|
||||
if (sock_fd != -1) {
|
||||
close(sock_fd);
|
||||
sock_fd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX work out Virtal Interface Masters */
|
||||
int
|
||||
if_vimaster(__unused const char *ifname)
|
||||
|
29
ipv4.c
29
ipv4.c
@ -169,15 +169,6 @@ ipv4_freeroutes(struct rt_head *rts)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_MEMORY
|
||||
static void
|
||||
ipv4_cleanup()
|
||||
{
|
||||
|
||||
ipv4_freeroutes(routes);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
ipv4_init(void)
|
||||
{
|
||||
@ -187,9 +178,6 @@ ipv4_init(void)
|
||||
if (routes == NULL)
|
||||
return -1;
|
||||
TAILQ_INIT(routes);
|
||||
#ifdef DEBUG_MEMORY
|
||||
atexit(ipv4_cleanup);
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -776,12 +764,17 @@ ipv4_free(struct interface *ifp)
|
||||
struct ipv4_state *state;
|
||||
struct ipv4_addr *addr;
|
||||
|
||||
state = IPV4_STATE(ifp);
|
||||
if (state) {
|
||||
while ((addr = TAILQ_FIRST(&state->addrs))) {
|
||||
TAILQ_REMOVE(&state->addrs, addr, next);
|
||||
free(addr);
|
||||
if (ifp) {
|
||||
state = IPV4_STATE(ifp);
|
||||
if (state) {
|
||||
while ((addr = TAILQ_FIRST(&state->addrs))) {
|
||||
TAILQ_REMOVE(&state->addrs, addr, next);
|
||||
free(addr);
|
||||
}
|
||||
free(state);
|
||||
}
|
||||
free(state);
|
||||
} else {
|
||||
ipv4_freeroutes(routes);
|
||||
routes = NULL;
|
||||
}
|
||||
}
|
||||
|
45
ipv6.c
45
ipv6.c
@ -74,20 +74,6 @@
|
||||
|
||||
static struct rt6head *routes;
|
||||
|
||||
#ifdef DEBUG_MEMORY
|
||||
static void
|
||||
ipv6_cleanup()
|
||||
{
|
||||
struct rt6 *rt;
|
||||
|
||||
while ((rt = TAILQ_FIRST(routes))) {
|
||||
TAILQ_REMOVE(routes, rt, next);
|
||||
free(rt);
|
||||
}
|
||||
free(routes);
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
ipv6_init(void)
|
||||
{
|
||||
@ -97,9 +83,6 @@ ipv6_init(void)
|
||||
if (routes == NULL)
|
||||
return -1;
|
||||
TAILQ_INIT(routes);
|
||||
#ifdef DEBUG_MEMORY
|
||||
atexit(ipv6_cleanup);
|
||||
#endif
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -659,16 +642,28 @@ ipv6_free(struct interface *ifp)
|
||||
{
|
||||
struct ipv6_state *state;
|
||||
struct ipv6_addr_l *ap;
|
||||
struct rt6 *rt;
|
||||
|
||||
ipv6_free_ll_callbacks(ifp);
|
||||
state = IPV6_STATE(ifp);
|
||||
if (state) {
|
||||
while ((ap = TAILQ_FIRST(&state->addrs))) {
|
||||
TAILQ_REMOVE(&state->addrs, ap, next);
|
||||
free(ap);
|
||||
if (ifp) {
|
||||
ipv6_free_ll_callbacks(ifp);
|
||||
state = IPV6_STATE(ifp);
|
||||
if (state) {
|
||||
while ((ap = TAILQ_FIRST(&state->addrs))) {
|
||||
TAILQ_REMOVE(&state->addrs, ap, next);
|
||||
free(ap);
|
||||
}
|
||||
free(state);
|
||||
ifp->if_data[IF_DATA_IPV6] = NULL;
|
||||
}
|
||||
} else {
|
||||
if (routes) {
|
||||
while ((rt = TAILQ_FIRST(routes))) {
|
||||
TAILQ_REMOVE(routes, rt, next);
|
||||
free(rt);
|
||||
}
|
||||
free(routes);
|
||||
routes = NULL;
|
||||
}
|
||||
free(state);
|
||||
ifp->if_data[IF_DATA_IPV6] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
50
ipv6nd.c
50
ipv6nd.c
@ -180,16 +180,6 @@ static void ipv6nd_handledata(void *arg);
|
||||
memset(filterp, 0xff, sizeof(struct icmp6_filter));
|
||||
#endif
|
||||
|
||||
#if DEBUG_MEMORY
|
||||
static void
|
||||
ipv6nd_cleanup(void)
|
||||
{
|
||||
|
||||
free(sndbuf);
|
||||
free(rcvbuf);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
ipv6nd_open(void)
|
||||
{
|
||||
@ -230,9 +220,6 @@ ipv6nd_open(void)
|
||||
goto eexit;
|
||||
|
||||
set_cloexec(sock);
|
||||
#if DEBUG_MEMORY
|
||||
atexit(ipv6nd_cleanup);
|
||||
#endif
|
||||
|
||||
len = CMSG_SPACE(sizeof(struct in6_pktinfo)) + CMSG_SPACE(sizeof(int));
|
||||
sndbuf = calloc(1, len);
|
||||
@ -465,11 +452,12 @@ ipv6nd_free(struct interface *ifp)
|
||||
ssize_t n;
|
||||
|
||||
state = RS_STATE(ifp);
|
||||
if (state) {
|
||||
free(state->rs);
|
||||
free(state);
|
||||
ifp->if_data[IF_DATA_IPV6ND] = NULL;
|
||||
}
|
||||
if (state == NULL)
|
||||
return 0;
|
||||
|
||||
free(state->rs);
|
||||
free(state);
|
||||
ifp->if_data[IF_DATA_IPV6ND] = NULL;
|
||||
n = 0;
|
||||
TAILQ_FOREACH_SAFE(rap, &ipv6_routers, next, ran) {
|
||||
if (rap->iface == ifp) {
|
||||
@ -477,6 +465,25 @@ ipv6nd_free(struct interface *ifp)
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we don't have any more IPv6 enabled interfaces,
|
||||
* close the global socket and release resources */
|
||||
TAILQ_FOREACH(ifp, ifaces, next) {
|
||||
if (RS_STATE(ifp))
|
||||
break;
|
||||
}
|
||||
if (ifp == NULL) {
|
||||
if (sock != -1) {
|
||||
close(sock);
|
||||
eloop_event_delete(sock);
|
||||
sock = -1;
|
||||
}
|
||||
free(sndbuf);
|
||||
free(rcvbuf);
|
||||
sndbuf = NULL;
|
||||
rcvbuf = NULL;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
@ -1031,8 +1038,10 @@ handle_flag:
|
||||
if (rap->lifetime && new_data)
|
||||
syslog(LOG_DEBUG, "%s: No DHCPv6 instruction in RA",
|
||||
ifp->name);
|
||||
if (options & DHCPCD_TEST)
|
||||
exit(EXIT_SUCCESS);
|
||||
if (options & DHCPCD_TEST) {
|
||||
eloop_exit(EXIT_SUCCESS);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Expire should be called last as the rap object could be destroyed */
|
||||
@ -1292,6 +1301,7 @@ ipv6nd_drop(struct interface *ifp)
|
||||
script_runreason(ifp, "ROUTERADVERT");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ipv6nd_unreachable(void *arg)
|
||||
{
|
||||
|
1
net.h
1
net.h
@ -103,6 +103,7 @@ int do_mtu(const char *, short int);
|
||||
int up_interface(struct interface *);
|
||||
int if_conf(struct interface *);
|
||||
int if_init(struct interface *);
|
||||
void if_free(void);
|
||||
|
||||
int open_link_socket(void);
|
||||
int manage_link(int);
|
||||
|
@ -89,7 +89,7 @@ inet6_sysctl(int code, int val, int action)
|
||||
return val;
|
||||
}
|
||||
|
||||
static void
|
||||
void
|
||||
restore_kernel_ra(void)
|
||||
{
|
||||
|
||||
@ -121,7 +121,7 @@ ipv6_ra_flush(void)
|
||||
int
|
||||
check_ipv6(const char *ifname, int own)
|
||||
{
|
||||
static int set_restore = 0, global_ra = 0;
|
||||
static int global_ra = 0;
|
||||
int ra;
|
||||
|
||||
/* BSD doesn't support these values per iface, so just return
|
||||
@ -141,10 +141,6 @@ check_ipv6(const char *ifname, int own)
|
||||
syslog(LOG_ERR, "IPV6CTL_ACCEPT_RTADV: %m");
|
||||
return ra;
|
||||
}
|
||||
if (!set_restore) {
|
||||
set_restore = 1;
|
||||
atexit(restore_kernel_ra);
|
||||
}
|
||||
ra = 0;
|
||||
|
||||
/* Flush the kernel knowledge of advertised routers
|
||||
|
@ -145,51 +145,36 @@ write_path(const char *path, const char *val)
|
||||
|
||||
static const char *prefix = "/proc/sys/net/ipv6/conf";
|
||||
|
||||
static void
|
||||
void
|
||||
restore_kernel_ra(void)
|
||||
{
|
||||
char path[256];
|
||||
|
||||
#ifndef DEBUG_MEMORY
|
||||
if (options & DHCPCD_FORKED)
|
||||
return;
|
||||
#endif
|
||||
|
||||
for (nrestore--; nrestore >= 0; nrestore--) {
|
||||
#ifdef DEBUG_MEMORY
|
||||
if (!(options & DHCPCD_FORKED)) {
|
||||
#endif
|
||||
syslog(LOG_INFO, "%s: restoring Kernel IPv6 RA support",
|
||||
restore[nrestore]);
|
||||
snprintf(path, sizeof(path), "%s/%s/accept_ra",
|
||||
prefix, restore[nrestore]);
|
||||
if (write_path(path, "1") == -1 && errno != ENOENT)
|
||||
syslog(LOG_ERR, "write_path: %s: %m", path);
|
||||
#ifdef DEBUG_MEMORY
|
||||
syslog(LOG_INFO, "%s: restoring Kernel IPv6 RA support",
|
||||
restore[nrestore]);
|
||||
snprintf(path, sizeof(path), "%s/%s/accept_ra",
|
||||
prefix, restore[nrestore]);
|
||||
if (write_path(path, "1") == -1 && errno != ENOENT)
|
||||
syslog(LOG_ERR, "write_path: %s: %m", path);
|
||||
}
|
||||
free(restore[nrestore]);
|
||||
#endif
|
||||
}
|
||||
#ifdef DEBUG_MEMORY
|
||||
free(restore);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
check_ipv6(const char *ifname, int own)
|
||||
{
|
||||
static int ipv6_checked = 0;
|
||||
int ra, ex, i;
|
||||
int ra, i;
|
||||
char path[256], *p, **nrest;
|
||||
|
||||
if (ifname == NULL) {
|
||||
if (ipv6_checked)
|
||||
return 1;
|
||||
ipv6_checked = 1;
|
||||
if (ifname == NULL)
|
||||
ifname = "all";
|
||||
ex = 1;
|
||||
} else
|
||||
ex = 0;
|
||||
|
||||
snprintf(path, sizeof(path), "%s/%s/autoconf", prefix, ifname);
|
||||
i = check_proc_int(path);
|
||||
@ -232,8 +217,6 @@ check_ipv6(const char *ifname, int own)
|
||||
restore[nrestore++] = p;
|
||||
|
||||
}
|
||||
if (ex)
|
||||
atexit(restore_kernel_ra);
|
||||
}
|
||||
|
||||
return ra;
|
||||
|
@ -32,8 +32,10 @@ char *hardware_platform(void);
|
||||
#ifdef INET6
|
||||
int check_ipv6(const char *, int);
|
||||
int ipv6_dadtransmits(const char *);
|
||||
void restore_kernel_ra(void);
|
||||
#else
|
||||
#define check_ipv6(a, b) -1
|
||||
#define restore_kernel_ra(a)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user