diff --git a/FTL.h b/FTL.h index 67922afb..f50f9825 100644 --- a/FTL.h +++ b/FTL.h @@ -248,12 +248,12 @@ extern unsigned char blockingstatus; extern char ** wildcarddomains; extern memoryStruct memory; -extern bool runtest; extern char * username; extern char timestamp[16]; extern bool flush; extern bool needGC; +extern bool daemonmode; extern bool database; extern long int lastdbindex; extern bool travis; diff --git a/args.c b/args.c index 089fa5fd..e09c8b13 100644 --- a/args.c +++ b/args.c @@ -12,7 +12,7 @@ #include "version.h" bool debug = false; -bool runtest = false; +bool daemonmode = true; bool travis = false; int argc_dnsmasq = 0; char **argv_dnsmasq = NULL; @@ -82,11 +82,10 @@ void parse_args(int argc, char* argv[]) } // Don't go into background - // This is a no-op but we still support it - // for backwards compatibility if(strcmp(argv[i], "-f") == 0 || strcmp(argv[i], "no-daemon") == 0) { + daemonmode = false; ok = true; } @@ -145,9 +144,8 @@ void parse_args(int argc, char* argv[]) printf("\t-v, version Return version\n"); printf("\t-t, tag Return git tag\n"); printf("\t-b, branch Return git branch\n"); - printf("\t process is running and exit\n"); - printf("\t even if not (instead of\n"); - printf("\t starting a new one)\n"); + printf("\t-f, no-daemon Don't go into daemon mode\n"); + printf("\t-h, help Display this help and exit\n"); printf("\tdnsmasq-test Test syntax of dnsmasq's\n"); printf("\t config files and exit\n"); printf("\n\nOnline help: https://github.com/pi-hole/FTL\n"); diff --git a/daemon.c b/daemon.c index 92ff614e..c535f857 100644 --- a/daemon.c +++ b/daemon.c @@ -9,10 +9,77 @@ * Please see LICENSE file for your rights under this license. */ #include "FTL.h" -#include struct timeval t0[NUMTIMERS]; +void go_daemon(void) +{ + pid_t process_id = 0; + pid_t sid = 0; + + // Create child process + process_id = fork(); + + // Indication of fork() failure + if (process_id < 0) + { + logg("fork failed!\n"); + // Return failure in exit status + exit(EXIT_FAILURE); + } + + // PARENT PROCESS. Need to kill it. + if (process_id > 0) + { + printf("FTL started!\n"); + // return success in exit status + exit(EXIT_SUCCESS); + } + + //unmask the file mode + umask(0); + + //set new session + // creates a session and sets the process group ID + sid = setsid(); + if(sid < 0) + { + // Return failure + logg("setsid failed!\n"); + exit(EXIT_FAILURE); + } + + // Create grandchild process + // Fork a second child and exit immediately to prevent zombies. This + // causes the second child process to be orphaned, making the init + // process responsible for its cleanup. And, since the first child is + // a session leader without a controlling terminal, it's possible for + // it to acquire one by opening a terminal in the future (System V- + // based systems). This second fork guarantees that the child is no + // longer a session leader, preventing the daemon from ever acquiring + // a controlling terminal. + process_id = fork(); + + // Indication of fork() failure + if (process_id < 0) + { + logg("fork failed!\n"); + // Return failure in exit status + exit(EXIT_FAILURE); + } + + // PARENT PROCESS. Need to kill it. + if (process_id > 0) + { + // return success in exit status + exit(EXIT_SUCCESS); + } + + savepid(); + + // Closing stdin, stdout and stderr is handled by dnsmasq +} + void timer_start(int i) { if(i >= NUMTIMERS) diff --git a/datastructure.c b/datastructure.c index 9f3b0d32..3d9a3242 100644 --- a/datastructure.c +++ b/datastructure.c @@ -241,15 +241,18 @@ int detectStatus(const char *domain) // Note that this is a really expensive subroutine and trying to match // blocked domains against all configured wildcards will take some time int i; + + // Return early if no wildcard domains are defined + if(counters.wildcarddomains < 1) + return QUERY_CACHE; + validate_access("wildcarddomains", counters.wildcarddomains-1, false, __LINE__, __FUNCTION__, __FILE__); for(i=0; i < counters.wildcarddomains; i++) { if(strcasecmp(wildcarddomains[i], domain) == 0) { // Exact match with wildcard domain - // if(debug) - // printf("%s / %s (exact wildcard match)\n",wildcarddomains[i], domain); - return 4; + return QUERY_WILDCARD; } // Create copy of domain under investigation char * part = strdup(domain); @@ -274,13 +277,11 @@ int detectStatus(const char *domain) // Test for a match if(strcasecmp(wildcarddomains[i], partbuffer) == 0) { - // Free allocated memory before return'ing + // Free allocated memory before returning free(part); free(partbuffer); // Return match with wildcard domain - // if(debug) - // printf("%s / %s (wildcard match)\n",wildcarddomains[i], partbuffer); - return 4; + return QUERY_WILDCARD; } if(strlen(partbuffer) > 0) { @@ -299,5 +300,5 @@ int detectStatus(const char *domain) // wildcard blocking, but from e.g. an // address=// configuration // Answer as "cached" - return 3; + return QUERY_CACHE; } diff --git a/dnsmasq/dnsmasq.c b/dnsmasq/dnsmasq.c index c5e768b0..54a47da8 100644 --- a/dnsmasq/dnsmasq.c +++ b/dnsmasq/dnsmasq.c @@ -570,7 +570,7 @@ int main_dnsmasq (int argc, char **argv) } } - FTL_start_threads(); + FTL_fork_and_bind_sockets(); log_err = log_start(ent_pw, err_pipe[1]); diff --git a/dnsmasq_interface.c b/dnsmasq_interface.c index 2f035010..7baa500a 100644 --- a/dnsmasq_interface.c +++ b/dnsmasq_interface.c @@ -735,10 +735,12 @@ pthread_t socket_listenthread; pthread_t DBthread; pthread_t GCthread; -void FTL_start_threads(void) +void FTL_fork_and_bind_sockets(void) { - // Save PID - savepid(); + if(!debug && daemonmode) + go_daemon(); + else + savepid(); // We will use the attributes object later to start all threads in detached mode pthread_attr_t attr; diff --git a/dnsmasq_interface.h b/dnsmasq_interface.h index e7e7a20b..7872be16 100644 --- a/dnsmasq_interface.h +++ b/dnsmasq_interface.h @@ -16,7 +16,7 @@ void FTL_reply(unsigned short flags, char *name, struct all_addr *addr, int id); void FTL_cache(unsigned int flags, char *name, struct all_addr *addr, char * arg, int id); void FTL_dnssec(int status, int id); void FTL_dnsmasq_reload(void); -void FTL_start_threads(void); +void FTL_fork_and_bind_sockets(void); void FTL_forwarding_failed(struct server *server); int FTL_listsfile(char* filename, unsigned int index, FILE *f, int cache_size, struct crec **rhash, int hashsz); diff --git a/socket.c b/socket.c index eae35635..61944192 100644 --- a/socket.c +++ b/socket.c @@ -300,12 +300,12 @@ void *telnet_connection_handler_thread(void *socket_desc) // Set connection type to telnet istelnet[sock] = true; - int sockID = sock; + // Define buffer for client's message char client_message[SOCKETBUFFERLEN] = ""; // Set thread name char threadname[16]; - sprintf(threadname,"telnet-%i",sockID); + sprintf(threadname,"telnet-%i",sock); prctl(PR_SET_NAME,threadname,0,0,0); //Receive from client ssize_t n;