xref: /netbsd-src/external/bsd/unbound/dist/testcode/testbound.c (revision 7a540f2bd4f5b968566c2607d6462c7f2fb452cf)
13b6c3722Schristos /*
23b6c3722Schristos  * testcode/testbound.c - test program for unbound.
33b6c3722Schristos  *
43b6c3722Schristos  * Copyright (c) 2007, NLnet Labs. All rights reserved.
53b6c3722Schristos  *
63b6c3722Schristos  * This software is open source.
73b6c3722Schristos  *
83b6c3722Schristos  * Redistribution and use in source and binary forms, with or without
93b6c3722Schristos  * modification, are permitted provided that the following conditions
103b6c3722Schristos  * are met:
113b6c3722Schristos  *
123b6c3722Schristos  * Redistributions of source code must retain the above copyright notice,
133b6c3722Schristos  * this list of conditions and the following disclaimer.
143b6c3722Schristos  *
153b6c3722Schristos  * Redistributions in binary form must reproduce the above copyright notice,
163b6c3722Schristos  * this list of conditions and the following disclaimer in the documentation
173b6c3722Schristos  * and/or other materials provided with the distribution.
183b6c3722Schristos  *
193b6c3722Schristos  * Neither the name of the NLNET LABS nor the names of its contributors may
203b6c3722Schristos  * be used to endorse or promote products derived from this software without
213b6c3722Schristos  * specific prior written permission.
223b6c3722Schristos  *
233b6c3722Schristos  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
243b6c3722Schristos  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
253b6c3722Schristos  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
263b6c3722Schristos  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
273b6c3722Schristos  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
283b6c3722Schristos  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
293b6c3722Schristos  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
303b6c3722Schristos  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
313b6c3722Schristos  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
323b6c3722Schristos  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
333b6c3722Schristos  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
343b6c3722Schristos  *
353b6c3722Schristos  */
363b6c3722Schristos /**
373b6c3722Schristos  * \file
383b6c3722Schristos  * Exits with code 1 on a failure. 0 if all unit tests are successful.
393b6c3722Schristos  */
403b6c3722Schristos 
413b6c3722Schristos #include "config.h"
423b6c3722Schristos #ifdef HAVE_TIME_H
433b6c3722Schristos #  include <time.h>
443b6c3722Schristos #endif
45d0eba39bSchristos #include <ctype.h>
463b6c3722Schristos #include "testcode/testpkts.h"
473b6c3722Schristos #include "testcode/replay.h"
483b6c3722Schristos #include "testcode/fake_event.h"
493b6c3722Schristos #include "daemon/remote.h"
50d0eba39bSchristos #include "libunbound/worker.h"
513b6c3722Schristos #include "util/config_file.h"
523b6c3722Schristos #include "sldns/keyraw.h"
53d0eba39bSchristos #ifdef UB_ON_WINDOWS
54d0eba39bSchristos #include "winrc/win_svc.h"
55d0eba39bSchristos #endif
563b6c3722Schristos 
573b6c3722Schristos /** signal that this is a testbound compile */
583b6c3722Schristos #define unbound_testbound 1
59d0eba39bSchristos /** renamed main routine */
60d0eba39bSchristos int daemon_main(int argc, char* argv[]);
613b6c3722Schristos /**
623b6c3722Schristos  * include the main program from the unbound daemon.
633b6c3722Schristos  * rename main to daemon_main to call it
643b6c3722Schristos  */
653b6c3722Schristos #define main daemon_main
663b6c3722Schristos #include "daemon/unbound.c"
673b6c3722Schristos #undef main
683b6c3722Schristos 
693b6c3722Schristos /** maximum line length for lines in the replay file. */
703b6c3722Schristos #define MAX_LINE_LEN 1024
713b6c3722Schristos /** config files (removed at exit) */
723b6c3722Schristos static struct config_strlist* cfgfiles = NULL;
733b6c3722Schristos 
7401049ae6Schristos #ifdef UNBOUND_ALLOC_STATS
7501049ae6Schristos #  define strdup(s) unbound_stat_strdup_log(s, __FILE__, __LINE__, __func__)
7601049ae6Schristos char* unbound_stat_strdup_log(char* s, const char* file, int line,
7701049ae6Schristos 	const char* func);
unbound_stat_strdup_log(char * s,const char * file,int line,const char * func)7801049ae6Schristos char* unbound_stat_strdup_log(char* s, const char* file, int line,
7901049ae6Schristos         const char* func) {
8001049ae6Schristos 	char* result;
8101049ae6Schristos 	size_t len;
8201049ae6Schristos 	if(!s) return NULL;
8301049ae6Schristos 	len = strlen(s);
8401049ae6Schristos 	log_info("%s:%d %s strdup(%u)", file, line, func, (unsigned)len+1);
8501049ae6Schristos 	result = unbound_stat_malloc(len+1);
8601049ae6Schristos 	memmove(result, s, len+1);
8701049ae6Schristos 	return result;
8801049ae6Schristos }
8901049ae6Schristos #endif /* UNBOUND_ALLOC_STATS */
9001049ae6Schristos 
913b6c3722Schristos /** give commandline usage for testbound. */
923b6c3722Schristos static void
testbound_usage(void)930cd9f4ecSchristos testbound_usage(void)
943b6c3722Schristos {
953b6c3722Schristos 	printf("usage: testbound [options]\n");
963b6c3722Schristos 	printf("\ttest the unbound daemon.\n");
973b6c3722Schristos 	printf("-h      this help\n");
983b6c3722Schristos 	printf("-p file	playback text file\n");
990cd9f4ecSchristos 	printf("-1 	detect SHA1 support (exit code 0 or 1)\n");
1003b6c3722Schristos 	printf("-2 	detect SHA256 support (exit code 0 or 1)\n");
1013b6c3722Schristos 	printf("-g 	detect GOST support (exit code 0 or 1)\n");
1023b6c3722Schristos 	printf("-e 	detect ECDSA support (exit code 0 or 1)\n");
1030cd9f4ecSchristos 	printf("-c 	detect CLIENT_SUBNET support (exit code 0 or 1)\n");
1040cd9f4ecSchristos 	printf("-i 	detect IPSECMOD support (exit code 0 or 1)\n");
1053b6c3722Schristos 	printf("-s 	testbound self-test - unit test of testbound parts.\n");
1063b6c3722Schristos 	printf("-o str  unbound commandline options separated by spaces.\n");
1073b6c3722Schristos 	printf("Version %s\n", PACKAGE_VERSION);
1083b6c3722Schristos 	printf("BSD licensed, see LICENSE file in source package.\n");
1093b6c3722Schristos 	printf("Report bugs to %s.\n", PACKAGE_BUGREPORT);
1103b6c3722Schristos }
1113b6c3722Schristos 
1123b6c3722Schristos /** Max number of arguments to pass to unbound. */
1133b6c3722Schristos #define MAXARG 100
1143b6c3722Schristos 
1153b6c3722Schristos /**
1163b6c3722Schristos  * Add options from string to passed argc. splits on whitespace.
1173b6c3722Schristos  * @param args: the option argument, "-v -p 12345" or so.
1183b6c3722Schristos  * @param pass_argc: ptr to the argc for unbound. Modified.
1193b6c3722Schristos  * @param pass_argv: the argv to pass to unbound. Modified.
1203b6c3722Schristos  */
1213b6c3722Schristos static void
add_opts(const char * args,int * pass_argc,char * pass_argv[])1223b6c3722Schristos add_opts(const char* args, int* pass_argc, char* pass_argv[])
1233b6c3722Schristos {
1243b6c3722Schristos 	const char *p = args, *np;
1253b6c3722Schristos 	size_t len;
1263b6c3722Schristos 	while(p && isspace((unsigned char)*p))
1273b6c3722Schristos 		p++;
1283b6c3722Schristos 	while(p && *p) {
1293b6c3722Schristos 		/* find location of next string and length of this one */
1303b6c3722Schristos 		if((np = strchr(p, ' ')))
1313b6c3722Schristos 			len = (size_t)(np-p);
1323b6c3722Schristos 		else	len = strlen(p);
1333b6c3722Schristos 		/* allocate and copy option */
1343b6c3722Schristos 		if(*pass_argc >= MAXARG-1)
1353b6c3722Schristos 			fatal_exit("too many arguments: '%s'", p);
1363b6c3722Schristos 		pass_argv[*pass_argc] = (char*)malloc(len+1);
1373b6c3722Schristos 		if(!pass_argv[*pass_argc])
1383b6c3722Schristos 			fatal_exit("add_opts: out of memory");
1393b6c3722Schristos 		memcpy(pass_argv[*pass_argc], p, len);
1403b6c3722Schristos 		pass_argv[*pass_argc][len] = 0;
1413b6c3722Schristos 		(*pass_argc)++;
1423b6c3722Schristos 		/* go to next option */
1433b6c3722Schristos 	        p = np;
1443b6c3722Schristos 		while(p && isspace((unsigned char)*p))
1453b6c3722Schristos 			p++;
1463b6c3722Schristos 	}
1473b6c3722Schristos }
1483b6c3722Schristos 
1493b6c3722Schristos /** pretty print commandline for unbound in this test */
1503b6c3722Schristos static void
echo_cmdline(int argc,char * argv[])1513b6c3722Schristos echo_cmdline(int argc, char* argv[])
1523b6c3722Schristos {
1533b6c3722Schristos 	int i;
1543b6c3722Schristos 	fprintf(stderr, "testbound is starting:");
1553b6c3722Schristos 	for(i=0; i<argc; i++) {
1563b6c3722Schristos 		fprintf(stderr, " [%s]", argv[i]);
1573b6c3722Schristos 	}
1583b6c3722Schristos 	fprintf(stderr, "\n");
1593b6c3722Schristos }
1603b6c3722Schristos 
1617cd94d69Schristos /** spool temp file name */
1627cd94d69Schristos static void
spool_temp_file_name(int * lineno,FILE * cfg,char * id)1637cd94d69Schristos spool_temp_file_name(int* lineno, FILE* cfg, char* id)
1647cd94d69Schristos {
1657cd94d69Schristos 	char line[MAX_LINE_LEN];
1667cd94d69Schristos 	/* find filename for new file */
1677cd94d69Schristos 	while(isspace((unsigned char)*id))
1687cd94d69Schristos 		id++;
1697cd94d69Schristos 	if(*id == '\0')
1707cd94d69Schristos 		fatal_exit("TEMPFILE_NAME must have id, line %d", *lineno);
171*7a540f2bSchristos 	strip_end_white(id);
1727cd94d69Schristos 	fake_temp_file("_temp_", id, line, sizeof(line));
1737cd94d69Schristos 	fprintf(cfg, "\"%s\"\n", line);
1747cd94d69Schristos }
1757cd94d69Schristos 
1767cd94d69Schristos /** spool temp file */
1777cd94d69Schristos static void
spool_temp_file(FILE * in,int * lineno,char * id)1787cd94d69Schristos spool_temp_file(FILE* in, int* lineno, char* id)
1797cd94d69Schristos {
1807cd94d69Schristos 	char line[MAX_LINE_LEN];
1817cd94d69Schristos 	char* parse;
1827cd94d69Schristos 	FILE* spool;
1837cd94d69Schristos 	/* find filename for new file */
1847cd94d69Schristos 	while(isspace((unsigned char)*id))
1857cd94d69Schristos 		id++;
1867cd94d69Schristos 	if(*id == '\0')
1877cd94d69Schristos 		fatal_exit("TEMPFILE_CONTENTS must have id, line %d", *lineno);
188*7a540f2bSchristos 	strip_end_white(id);
1897cd94d69Schristos 	fake_temp_file("_temp_", id, line, sizeof(line));
1907cd94d69Schristos 	/* open file and spool to it */
1917cd94d69Schristos 	spool = fopen(line, "w");
1927cd94d69Schristos 	if(!spool) fatal_exit("could not open %s: %s", line, strerror(errno));
1937cd94d69Schristos 	fprintf(stderr, "testbound is spooling temp file: %s\n", line);
1947cd94d69Schristos 	if(!cfg_strlist_insert(&cfgfiles, strdup(line)))
1957cd94d69Schristos 		fatal_exit("out of memory");
1967cd94d69Schristos 	line[sizeof(line)-1] = 0;
1977cd94d69Schristos 	while(fgets(line, MAX_LINE_LEN-1, in)) {
1987cd94d69Schristos 		parse = line;
1997cd94d69Schristos 		(*lineno)++;
2007cd94d69Schristos 		while(isspace((unsigned char)*parse))
2017cd94d69Schristos 			parse++;
2027cd94d69Schristos 		if(strncmp(parse, "$INCLUDE_TEMPFILE", 17) == 0) {
2037cd94d69Schristos 			char l2[MAX_LINE_LEN-30]; /* -30 makes it fit with
2047cd94d69Schristos 				a preceding $INCLUDE in the buf line[] */
2057cd94d69Schristos 			char* tid = parse+17;
2067cd94d69Schristos 			while(isspace((unsigned char)*tid))
2077cd94d69Schristos 				tid++;
208*7a540f2bSchristos 			strip_end_white(tid);
2097cd94d69Schristos 			fake_temp_file("_temp_", tid, l2, sizeof(l2));
2107cd94d69Schristos 			snprintf(line, sizeof(line), "$INCLUDE %s\n", l2);
2117cd94d69Schristos 		}
2127cd94d69Schristos 		if(strncmp(parse, "TEMPFILE_END", 12) == 0) {
2137cd94d69Schristos 			fclose(spool);
2147cd94d69Schristos 			return;
2157cd94d69Schristos 		}
2167cd94d69Schristos 		fputs(line, spool);
2177cd94d69Schristos 	}
2187cd94d69Schristos 	fatal_exit("no TEMPFILE_END in input file");
2197cd94d69Schristos }
2207cd94d69Schristos 
2213b6c3722Schristos /** spool autotrust file */
2223b6c3722Schristos static void
spool_auto_file(FILE * in,int * lineno,FILE * cfg,char * id)2233b6c3722Schristos spool_auto_file(FILE* in, int* lineno, FILE* cfg, char* id)
2243b6c3722Schristos {
2253b6c3722Schristos 	char line[MAX_LINE_LEN];
2263b6c3722Schristos 	char* parse;
2273b6c3722Schristos 	FILE* spool;
2283b6c3722Schristos 	/* find filename for new file */
2293b6c3722Schristos 	while(isspace((unsigned char)*id))
2303b6c3722Schristos 		id++;
2313b6c3722Schristos 	if(*id == '\0')
2323b6c3722Schristos 		fatal_exit("AUTROTRUST_FILE must have id, line %d", *lineno);
233*7a540f2bSchristos 	strip_end_white(id);
2343b6c3722Schristos 	fake_temp_file("_auto_", id, line, sizeof(line));
2353b6c3722Schristos 	/* add option for the file */
2363b6c3722Schristos 	fprintf(cfg, "server:	auto-trust-anchor-file: \"%s\"\n", line);
2373b6c3722Schristos 	/* open file and spool to it */
2383b6c3722Schristos 	spool = fopen(line, "w");
2393b6c3722Schristos 	if(!spool) fatal_exit("could not open %s: %s", line, strerror(errno));
2403b6c3722Schristos 	fprintf(stderr, "testbound is spooling key file: %s\n", line);
2413b6c3722Schristos 	if(!cfg_strlist_insert(&cfgfiles, strdup(line)))
2423b6c3722Schristos 		fatal_exit("out of memory");
2433b6c3722Schristos 	line[sizeof(line)-1] = 0;
2443b6c3722Schristos 	while(fgets(line, MAX_LINE_LEN-1, in)) {
2453b6c3722Schristos 		parse = line;
2463b6c3722Schristos 		(*lineno)++;
2473b6c3722Schristos 		while(isspace((unsigned char)*parse))
2483b6c3722Schristos 			parse++;
2493b6c3722Schristos 		if(strncmp(parse, "AUTOTRUST_END", 13) == 0) {
2503b6c3722Schristos 			fclose(spool);
2513b6c3722Schristos 			return;
2523b6c3722Schristos 		}
2533b6c3722Schristos 		fputs(line, spool);
2543b6c3722Schristos 	}
2553b6c3722Schristos 	fatal_exit("no AUTOTRUST_END in input file");
2563b6c3722Schristos }
2573b6c3722Schristos 
2583b6c3722Schristos /** process config elements */
2593b6c3722Schristos static void
setup_config(FILE * in,int * lineno,int * pass_argc,char * pass_argv[])2603b6c3722Schristos setup_config(FILE* in, int* lineno, int* pass_argc, char* pass_argv[])
2613b6c3722Schristos {
2623b6c3722Schristos 	char configfile[MAX_LINE_LEN];
2633b6c3722Schristos 	char line[MAX_LINE_LEN];
2643b6c3722Schristos 	char* parse;
2653b6c3722Schristos 	FILE* cfg;
2663b6c3722Schristos 	fake_temp_file("_cfg", "", configfile, sizeof(configfile));
2673b6c3722Schristos 	add_opts("-c", pass_argc, pass_argv);
2683b6c3722Schristos 	add_opts(configfile, pass_argc, pass_argv);
2693b6c3722Schristos 	cfg = fopen(configfile, "w");
2703b6c3722Schristos 	if(!cfg) fatal_exit("could not open %s: %s",
2713b6c3722Schristos 			configfile, strerror(errno));
2723b6c3722Schristos 	if(!cfg_strlist_insert(&cfgfiles, strdup(configfile)))
2733b6c3722Schristos 		fatal_exit("out of memory");
2743b6c3722Schristos 	line[sizeof(line)-1] = 0;
2753b6c3722Schristos 	/* some basic settings to not pollute the host system */
2763b6c3722Schristos 	fprintf(cfg, "server:	use-syslog: no\n");
2773b6c3722Schristos 	fprintf(cfg, "		directory: \"\"\n");
2783b6c3722Schristos 	fprintf(cfg, "		chroot: \"\"\n");
2793b6c3722Schristos 	fprintf(cfg, "		username: \"\"\n");
2803b6c3722Schristos 	fprintf(cfg, "		pidfile: \"\"\n");
2813b6c3722Schristos 	fprintf(cfg, "		val-log-level: 2\n");
282*7a540f2bSchristos 	fprintf(cfg, "		log-servfail: yes\n");
2833b6c3722Schristos 	fprintf(cfg, "remote-control:	control-enable: no\n");
2843b6c3722Schristos 	while(fgets(line, MAX_LINE_LEN-1, in)) {
2853b6c3722Schristos 		parse = line;
2863b6c3722Schristos 		(*lineno)++;
2873b6c3722Schristos 		while(isspace((unsigned char)*parse))
2883b6c3722Schristos 			parse++;
2893b6c3722Schristos 		if(!*parse || parse[0] == ';')
2903b6c3722Schristos 			continue;
2913b6c3722Schristos 		if(strncmp(parse, "COMMANDLINE", 11) == 0) {
2923b6c3722Schristos 			parse[strlen(parse)-1] = 0; /* strip off \n */
2933b6c3722Schristos 			add_opts(parse+11, pass_argc, pass_argv);
2943b6c3722Schristos 			continue;
2953b6c3722Schristos 		}
2963b6c3722Schristos 		if(strncmp(parse, "AUTOTRUST_FILE", 14) == 0) {
2973b6c3722Schristos 			spool_auto_file(in, lineno, cfg, parse+14);
2983b6c3722Schristos 			continue;
2993b6c3722Schristos 		}
3007cd94d69Schristos 		if(strncmp(parse, "TEMPFILE_NAME", 13) == 0) {
3017cd94d69Schristos 			spool_temp_file_name(lineno, cfg, parse+13);
3027cd94d69Schristos 			continue;
3037cd94d69Schristos 		}
3047cd94d69Schristos 		if(strncmp(parse, "TEMPFILE_CONTENTS", 17) == 0) {
3057cd94d69Schristos 			spool_temp_file(in, lineno, parse+17);
3067cd94d69Schristos 			continue;
3077cd94d69Schristos 		}
3083b6c3722Schristos 		if(strncmp(parse, "CONFIG_END", 10) == 0) {
3093b6c3722Schristos 			fclose(cfg);
3103b6c3722Schristos 			return;
3113b6c3722Schristos 		}
3123b6c3722Schristos 		fputs(line, cfg);
3133b6c3722Schristos 	}
3143b6c3722Schristos 	fatal_exit("No CONFIG_END in input file");
3153b6c3722Schristos 
3163b6c3722Schristos }
3173b6c3722Schristos 
3183b6c3722Schristos /** read playback file */
3193b6c3722Schristos static struct replay_scenario*
setup_playback(const char * filename,int * pass_argc,char * pass_argv[])3203b6c3722Schristos setup_playback(const char* filename, int* pass_argc, char* pass_argv[])
3213b6c3722Schristos {
3223b6c3722Schristos 	struct replay_scenario* scen = NULL;
3233b6c3722Schristos 	int lineno = 0;
3243b6c3722Schristos 
3253b6c3722Schristos 	if(filename) {
3263b6c3722Schristos 		FILE *in = fopen(filename, "rb");
3273b6c3722Schristos 		if(!in) {
3283b6c3722Schristos 			perror(filename);
3293b6c3722Schristos 			exit(1);
3303b6c3722Schristos 		}
3313b6c3722Schristos 		setup_config(in, &lineno, pass_argc, pass_argv);
3323b6c3722Schristos 		scen = replay_scenario_read(in, filename, &lineno);
3333b6c3722Schristos 		fclose(in);
3343b6c3722Schristos 		if(!scen)
3353b6c3722Schristos 			fatal_exit("Could not read: %s", filename);
3363b6c3722Schristos 	}
3373b6c3722Schristos 	else fatal_exit("need a playback file (-p)");
3383b6c3722Schristos 	log_info("Scenario: %s", scen->title);
3393b6c3722Schristos 	return scen;
3403b6c3722Schristos }
3413b6c3722Schristos 
3423b6c3722Schristos /** remove config file at exit */
remove_configfile(void)343d0eba39bSchristos static void remove_configfile(void)
3443b6c3722Schristos {
3453b6c3722Schristos 	struct config_strlist* p;
3463b6c3722Schristos 	for(p=cfgfiles; p; p=p->next)
3473b6c3722Schristos 		unlink(p->str);
3483b6c3722Schristos 	config_delstrlist(cfgfiles);
3493b6c3722Schristos 	cfgfiles = NULL;
3503b6c3722Schristos }
3513b6c3722Schristos 
3523b6c3722Schristos /**
3533b6c3722Schristos  * Main fake event test program. Setup, teardown and report errors.
3543b6c3722Schristos  * @param argc: arg count.
3553b6c3722Schristos  * @param argv: array of commandline arguments.
3563b6c3722Schristos  * @return program failure if test fails.
3573b6c3722Schristos  */
3583b6c3722Schristos int
main(int argc,char * argv[])3593b6c3722Schristos main(int argc, char* argv[])
3603b6c3722Schristos {
3613b6c3722Schristos 	int c, res;
3623b6c3722Schristos 	int pass_argc = 0;
3633b6c3722Schristos 	char* pass_argv[MAXARG];
3643b6c3722Schristos 	char* playback_file = NULL;
3653b6c3722Schristos 	int init_optind = optind;
3663b6c3722Schristos 	char* init_optarg = optarg;
3673b6c3722Schristos 	struct replay_scenario* scen = NULL;
3683b6c3722Schristos 
3693b6c3722Schristos 	/* we do not want the test to depend on the timezone */
3703b6c3722Schristos 	(void)putenv("TZ=UTC");
371f42d8de7Schristos 	memset(pass_argv, 0, sizeof(pass_argv));
372d0eba39bSchristos #ifdef HAVE_SYSTEMD
373d0eba39bSchristos 	/* we do not want the test to use systemd daemon startup notification*/
374d0eba39bSchristos 	(void)unsetenv("NOTIFY_SOCKET");
375d0eba39bSchristos #endif /* HAVE_SYSTEMD */
3763b6c3722Schristos 
377*7a540f2bSchristos 	checklock_start();
3783b6c3722Schristos 	log_init(NULL, 0, NULL);
3793b6c3722Schristos 	/* determine commandline options for the daemon */
3803b6c3722Schristos 	pass_argc = 1;
3813b6c3722Schristos 	pass_argv[0] = "unbound";
3823b6c3722Schristos 	add_opts("-d", &pass_argc, pass_argv);
3830cd9f4ecSchristos 	while( (c=getopt(argc, argv, "12egciho:p:s")) != -1) {
3843b6c3722Schristos 		switch(c) {
3853b6c3722Schristos 		case 's':
3863b6c3722Schristos 			free(pass_argv[1]);
3873b6c3722Schristos 			testbound_selftest();
3887cd94d69Schristos 			checklock_stop();
3897cd94d69Schristos 			if(log_get_lock()) {
39001049ae6Schristos 				lock_basic_destroy((lock_basic_type*)log_get_lock());
3917cd94d69Schristos 			}
3923b6c3722Schristos 			exit(0);
3930cd9f4ecSchristos 		case '1':
3940cd9f4ecSchristos #ifdef USE_SHA1
3950cd9f4ecSchristos 			printf("SHA1 supported\n");
3960cd9f4ecSchristos 			exit(0);
3970cd9f4ecSchristos #else
3980cd9f4ecSchristos 			printf("SHA1 not supported\n");
3990cd9f4ecSchristos 			exit(1);
4000cd9f4ecSchristos #endif
4010cd9f4ecSchristos 			break;
4023b6c3722Schristos 		case '2':
4033b6c3722Schristos #if (defined(HAVE_EVP_SHA256) || defined(HAVE_NSS) || defined(HAVE_NETTLE)) && defined(USE_SHA2)
4043b6c3722Schristos 			printf("SHA256 supported\n");
4053b6c3722Schristos 			exit(0);
4063b6c3722Schristos #else
4073b6c3722Schristos 			printf("SHA256 not supported\n");
4083b6c3722Schristos 			exit(1);
4093b6c3722Schristos #endif
4103b6c3722Schristos 			break;
4113b6c3722Schristos 		case 'e':
4123b6c3722Schristos #if defined(USE_ECDSA)
4133b6c3722Schristos 			printf("ECDSA supported\n");
4143b6c3722Schristos 			exit(0);
4153b6c3722Schristos #else
4163b6c3722Schristos 			printf("ECDSA not supported\n");
4173b6c3722Schristos 			exit(1);
4183b6c3722Schristos #endif
4193b6c3722Schristos 			break;
4203b6c3722Schristos 		case 'g':
4213b6c3722Schristos #ifdef USE_GOST
4223b6c3722Schristos 			if(sldns_key_EVP_load_gost_id()) {
4233b6c3722Schristos 				printf("GOST supported\n");
4243b6c3722Schristos 				exit(0);
4253b6c3722Schristos 			} else {
4263b6c3722Schristos 				printf("GOST not supported\n");
4273b6c3722Schristos 				exit(1);
4283b6c3722Schristos 			}
4293b6c3722Schristos #else
4303b6c3722Schristos 			printf("GOST not supported\n");
4313b6c3722Schristos 			exit(1);
4323b6c3722Schristos #endif
4333b6c3722Schristos 			break;
4340cd9f4ecSchristos 		case 'c':
4350cd9f4ecSchristos #ifdef CLIENT_SUBNET
4360cd9f4ecSchristos 			printf("CLIENT_SUBNET supported\n");
4370cd9f4ecSchristos 			exit(0);
4380cd9f4ecSchristos #else
4390cd9f4ecSchristos 			printf("CLIENT_SUBNET not supported\n");
4400cd9f4ecSchristos 			exit(1);
4410cd9f4ecSchristos #endif
4420cd9f4ecSchristos 			break;
4430cd9f4ecSchristos 		case 'i':
4440cd9f4ecSchristos #ifdef USE_IPSECMOD
4450cd9f4ecSchristos 			printf("IPSECMOD supported\n");
4460cd9f4ecSchristos 			exit(0);
4470cd9f4ecSchristos #else
4480cd9f4ecSchristos 			printf("IPSECMOD not supported\n");
4490cd9f4ecSchristos 			exit(1);
4500cd9f4ecSchristos #endif
4510cd9f4ecSchristos 			break;
4523b6c3722Schristos 		case 'p':
4533b6c3722Schristos 			playback_file = optarg;
4543b6c3722Schristos 			break;
4553b6c3722Schristos 		case 'o':
4563b6c3722Schristos 			add_opts(optarg, &pass_argc, pass_argv);
4573b6c3722Schristos 			break;
4583b6c3722Schristos 		case '?':
4593b6c3722Schristos 		case 'h':
4603b6c3722Schristos 		default:
4613b6c3722Schristos 			testbound_usage();
462f42d8de7Schristos 			exit(1);
4633b6c3722Schristos 		}
4643b6c3722Schristos 	}
4653b6c3722Schristos 	argc -= optind;
466f42d8de7Schristos 	/* argv += optind; not using further arguments */
4673b6c3722Schristos 	if(argc != 0) {
4683b6c3722Schristos 		testbound_usage();
469f42d8de7Schristos 		exit(1);
4703b6c3722Schristos 	}
4713b6c3722Schristos 	log_info("Start of %s testbound program.", PACKAGE_STRING);
4723b6c3722Schristos 	if(atexit(&remove_configfile) != 0)
4733b6c3722Schristos 		fatal_exit("atexit() failed: %s", strerror(errno));
4743b6c3722Schristos 
4753b6c3722Schristos 	/* setup test environment */
4763b6c3722Schristos 	scen = setup_playback(playback_file, &pass_argc, pass_argv);
4773b6c3722Schristos 	/* init fake event backend */
4783b6c3722Schristos 	fake_event_init(scen);
4793b6c3722Schristos 
4803b6c3722Schristos 	pass_argv[pass_argc] = NULL;
4813b6c3722Schristos 	echo_cmdline(pass_argc, pass_argv);
4823b6c3722Schristos 
4833b6c3722Schristos 	/* reset getopt processing */
4843b6c3722Schristos 	optind = init_optind;
4853b6c3722Schristos 	optarg = init_optarg;
4863b6c3722Schristos 
4873b6c3722Schristos 	/* run the normal daemon */
4883b6c3722Schristos 	res = daemon_main(pass_argc, pass_argv);
4893b6c3722Schristos 
4903b6c3722Schristos 	fake_event_cleanup();
4913b6c3722Schristos 	for(c=1; c<pass_argc; c++)
4923b6c3722Schristos 		free(pass_argv[c]);
4933b6c3722Schristos 	if(res == 0) {
4947cd94d69Schristos 		log_info("Testbound Exit Success\n");
49501049ae6Schristos 		/* remove configfile from here, the atexit() is for when
49601049ae6Schristos 		 * there is a crash to remove the tmpdir file.
49701049ae6Schristos 		 * This one removes the file while alloc and log locks are
49801049ae6Schristos 		 * still valid, and can be logged (for memory calculation),
49901049ae6Schristos 		 * it leaves the ptr NULL so the atexit does nothing. */
50001049ae6Schristos 		remove_configfile();
5017cd94d69Schristos 		if(log_get_lock()) {
50201049ae6Schristos 			lock_basic_destroy((lock_basic_type*)log_get_lock());
5037cd94d69Schristos 		}
5043b6c3722Schristos #ifdef HAVE_PTHREAD
5053b6c3722Schristos 		/* dlopen frees its thread state (dlopen of gost engine) */
5063b6c3722Schristos 		pthread_exit(NULL);
5073b6c3722Schristos #endif
5083b6c3722Schristos 	}
5093b6c3722Schristos 	return res;
5103b6c3722Schristos }
5113b6c3722Schristos 
5123b6c3722Schristos /* fake remote control */
daemon_remote_open_ports(struct config_file * ATTR_UNUSED (cfg))5133b6c3722Schristos struct listen_port* daemon_remote_open_ports(struct config_file*
5143b6c3722Schristos 	ATTR_UNUSED(cfg))
5153b6c3722Schristos {
5163b6c3722Schristos 	return NULL;
5173b6c3722Schristos }
5183b6c3722Schristos 
daemon_remote_create(struct config_file * ATTR_UNUSED (cfg))5193b6c3722Schristos struct daemon_remote* daemon_remote_create(struct config_file* ATTR_UNUSED(cfg))
5203b6c3722Schristos {
5213b6c3722Schristos 	return (struct daemon_remote*)calloc(1,1);
5223b6c3722Schristos }
5233b6c3722Schristos 
daemon_remote_delete(struct daemon_remote * rc)5243b6c3722Schristos void daemon_remote_delete(struct daemon_remote* rc)
5253b6c3722Schristos {
5263b6c3722Schristos 	free(rc);
5273b6c3722Schristos }
5283b6c3722Schristos 
daemon_remote_clear(struct daemon_remote * ATTR_UNUSED (rc))5293b6c3722Schristos void daemon_remote_clear(struct daemon_remote* ATTR_UNUSED(rc))
5303b6c3722Schristos {
5313b6c3722Schristos 	/* nothing */
5323b6c3722Schristos }
5333b6c3722Schristos 
daemon_remote_open_accept(struct daemon_remote * ATTR_UNUSED (rc),struct listen_port * ATTR_UNUSED (ports),struct worker * ATTR_UNUSED (worker))5343b6c3722Schristos int daemon_remote_open_accept(struct daemon_remote* ATTR_UNUSED(rc),
5353b6c3722Schristos         struct listen_port* ATTR_UNUSED(ports),
5363b6c3722Schristos 	struct worker* ATTR_UNUSED(worker))
5373b6c3722Schristos {
5383b6c3722Schristos 	return 1;
5393b6c3722Schristos }
5403b6c3722Schristos 
remote_accept_callback(struct comm_point * ATTR_UNUSED (c),void * ATTR_UNUSED (arg),int ATTR_UNUSED (error),struct comm_reply * ATTR_UNUSED (repinfo))5413b6c3722Schristos int remote_accept_callback(struct comm_point* ATTR_UNUSED(c),
5423b6c3722Schristos 	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
5433b6c3722Schristos         struct comm_reply* ATTR_UNUSED(repinfo))
5443b6c3722Schristos {
5453b6c3722Schristos 	log_assert(0);
5463b6c3722Schristos 	return 0;
5473b6c3722Schristos }
5483b6c3722Schristos 
remote_control_callback(struct comm_point * ATTR_UNUSED (c),void * ATTR_UNUSED (arg),int ATTR_UNUSED (error),struct comm_reply * ATTR_UNUSED (repinfo))5493b6c3722Schristos int remote_control_callback(struct comm_point* ATTR_UNUSED(c),
5503b6c3722Schristos 	void* ATTR_UNUSED(arg), int ATTR_UNUSED(error),
5513b6c3722Schristos         struct comm_reply* ATTR_UNUSED(repinfo))
5523b6c3722Schristos {
5533b6c3722Schristos 	log_assert(0);
5543b6c3722Schristos 	return 0;
5553b6c3722Schristos }
5563b6c3722Schristos 
remote_get_opt_ssl(char * ATTR_UNUSED (str),void * ATTR_UNUSED (arg))5573b6c3722Schristos void remote_get_opt_ssl(char* ATTR_UNUSED(str), void* ATTR_UNUSED(arg))
5583b6c3722Schristos {
5593b6c3722Schristos         log_assert(0);
5603b6c3722Schristos }
5613b6c3722Schristos 
562d0eba39bSchristos #ifdef UB_ON_WINDOWS
wsvc_command_option(const char * ATTR_UNUSED (wopt),const char * ATTR_UNUSED (cfgfile),int ATTR_UNUSED (v),int ATTR_UNUSED (c))5633b6c3722Schristos void wsvc_command_option(const char* ATTR_UNUSED(wopt),
5643b6c3722Schristos 	const char* ATTR_UNUSED(cfgfile), int ATTR_UNUSED(v),
5653b6c3722Schristos 	int ATTR_UNUSED(c))
5663b6c3722Schristos {
5673b6c3722Schristos 	log_assert(0);
5683b6c3722Schristos }
569d0eba39bSchristos #endif
5703b6c3722Schristos 
571d0eba39bSchristos #ifdef UB_ON_WINDOWS
wsvc_setup_worker(struct worker * ATTR_UNUSED (worker))5723b6c3722Schristos void wsvc_setup_worker(struct worker* ATTR_UNUSED(worker))
5733b6c3722Schristos {
5743b6c3722Schristos 	/* do nothing */
5753b6c3722Schristos }
576d0eba39bSchristos #endif
5773b6c3722Schristos 
578d0eba39bSchristos #ifdef UB_ON_WINDOWS
wsvc_desetup_worker(struct worker * ATTR_UNUSED (worker))5793b6c3722Schristos void wsvc_desetup_worker(struct worker* ATTR_UNUSED(worker))
5803b6c3722Schristos {
5813b6c3722Schristos 	/* do nothing */
5823b6c3722Schristos }
583d0eba39bSchristos #endif
5843b6c3722Schristos 
5853b6c3722Schristos #ifdef UB_ON_WINDOWS
worker_win_stop_cb(int ATTR_UNUSED (fd),short ATTR_UNUSED (ev),void * ATTR_UNUSED (arg))5863b6c3722Schristos void worker_win_stop_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev),
5873b6c3722Schristos 	void* ATTR_UNUSED(arg))
5883b6c3722Schristos {
5893b6c3722Schristos 	log_assert(0);
5903b6c3722Schristos }
5913b6c3722Schristos 
wsvc_cron_cb(void * ATTR_UNUSED (arg))5923b6c3722Schristos void wsvc_cron_cb(void* ATTR_UNUSED(arg))
5933b6c3722Schristos {
5943b6c3722Schristos 	log_assert(0);
5953b6c3722Schristos }
5963b6c3722Schristos #endif /* UB_ON_WINDOWS */
5973b6c3722Schristos 
tcp_connect_errno_needs_log(struct sockaddr * ATTR_UNUSED (addr),socklen_t ATTR_UNUSED (addrlen))598d0eba39bSchristos int tcp_connect_errno_needs_log(struct sockaddr* ATTR_UNUSED(addr),
599d0eba39bSchristos 	socklen_t ATTR_UNUSED(addrlen))
600d0eba39bSchristos {
601d0eba39bSchristos 	return 1;
602d0eba39bSchristos }
603d0eba39bSchristos 
squelch_err_ssl_handshake(unsigned long ATTR_UNUSED (err))604d0eba39bSchristos int squelch_err_ssl_handshake(unsigned long ATTR_UNUSED(err))
605d0eba39bSchristos {
606d0eba39bSchristos 	return 0;
607d0eba39bSchristos }
608*7a540f2bSchristos 
listen_setup_locks(void)609*7a540f2bSchristos void listen_setup_locks(void)
610*7a540f2bSchristos {
611*7a540f2bSchristos 	/* nothing */
612*7a540f2bSchristos }
613*7a540f2bSchristos 
listen_desetup_locks(void)614*7a540f2bSchristos void listen_desetup_locks(void)
615*7a540f2bSchristos {
616*7a540f2bSchristos 	/* nothing */
617*7a540f2bSchristos }
618