Commit Diff
Diff:
e1ea0c7dafdd5228b6c39e9685f7ca8a126d6562
06aa4e5703d1d1b7a38cfc204ff6cee750a51642
Commit:
06aa4e5703d1d1b7a38cfc204ff6cee750a51642
Tree:
577bc453b2a7849066b69f5e3c82eb1405578ad8
Author:
pbug <pbug@delphinusdns.org>
Committer:
pbug <pbug@delphinusdns.org>
Date:
Tue Apr 12 10:45:49 2011 UTC
Message:
* when a slave dies it will signal to the master that it died which then will bring all the other slaves down. It polls every second for this via shared memory (anonymous mmap).
blob - a9a98b218e3f77f046a2d426ad30aec388eef779
blob + 69f569b584e1c127908eefdacbbe232d9870758c
--- include.h
+++ include.h
@@ -34,6 +34,7 @@
#include <sys/stat.h>
#include <sys/uio.h>
#include <sys/queue.h>
+#include <sys/mman.h>
#include <net/if.h>
blob - 257f1e15748cd3d1bb9e6da15539e23917632e83
blob + 1316102eebff35676343eaa1fd8623f42246e3d0
--- main.c
+++ main.c
@@ -67,6 +67,9 @@ void build_reply(struct sreply *reply, int so, char *b
void recurseheader(struct srecurseheader *, int, struct sockaddr_storage *, struct sockaddr_storage *, int);
void setup_master(int);
void master_shutdown(int);
+void slave_shutdown(void);
+void slave_signal(int);
+
/* aliases */
#define DEFAULT_PRIVILEGE "named"
@@ -97,6 +100,7 @@ extern char *__progname;
static int lflag = 0;
static int rflag = 0;
static u_int16_t port = 53;
+static int *ptr = NULL;
/* singly linked list for tcp operations */
SLIST_HEAD(listhead, tcps) tcpshead;
@@ -117,7 +121,7 @@ struct tcps {
} *tn1, *tn2, *tnp;
-static const char rcsid[] = "$Id: main.c,v 1.61 2011/04/12 09:32:31 pbug Exp $";
+static const char rcsid[] = "$Id: main.c,v 1.62 2011/04/12 10:45:49 pbug Exp $";
/*
* MAIN - set up arguments, set up database, set up sockets, call mainloop
@@ -212,7 +216,23 @@ main(int argc, char *argv[])
openlog(__progname, LOG_PID | LOG_NDELAY, LOG_DAEMON);
syslog(LOG_INFO, "starting up");
+ /*
+ * make a shared memory segment for signaling kills between
+ * processes...
+ */
+
+ ptr = mmap(NULL, sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED |\
+ MAP_ANON, -1, 0);
+
+ if (ptr == MAP_FAILED) {
+ syslog(LOG_ERR, "failed to setup mmap segment, exit");
+ exit(1);
+ }
+
+ *ptr = 0;
+
+
/* make a master program that holds the pidfile, boss of ... eek */
pid = fork();
@@ -233,18 +253,21 @@ main(int argc, char *argv[])
if (db_create((DB **)&db, (DB_ENV *)NULL, 0) != 0) {
syslog(LOG_INFO, "db_create: %m");
+ slave_shutdown();
exit(1);
}
#if DB_VERSION_MINOR > 0
if (db->open(db, NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0600) != 0) {
syslog(LOG_INFO, "db->open: %m");
db->close(db, DB_NOSYNC);
+ slave_shutdown();
exit(1);
}
#else
if (db->open(db, NULL, NULL, DB_BTREE, DB_CREATE, 0600) != 0) {
syslog(LOG_INFO, "db->open: %m");
db->close(db, DB_NOSYNC);
+ slave_shutdown();
exit(1);
}
#endif /*minor*/
@@ -255,6 +278,7 @@ main(int argc, char *argv[])
if (db == NULL) {
syslog(LOG_INFO, "dbopen: %m");
+ slave_shutdown();
exit(1);
}
@@ -264,17 +288,20 @@ main(int argc, char *argv[])
if (parse_file(db, conffile) < 0) {
syslog(LOG_INFO, "parsing config file failed");
+ slave_shutdown();
exit(1);
}
pw = getpwnam(DEFAULT_PRIVILEGE);
if (pw == NULL) {
syslog(LOG_INFO, "getpwnam: %m");
+ slave_shutdown();
exit(1);
}
if (bcount > DEFAULT_SOCKET) {
syslog(LOG_INFO, "not enough sockets available\n");
+ slave_shutdown();
exit(1);
}
@@ -296,6 +323,7 @@ main(int argc, char *argv[])
if ((gai_error = getaddrinfo(bind_list[i], buf, &hints, &res0)) != 0) {
syslog(LOG_INFO, "getaddrinfo: %s\n", gai_strerror(gai_error));
+ slave_shutdown();
exit (1);
}
@@ -303,11 +331,13 @@ main(int argc, char *argv[])
if ((udp[i] = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) {
syslog(LOG_INFO, "socket: %m");
+ slave_shutdown();
exit(1);
}
if (bind(udp[i], res->ai_addr, res->ai_addrlen) < 0) {
syslog(LOG_INFO, "bind: %m");
+ slave_shutdown();
exit(1);
}
@@ -334,6 +364,7 @@ main(int argc, char *argv[])
if ((gai_error = getaddrinfo(bind_list[i], buf, &hints, &res0)) != 0) {
syslog(LOG_INFO, "getaddrinfo: %s\n", gai_strerror(gai_error));
+ slave_shutdown();
exit (1);
}
@@ -341,14 +372,17 @@ main(int argc, char *argv[])
if ((tcp[i] = socket(res->ai_family, res->ai_socktype, res->ai_protocol)) < 0) {
syslog(LOG_INFO, "tcp socket: %m");
+ slave_shutdown();
exit(1);
}
if (setsockopt(tcp[i], SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
syslog(LOG_INFO, "setsockopt: %m");
+ slave_shutdown();
exit(1);
}
if (bind(tcp[i], res->ai_addr, res->ai_addrlen) < 0) {
syslog(LOG_INFO, "tcp bind: %m");
+ slave_shutdown();
exit(1);
}
@@ -357,6 +391,7 @@ main(int argc, char *argv[])
} else {
if (getifaddrs(&ifap) < 0) {
syslog(LOG_INFO, "getifaddrs");
+ slave_shutdown();
exit(1);
}
@@ -410,11 +445,13 @@ main(int argc, char *argv[])
if ((udp[i] = socket(pifap->ifa_addr->sa_family, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
syslog(LOG_INFO, "socket: %m");
+ slave_shutdown();
exit(1);
}
if (bind(udp[i], (struct sockaddr *)pifap->ifa_addr, salen) < 0) {
syslog(LOG_INFO, "bind: %m");
+ slave_shutdown();
exit(1);
}
@@ -434,22 +471,26 @@ main(int argc, char *argv[])
if ((tcp[i] = socket(pifap->ifa_addr->sa_family, SOCK_STREAM, IPPROTO_TCP)) < 0) {
syslog(LOG_INFO, "tcp socket: %m");
+ slave_shutdown();
exit(1);
}
if (setsockopt(tcp[i], SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) < 0) {
syslog(LOG_INFO, "setsockopt: %m");
+ slave_shutdown();
exit(1);
}
if (bind(tcp[i], (struct sockaddr *)pifap->ifa_addr, salen) < 0) {
syslog(LOG_INFO, "tcp bind: %m");
+ slave_shutdown();
exit(1);
- }
+ }
} /* AF_INET */
if (i >= DEFAULT_SOCKET) {
syslog(LOG_INFO, "not enough sockets available\n");
+ slave_shutdown();
exit(1);
}
}
@@ -457,16 +498,19 @@ main(int argc, char *argv[])
if (rflag == 1) {
if ((raw[0] = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0) {
syslog(LOG_INFO, "raw socket: %m");
+ slave_shutdown();
exit(1);
}
if (setsockopt(raw[0], IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) < 0) {
syslog(LOG_INFO, "raw setsockopt: %m");
+ slave_shutdown();
exit(1);
}
if ((raw[1] = socket(AF_INET6, SOCK_RAW, IPPROTO_UDP)) < 0) {
syslog(LOG_INFO, "raw socket[1]: %m");
+ slave_shutdown();
exit(1);
}
@@ -475,22 +519,28 @@ main(int argc, char *argv[])
/* chroot to the drop priv user home directory */
if (chroot(pw->pw_dir) < 0) {
syslog(LOG_INFO, "chroot: %m");
+ slave_shutdown();
exit(1);
}
if (chdir("/") < 0) {
syslog(LOG_INFO, "chdir: %m");
+ slave_shutdown();
exit(1);
}
#endif
/*
- * ignore SIGPIPE signal
+ * add signals
*/
signal(SIGPIPE, SIG_IGN);
+ signal(SIGTERM, slave_signal);
+ signal(SIGINT, slave_signal);
+ signal(SIGQUIT, slave_signal);
+
/*
* I open the log again after the chroot just in case I can't
* reach the old /dev/log anymore.
@@ -503,27 +553,32 @@ main(int argc, char *argv[])
if (setgroups(1, &pw->pw_gid) < 0) {
syslog(LOG_INFO, "setgroups: %m");
+ slave_shutdown();
exit(1);
}
#ifdef __OpenBSD__
if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) < 0) {
syslog(LOG_INFO, "setresgid: %m");
+ slave_shutdown();
exit(1);
}
if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0) {
syslog(LOG_INFO, "setresuid: %m");
+ slave_shutdown();
exit(1);
}
#else
if (setgid(pw->pw_gid) < 0) {
syslog(LOG_INFO, "setgid: %m");
+ slave_shutdown();
exit(1);
}
if (setuid(pw->pw_uid) < 0) {
syslog(LOG_INFO, "setuid: %m");
+ slave_shutdown();
exit(1);
}
#endif
@@ -535,12 +590,14 @@ main(int argc, char *argv[])
if (socketpair(AF_UNIX, SOCK_DGRAM, 0, (int *)&sp) < 0) {
syslog(LOG_INFO, "socketpair: %m");
+ slave_shutdown();
exit(1);
}
switch (pid = fork()) {
case -1:
syslog(LOG_INFO, "fork: %m");
+ slave_shutdown();
exit(1);
case 0:
@@ -2605,6 +2662,12 @@ recurseheader(struct srecurseheader *rh, int proto, st
return;
}
+/*
+ * The master process, waits to be killed, if any other processes are killed
+ * and they indicate shutdown through the shared memory segment it will kill
+ * the rest of processes in the parent group.
+ */
+
void
setup_master(int port)
{
@@ -2612,7 +2675,9 @@ setup_master(int port)
pid_t pid;
int fd;
+#ifndef __linux__
setproctitle("wildcarddnsd master on port %u", port);
+#endif
fd = open(PIDFILE, O_WRONLY | O_APPEND | O_CREAT, 0644);
if (fd < 0) {
@@ -2629,14 +2694,25 @@ setup_master(int port)
close(fd);
signal(SIGTERM, master_shutdown);
+ signal(SIGINT, master_shutdown);
+ signal(SIGQUIT, master_shutdown);
for (;;) {
- sleep(10);
+ sleep(1);
+
+ if (*ptr) {
+ syslog(LOG_INFO, "pid %u died, killing wildcarddnsd", *ptr);
+ master_shutdown(SIGTERM);
+ }
}
/* NOTREACHED */
}
+/*
+ * master_shutdown - unlink pid file and kill parent group
+ */
+
void
master_shutdown(int sig)
{
@@ -2645,7 +2721,34 @@ master_shutdown(int sig)
unlink(PIDFILE);
pid = getpgrp();
- killpg(pid, SIGTERM);
+ killpg(pid, sig);
exit(0);
+}
+
+/*
+ * slave_shutdown - a slave wishes to shutdown, enter its pid into the
+ * shutdown shared memory and return.
+ */
+
+void
+slave_shutdown(void)
+{
+ pid_t pid;
+
+ pid = getpid();
+
+ *ptr = pid;
+}
+
+/*
+ * slave_signal - a slave got a signal, call slave_shutdown and exit..
+ */
+
+void
+slave_signal(int sig)
+{
+ slave_shutdown();
+ syslog(LOG_INFO, "shutting down on signal");
+ exit(1);
}
blob - 768419ee353a87cd570d33d2ee38b1098604fb68
blob + 6a884b1035d4af7a8d8f2d60fa58d6bf6fdc5b52
--- parse.c
+++ parse.c
@@ -35,6 +35,8 @@ extern void init_region(void);
extern int insert_region(char *address, char *prefix, u_int8_t region);
extern int insert_wildcard(char *address, char *prefixlen);
extern int insert_recurse(char *, char *);
+extern void slave_shutdown(void);
+
static int parse_file0(char *filename, DB *db, FILE *f);
struct myrr_lookup {
@@ -84,7 +86,7 @@ struct cmd_lookup {
static u_int32_t config = 0;
-static const char rcsid[] = "$Id: parse.c,v 1.29 2011/02/13 18:06:53 pbug Exp $";
+static const char rcsid[] = "$Id: parse.c,v 1.30 2011/04/12 10:45:49 pbug Exp $";
/*
* PARSE_FILE - parse the configfile XXX rewrite me in yacc :(
@@ -374,6 +376,7 @@ parse_file0(char *filename, DB *db, FILE *f)
converted_name = (char *)malloc(1);
if (converted_name == NULL) {
syslog(LOG_INFO, "malloc: %m");
+ slave_shutdown();
exit(1);
}
*converted_name = '*';
@@ -382,6 +385,7 @@ parse_file0(char *filename, DB *db, FILE *f)
converted_name = (char *)malloc(1);
if (converted_name == NULL) {
syslog(LOG_INFO, "malloc: %m");
+ slave_shutdown();
exit(1);
}
*converted_name = '\0';
@@ -390,6 +394,7 @@ parse_file0(char *filename, DB *db, FILE *f)
converted_name = dns_label(domainname, &converted_namelen);
if (converted_name == NULL) {
fprintf(stderr, "(XXX) illegal domain name line %d\n", line);
+ slave_shutdown();
exit(1);
}
}
@@ -1205,18 +1210,21 @@ opendatabase(DB *ret)
if (db_create((DB **)&ret, (DB_ENV *)NULL, 0) != 0) {
syslog(LOG_INFO, "db_create: %m");
+ slave_shutdown();
exit(1);
}
#if DB_VERSION_MINOR > 0
if (ret->open(ret, NULL, NULL, NULL, DB_BTREE, DB_CREATE, 0600) != 0) {
syslog(LOG_INFO, "db->open: %m");
ret->close(ret, DB_NOSYNC);
+ slave_shutdown();
exit(1);
}
#else
if (ret->open(ret, NULL, NULL, DB_BTREE, DB_CREATE, 0600) != 0) {
syslog(LOG_INFO, "db->open: %m");
ret->close(ret, DB_NOSYNC);
+ slave_shutdown();
exit(1);
}
#endif /*minor*/
@@ -1227,6 +1235,7 @@ opendatabase(DB *ret)
if (ret == NULL) {
syslog(LOG_INFO, "dbopen: %m");
+ slave_shutdown();
exit(1);
}
blob - 2dfafc999c8c4e3bd3a3b533dd6b5290beaa742c
blob + 7f9ab3f81db8c4c3f9cdf86f32a6208f1c9f7081
--- recurse.c
+++ recurse.c
@@ -29,10 +29,6 @@
#include "dns.h"
#include "db.h"
-void init_recurse(void);
-int find_recurse(struct sockaddr_storage *sst, int family);
-int insert_recurse(char *address, char *prefixlen);
-void recurseloop(int sp, int *raw, DB *db);
extern void update_db(DB *, struct domain *);
extern in_addr_t getmask(int prefixlen);
extern int getmask6(int prefixlen, struct sockaddr_in6 *sin6);
@@ -40,6 +36,12 @@ extern struct question * build_question(char *buf, int
extern struct question * build_fake_question(char *, int, u_int16_t);
extern int free_question(struct question *);
extern int lookup_zone(DB *db, struct question *question, struct domain *sd, int *lzerrno, char *replystring, int wildcard);
+extern void slave_shutdown(void);
+
+void init_recurse(void);
+int find_recurse(struct sockaddr_storage *sst, int family);
+int insert_recurse(char *address, char *prefixlen);
+void recurseloop(int sp, int *raw, DB *db);
int lookup_ns(DB *, struct recurses *);
int lookup_a(DB *, struct recurses *, struct ns *);
int recurse_parse(DB *db, struct recurses *sr, u_char *buf, u_int16_t offset);
@@ -50,6 +52,7 @@ void reply_raw(DB *db, struct recurses *sr, struct dom
void reply_raw_cname(DB *db, struct recurses *sr, struct domain *sd, int *raw);
void reply_raw_noerror(DB *, struct recurses *, struct domain *, int *);
void reply_raw_nxdomain(DB *, struct recurses *, struct domain *, int *);
+
extern void build_reply(struct sreply *reply, int so, char *buf, int len, struct question *q, struct sockaddr *sa, socklen_t slen, struct domain *sd1, struct domain *sd2, u_int8_t region, int istcp, int wildcard, struct recurses *sr);
extern void reply_a(struct sreply *, DB *);
extern void reply_aaaa(struct sreply *, DB *);
@@ -87,7 +90,7 @@ struct recurseentry {
} *rn1, *rn2, *rnp;
-static const char rcsid[] = "$Id: recurse.c,v 1.34 2011/02/28 21:04:56 pbug Exp $";
+static const char rcsid[] = "$Id: recurse.c,v 1.35 2011/04/12 10:45:49 pbug Exp $";
/*
* INIT_RECURSE - initialize the recurse singly linked list
@@ -474,6 +477,7 @@ recurseloop(int sp, int *raw, DB *db)
/* check if we're flooding anything */
if (sr1->packetcount > 50) {
syslog(LOG_ERR, "packetcount is over 50, I think I'm flooding something, abort()");
+ slave_shutdown();
abort();
}
blob - 561916569f7f8e373874c9826f5f4307d32c5ad3
blob + 2bc861b56b84af29eb5706c5dcefdd01778dde82
--- reply.c
+++ reply.c
@@ -54,6 +54,7 @@ extern int additional_ptr(char *, int, struct domain *
extern struct question * build_fake_question(char *, int, u_int16_t);
extern int free_question(struct question *);
extern int lookup_zone(DB *, struct question *, struct domain *, int *, char *, int);
+extern void slave_shutdown(void);
void update_db(DB *, struct domain *);
struct domain * Lookup_zone(DB *db, char *name, u_int16_t namelen, u_int16_t type, int);
@@ -79,7 +80,7 @@ struct collects {
} *cn1, *cn2, *cnp;
-static const char rcsid[] = "$Id: reply.c,v 1.44 2011/02/13 18:06:53 pbug Exp $";
+static const char rcsid[] = "$Id: reply.c,v 1.45 2011/04/12 10:45:49 pbug Exp $";
/*
* REPLY_A() - replies a DNS question (*q) on socket (so)
@@ -2119,6 +2120,7 @@ update_db(DB *db, struct domain *sd)
do {
if (++i == 32) {
syslog(LOG_ERR, "could not update zone for 32 tries, giving up entire database, quit");
+ slave_shutdown();
exit(1);
}
repomaster@centroid.eu