1*be771a7bSCy Schubert /* 2*be771a7bSCy Schubert * testcode/testbound.c - test program for unbound. 3*be771a7bSCy Schubert * 4*be771a7bSCy Schubert * Copyright (c) 2007, NLnet Labs. All rights reserved. 5*be771a7bSCy Schubert * 6*be771a7bSCy Schubert * This software is open source. 7*be771a7bSCy Schubert * 8*be771a7bSCy Schubert * Redistribution and use in source and binary forms, with or without 9*be771a7bSCy Schubert * modification, are permitted provided that the following conditions 10*be771a7bSCy Schubert * are met: 11*be771a7bSCy Schubert * 12*be771a7bSCy Schubert * Redistributions of source code must retain the above copyright notice, 13*be771a7bSCy Schubert * this list of conditions and the following disclaimer. 14*be771a7bSCy Schubert * 15*be771a7bSCy Schubert * Redistributions in binary form must reproduce the above copyright notice, 16*be771a7bSCy Schubert * this list of conditions and the following disclaimer in the documentation 17*be771a7bSCy Schubert * and/or other materials provided with the distribution. 18*be771a7bSCy Schubert * 19*be771a7bSCy Schubert * Neither the name of the NLNET LABS nor the names of its contributors may 20*be771a7bSCy Schubert * be used to endorse or promote products derived from this software without 21*be771a7bSCy Schubert * specific prior written permission. 22*be771a7bSCy Schubert * 23*be771a7bSCy Schubert * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24*be771a7bSCy Schubert * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25*be771a7bSCy Schubert * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 26*be771a7bSCy Schubert * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 27*be771a7bSCy Schubert * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 28*be771a7bSCy Schubert * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 29*be771a7bSCy Schubert * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 30*be771a7bSCy Schubert * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 31*be771a7bSCy Schubert * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 32*be771a7bSCy Schubert * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33*be771a7bSCy Schubert * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34*be771a7bSCy Schubert * 35*be771a7bSCy Schubert */ 36*be771a7bSCy Schubert /** 37*be771a7bSCy Schubert * \file 38*be771a7bSCy Schubert * Exits with code 1 on a failure. 0 if all unit tests are successful. 39*be771a7bSCy Schubert */ 40*be771a7bSCy Schubert 41*be771a7bSCy Schubert #include "config.h" 42*be771a7bSCy Schubert #ifdef HAVE_TIME_H 43*be771a7bSCy Schubert # include <time.h> 44*be771a7bSCy Schubert #endif 45*be771a7bSCy Schubert #include <ctype.h> 46*be771a7bSCy Schubert #include "testcode/testpkts.h" 47*be771a7bSCy Schubert #include "testcode/replay.h" 48*be771a7bSCy Schubert #include "testcode/fake_event.h" 49*be771a7bSCy Schubert #include "daemon/remote.h" 50*be771a7bSCy Schubert #include "libunbound/worker.h" 51*be771a7bSCy Schubert #include "daemon/worker.h" 52*be771a7bSCy Schubert #include "util/config_file.h" 53*be771a7bSCy Schubert #include "sldns/keyraw.h" 54*be771a7bSCy Schubert #ifdef UB_ON_WINDOWS 55*be771a7bSCy Schubert #include "winrc/win_svc.h" 56*be771a7bSCy Schubert #endif 57*be771a7bSCy Schubert 58*be771a7bSCy Schubert /** signal that this is a testbound compile */ 59*be771a7bSCy Schubert #define unbound_testbound 1 60*be771a7bSCy Schubert /** renamed main routine */ 61*be771a7bSCy Schubert int daemon_main(int argc, char* argv[]); 62*be771a7bSCy Schubert /** 63*be771a7bSCy Schubert * include the main program from the unbound daemon. 64*be771a7bSCy Schubert * rename main to daemon_main to call it 65*be771a7bSCy Schubert */ 66*be771a7bSCy Schubert #define main daemon_main 67*be771a7bSCy Schubert #include "daemon/unbound.c" 68*be771a7bSCy Schubert #undef main 69*be771a7bSCy Schubert 70*be771a7bSCy Schubert /** maximum line length for lines in the replay file. */ 71*be771a7bSCy Schubert #define MAX_LINE_LEN 1024 72*be771a7bSCy Schubert /** config files (removed at exit) */ 73*be771a7bSCy Schubert static struct config_strlist* cfgfiles = NULL; 74*be771a7bSCy Schubert 75*be771a7bSCy Schubert /** give commandline usage for testbound. */ 76*be771a7bSCy Schubert static void 77*be771a7bSCy Schubert testbound_usage(void) 78*be771a7bSCy Schubert { 79*be771a7bSCy Schubert printf("usage: testbound [options]\n"); 80*be771a7bSCy Schubert printf("\ttest the unbound daemon.\n"); 81*be771a7bSCy Schubert printf("-h this help\n"); 82*be771a7bSCy Schubert printf("-p file playback text file\n"); 83*be771a7bSCy Schubert printf("-1 detect SHA1 support (exit code 0 or 1)\n"); 84*be771a7bSCy Schubert printf("-2 detect SHA256 support (exit code 0 or 1)\n"); 85*be771a7bSCy Schubert printf("-g detect GOST support (exit code 0 or 1)\n"); 86*be771a7bSCy Schubert printf("-e detect ECDSA support (exit code 0 or 1)\n"); 87*be771a7bSCy Schubert printf("-c detect CLIENT_SUBNET support (exit code 0 or 1)\n"); 88*be771a7bSCy Schubert printf("-i detect IPSECMOD support (exit code 0 or 1)\n"); 89*be771a7bSCy Schubert printf("-s testbound self-test - unit test of testbound parts.\n"); 90*be771a7bSCy Schubert printf("-o str unbound commandline options separated by spaces.\n"); 91*be771a7bSCy Schubert printf("Version %s\n", PACKAGE_VERSION); 92*be771a7bSCy Schubert printf("BSD licensed, see LICENSE file in source package.\n"); 93*be771a7bSCy Schubert printf("Report bugs to %s.\n", PACKAGE_BUGREPORT); 94*be771a7bSCy Schubert } 95*be771a7bSCy Schubert 96*be771a7bSCy Schubert /** Max number of arguments to pass to unbound. */ 97*be771a7bSCy Schubert #define MAXARG 100 98*be771a7bSCy Schubert 99*be771a7bSCy Schubert /** 100*be771a7bSCy Schubert * Add options from string to passed argc. splits on whitespace. 101*be771a7bSCy Schubert * @param args: the option argument, "-v -p 12345" or so. 102*be771a7bSCy Schubert * @param pass_argc: ptr to the argc for unbound. Modified. 103*be771a7bSCy Schubert * @param pass_argv: the argv to pass to unbound. Modified. 104*be771a7bSCy Schubert */ 105*be771a7bSCy Schubert static void 106*be771a7bSCy Schubert add_opts(const char* args, int* pass_argc, char* pass_argv[]) 107*be771a7bSCy Schubert { 108*be771a7bSCy Schubert const char *p = args, *np; 109*be771a7bSCy Schubert size_t len; 110*be771a7bSCy Schubert while(p && isspace((unsigned char)*p)) 111*be771a7bSCy Schubert p++; 112*be771a7bSCy Schubert while(p && *p) { 113*be771a7bSCy Schubert /* find location of next string and length of this one */ 114*be771a7bSCy Schubert if((np = strchr(p, ' '))) 115*be771a7bSCy Schubert len = (size_t)(np-p); 116*be771a7bSCy Schubert else len = strlen(p); 117*be771a7bSCy Schubert /* allocate and copy option */ 118*be771a7bSCy Schubert if(*pass_argc >= MAXARG-1) 119*be771a7bSCy Schubert fatal_exit("too many arguments: '%s'", p); 120*be771a7bSCy Schubert pass_argv[*pass_argc] = (char*)malloc(len+1); 121*be771a7bSCy Schubert if(!pass_argv[*pass_argc]) 122*be771a7bSCy Schubert fatal_exit("add_opts: out of memory"); 123*be771a7bSCy Schubert memcpy(pass_argv[*pass_argc], p, len); 124*be771a7bSCy Schubert pass_argv[*pass_argc][len] = 0; 125*be771a7bSCy Schubert (*pass_argc)++; 126*be771a7bSCy Schubert /* go to next option */ 127*be771a7bSCy Schubert p = np; 128*be771a7bSCy Schubert while(p && isspace((unsigned char)*p)) 129*be771a7bSCy Schubert p++; 130*be771a7bSCy Schubert } 131*be771a7bSCy Schubert } 132*be771a7bSCy Schubert 133*be771a7bSCy Schubert /** pretty print commandline for unbound in this test */ 134*be771a7bSCy Schubert static void 135*be771a7bSCy Schubert echo_cmdline(int argc, char* argv[]) 136*be771a7bSCy Schubert { 137*be771a7bSCy Schubert int i; 138*be771a7bSCy Schubert fprintf(stderr, "testbound is starting:"); 139*be771a7bSCy Schubert for(i=0; i<argc; i++) { 140*be771a7bSCy Schubert fprintf(stderr, " [%s]", argv[i]); 141*be771a7bSCy Schubert } 142*be771a7bSCy Schubert fprintf(stderr, "\n"); 143*be771a7bSCy Schubert } 144*be771a7bSCy Schubert 145*be771a7bSCy Schubert /** spool temp file name */ 146*be771a7bSCy Schubert static void 147*be771a7bSCy Schubert spool_temp_file_name(int* lineno, FILE* cfg, char* id) 148*be771a7bSCy Schubert { 149*be771a7bSCy Schubert char line[MAX_LINE_LEN]; 150*be771a7bSCy Schubert /* find filename for new file */ 151*be771a7bSCy Schubert while(isspace((unsigned char)*id)) 152*be771a7bSCy Schubert id++; 153*be771a7bSCy Schubert if(*id == '\0') 154*be771a7bSCy Schubert fatal_exit("TEMPFILE_NAME must have id, line %d", *lineno); 155*be771a7bSCy Schubert strip_end_white(id); 156*be771a7bSCy Schubert fake_temp_file("_temp_", id, line, sizeof(line)); 157*be771a7bSCy Schubert fprintf(cfg, "\"%s\"\n", line); 158*be771a7bSCy Schubert } 159*be771a7bSCy Schubert 160*be771a7bSCy Schubert /** spool temp file */ 161*be771a7bSCy Schubert static void 162*be771a7bSCy Schubert spool_temp_file(FILE* in, int* lineno, char* id) 163*be771a7bSCy Schubert { 164*be771a7bSCy Schubert char line[MAX_LINE_LEN]; 165*be771a7bSCy Schubert char* parse; 166*be771a7bSCy Schubert FILE* spool; 167*be771a7bSCy Schubert /* find filename for new file */ 168*be771a7bSCy Schubert while(isspace((unsigned char)*id)) 169*be771a7bSCy Schubert id++; 170*be771a7bSCy Schubert if(*id == '\0') 171*be771a7bSCy Schubert fatal_exit("TEMPFILE_CONTENTS must have id, line %d", *lineno); 172*be771a7bSCy Schubert strip_end_white(id); 173*be771a7bSCy Schubert fake_temp_file("_temp_", id, line, sizeof(line)); 174*be771a7bSCy Schubert /* open file and spool to it */ 175*be771a7bSCy Schubert spool = fopen(line, "w"); 176*be771a7bSCy Schubert if(!spool) fatal_exit("could not open %s: %s", line, strerror(errno)); 177*be771a7bSCy Schubert fprintf(stderr, "testbound is spooling temp file: %s\n", line); 178*be771a7bSCy Schubert if(!cfg_strlist_insert(&cfgfiles, strdup(line))) 179*be771a7bSCy Schubert fatal_exit("out of memory"); 180*be771a7bSCy Schubert line[sizeof(line)-1] = 0; 181*be771a7bSCy Schubert while(fgets(line, MAX_LINE_LEN-1, in)) { 182*be771a7bSCy Schubert parse = line; 183*be771a7bSCy Schubert (*lineno)++; 184*be771a7bSCy Schubert while(isspace((unsigned char)*parse)) 185*be771a7bSCy Schubert parse++; 186*be771a7bSCy Schubert if(strncmp(parse, "$INCLUDE_TEMPFILE", 17) == 0) { 187*be771a7bSCy Schubert char l2[MAX_LINE_LEN-30]; /* -30 makes it fit with 188*be771a7bSCy Schubert a preceding $INCLUDE in the buf line[] */ 189*be771a7bSCy Schubert char* tid = parse+17; 190*be771a7bSCy Schubert while(isspace((unsigned char)*tid)) 191*be771a7bSCy Schubert tid++; 192*be771a7bSCy Schubert strip_end_white(tid); 193*be771a7bSCy Schubert fake_temp_file("_temp_", tid, l2, sizeof(l2)); 194*be771a7bSCy Schubert snprintf(line, sizeof(line), "$INCLUDE %s\n", l2); 195*be771a7bSCy Schubert } 196*be771a7bSCy Schubert if(strncmp(parse, "TEMPFILE_END", 12) == 0) { 197*be771a7bSCy Schubert fclose(spool); 198*be771a7bSCy Schubert return; 199*be771a7bSCy Schubert } 200*be771a7bSCy Schubert fputs(line, spool); 201*be771a7bSCy Schubert } 202*be771a7bSCy Schubert fatal_exit("no TEMPFILE_END in input file"); 203*be771a7bSCy Schubert } 204*be771a7bSCy Schubert 205*be771a7bSCy Schubert /** spool autotrust file */ 206*be771a7bSCy Schubert static void 207*be771a7bSCy Schubert spool_auto_file(FILE* in, int* lineno, FILE* cfg, char* id) 208*be771a7bSCy Schubert { 209*be771a7bSCy Schubert char line[MAX_LINE_LEN]; 210*be771a7bSCy Schubert char* parse; 211*be771a7bSCy Schubert FILE* spool; 212*be771a7bSCy Schubert /* find filename for new file */ 213*be771a7bSCy Schubert while(isspace((unsigned char)*id)) 214*be771a7bSCy Schubert id++; 215*be771a7bSCy Schubert if(*id == '\0') 216*be771a7bSCy Schubert fatal_exit("AUTROTRUST_FILE must have id, line %d", *lineno); 217*be771a7bSCy Schubert strip_end_white(id); 218*be771a7bSCy Schubert fake_temp_file("_auto_", id, line, sizeof(line)); 219*be771a7bSCy Schubert /* add option for the file */ 220*be771a7bSCy Schubert fprintf(cfg, "server: auto-trust-anchor-file: \"%s\"\n", line); 221*be771a7bSCy Schubert /* open file and spool to it */ 222*be771a7bSCy Schubert spool = fopen(line, "w"); 223*be771a7bSCy Schubert if(!spool) fatal_exit("could not open %s: %s", line, strerror(errno)); 224*be771a7bSCy Schubert fprintf(stderr, "testbound is spooling key file: %s\n", line); 225*be771a7bSCy Schubert if(!cfg_strlist_insert(&cfgfiles, strdup(line))) 226*be771a7bSCy Schubert fatal_exit("out of memory"); 227*be771a7bSCy Schubert line[sizeof(line)-1] = 0; 228*be771a7bSCy Schubert while(fgets(line, MAX_LINE_LEN-1, in)) { 229*be771a7bSCy Schubert parse = line; 230*be771a7bSCy Schubert (*lineno)++; 231*be771a7bSCy Schubert while(isspace((unsigned char)*parse)) 232*be771a7bSCy Schubert parse++; 233*be771a7bSCy Schubert if(strncmp(parse, "AUTOTRUST_END", 13) == 0) { 234*be771a7bSCy Schubert fclose(spool); 235*be771a7bSCy Schubert return; 236*be771a7bSCy Schubert } 237*be771a7bSCy Schubert fputs(line, spool); 238*be771a7bSCy Schubert } 239*be771a7bSCy Schubert fatal_exit("no AUTOTRUST_END in input file"); 240*be771a7bSCy Schubert } 241*be771a7bSCy Schubert 242*be771a7bSCy Schubert /** process config elements */ 243*be771a7bSCy Schubert static void 244*be771a7bSCy Schubert setup_config(FILE* in, int* lineno, int* pass_argc, char* pass_argv[]) 245*be771a7bSCy Schubert { 246*be771a7bSCy Schubert char configfile[MAX_LINE_LEN]; 247*be771a7bSCy Schubert char line[MAX_LINE_LEN]; 248*be771a7bSCy Schubert char* parse; 249*be771a7bSCy Schubert FILE* cfg; 250*be771a7bSCy Schubert fake_temp_file("_cfg", "", configfile, sizeof(configfile)); 251*be771a7bSCy Schubert add_opts("-c", pass_argc, pass_argv); 252*be771a7bSCy Schubert add_opts(configfile, pass_argc, pass_argv); 253*be771a7bSCy Schubert cfg = fopen(configfile, "w"); 254*be771a7bSCy Schubert if(!cfg) fatal_exit("could not open %s: %s", 255*be771a7bSCy Schubert configfile, strerror(errno)); 256*be771a7bSCy Schubert if(!cfg_strlist_insert(&cfgfiles, strdup(configfile))) 257*be771a7bSCy Schubert fatal_exit("out of memory"); 258*be771a7bSCy Schubert line[sizeof(line)-1] = 0; 259*be771a7bSCy Schubert /* some basic settings to not pollute the host system */ 260*be771a7bSCy Schubert fprintf(cfg, "server: use-syslog: no\n"); 261*be771a7bSCy Schubert fprintf(cfg, " directory: \"\"\n"); 262*be771a7bSCy Schubert fprintf(cfg, " chroot: \"\"\n"); 263*be771a7bSCy Schubert fprintf(cfg, " username: \"\"\n"); 264*be771a7bSCy Schubert fprintf(cfg, " pidfile: \"\"\n"); 265*be771a7bSCy Schubert fprintf(cfg, " val-log-level: 2\n"); 266*be771a7bSCy Schubert fprintf(cfg, " log-servfail: yes\n"); 267*be771a7bSCy Schubert fprintf(cfg, "remote-control: control-enable: no\n"); 268*be771a7bSCy Schubert while(fgets(line, MAX_LINE_LEN-1, in)) { 269*be771a7bSCy Schubert parse = line; 270*be771a7bSCy Schubert (*lineno)++; 271*be771a7bSCy Schubert while(isspace((unsigned char)*parse)) 272*be771a7bSCy Schubert parse++; 273*be771a7bSCy Schubert if(!*parse || parse[0] == ';') 274*be771a7bSCy Schubert continue; 275*be771a7bSCy Schubert if(strncmp(parse, "COMMANDLINE", 11) == 0) { 276*be771a7bSCy Schubert parse[strlen(parse)-1] = 0; /* strip off \n */ 277*be771a7bSCy Schubert add_opts(parse+11, pass_argc, pass_argv); 278*be771a7bSCy Schubert continue; 279*be771a7bSCy Schubert } 280*be771a7bSCy Schubert if(strncmp(parse, "AUTOTRUST_FILE", 14) == 0) { 281*be771a7bSCy Schubert spool_auto_file(in, lineno, cfg, parse+14); 282*be771a7bSCy Schubert continue; 283*be771a7bSCy Schubert } 284*be771a7bSCy Schubert if(strncmp(parse, "TEMPFILE_NAME", 13) == 0) { 285*be771a7bSCy Schubert spool_temp_file_name(lineno, cfg, parse+13); 286*be771a7bSCy Schubert continue; 287*be771a7bSCy Schubert } 288*be771a7bSCy Schubert if(strncmp(parse, "TEMPFILE_CONTENTS", 17) == 0) { 289*be771a7bSCy Schubert spool_temp_file(in, lineno, parse+17); 290*be771a7bSCy Schubert continue; 291*be771a7bSCy Schubert } 292*be771a7bSCy Schubert if(strncmp(parse, "CONFIG_END", 10) == 0) { 293*be771a7bSCy Schubert fclose(cfg); 294*be771a7bSCy Schubert return; 295*be771a7bSCy Schubert } 296*be771a7bSCy Schubert fputs(line, cfg); 297*be771a7bSCy Schubert } 298*be771a7bSCy Schubert fatal_exit("No CONFIG_END in input file"); 299*be771a7bSCy Schubert 300*be771a7bSCy Schubert } 301*be771a7bSCy Schubert 302*be771a7bSCy Schubert /** read playback file */ 303*be771a7bSCy Schubert static struct replay_scenario* 304*be771a7bSCy Schubert setup_playback(const char* filename, int* pass_argc, char* pass_argv[]) 305*be771a7bSCy Schubert { 306*be771a7bSCy Schubert struct replay_scenario* scen = NULL; 307*be771a7bSCy Schubert int lineno = 0; 308*be771a7bSCy Schubert 309*be771a7bSCy Schubert if(filename) { 310*be771a7bSCy Schubert FILE *in = fopen(filename, "rb"); 311*be771a7bSCy Schubert if(!in) { 312*be771a7bSCy Schubert perror(filename); 313*be771a7bSCy Schubert exit(1); 314*be771a7bSCy Schubert } 315*be771a7bSCy Schubert setup_config(in, &lineno, pass_argc, pass_argv); 316*be771a7bSCy Schubert scen = replay_scenario_read(in, filename, &lineno); 317*be771a7bSCy Schubert fclose(in); 318*be771a7bSCy Schubert if(!scen) 319*be771a7bSCy Schubert fatal_exit("Could not read: %s", filename); 320*be771a7bSCy Schubert } 321*be771a7bSCy Schubert else fatal_exit("need a playback file (-p)"); 322*be771a7bSCy Schubert log_info("Scenario: %s", scen->title); 323*be771a7bSCy Schubert return scen; 324*be771a7bSCy Schubert } 325*be771a7bSCy Schubert 326*be771a7bSCy Schubert /** remove config file at exit */ 327*be771a7bSCy Schubert static void remove_configfile(void) 328*be771a7bSCy Schubert { 329*be771a7bSCy Schubert struct config_strlist* p; 330*be771a7bSCy Schubert for(p=cfgfiles; p; p=p->next) 331*be771a7bSCy Schubert unlink(p->str); 332*be771a7bSCy Schubert config_delstrlist(cfgfiles); 333*be771a7bSCy Schubert cfgfiles = NULL; 334*be771a7bSCy Schubert } 335*be771a7bSCy Schubert 336*be771a7bSCy Schubert /** 337*be771a7bSCy Schubert * Main fake event test program. Setup, teardown and report errors. 338*be771a7bSCy Schubert * @param argc: arg count. 339*be771a7bSCy Schubert * @param argv: array of commandline arguments. 340*be771a7bSCy Schubert * @return program failure if test fails. 341*be771a7bSCy Schubert */ 342*be771a7bSCy Schubert int 343*be771a7bSCy Schubert main(int argc, char* argv[]) 344*be771a7bSCy Schubert { 345*be771a7bSCy Schubert int c, res; 346*be771a7bSCy Schubert int pass_argc = 0; 347*be771a7bSCy Schubert char* pass_argv[MAXARG]; 348*be771a7bSCy Schubert char* playback_file = NULL; 349*be771a7bSCy Schubert int init_optind = optind; 350*be771a7bSCy Schubert char* init_optarg = optarg; 351*be771a7bSCy Schubert struct replay_scenario* scen = NULL; 352*be771a7bSCy Schubert 353*be771a7bSCy Schubert /* we do not want the test to depend on the timezone */ 354*be771a7bSCy Schubert (void)putenv("TZ=UTC"); 355*be771a7bSCy Schubert memset(pass_argv, 0, sizeof(pass_argv)); 356*be771a7bSCy Schubert #ifdef HAVE_SYSTEMD 357*be771a7bSCy Schubert /* we do not want the test to use systemd daemon startup notification*/ 358*be771a7bSCy Schubert (void)unsetenv("NOTIFY_SOCKET"); 359*be771a7bSCy Schubert #endif /* HAVE_SYSTEMD */ 360*be771a7bSCy Schubert 361*be771a7bSCy Schubert checklock_start(); 362*be771a7bSCy Schubert log_init(NULL, 0, NULL); 363*be771a7bSCy Schubert /* determine commandline options for the daemon */ 364*be771a7bSCy Schubert pass_argc = 1; 365*be771a7bSCy Schubert pass_argv[0] = "unbound"; 366*be771a7bSCy Schubert add_opts("-d", &pass_argc, pass_argv); 367*be771a7bSCy Schubert while( (c=getopt(argc, argv, "12egciho:p:s")) != -1) { 368*be771a7bSCy Schubert switch(c) { 369*be771a7bSCy Schubert case 's': 370*be771a7bSCy Schubert free(pass_argv[1]); 371*be771a7bSCy Schubert testbound_selftest(); 372*be771a7bSCy Schubert checklock_stop(); 373*be771a7bSCy Schubert if(log_get_lock()) { 374*be771a7bSCy Schubert lock_basic_destroy((lock_basic_type*)log_get_lock()); 375*be771a7bSCy Schubert } 376*be771a7bSCy Schubert exit(0); 377*be771a7bSCy Schubert case '1': 378*be771a7bSCy Schubert #ifdef USE_SHA1 379*be771a7bSCy Schubert printf("SHA1 supported\n"); 380*be771a7bSCy Schubert exit(0); 381*be771a7bSCy Schubert #else 382*be771a7bSCy Schubert printf("SHA1 not supported\n"); 383*be771a7bSCy Schubert exit(1); 384*be771a7bSCy Schubert #endif 385*be771a7bSCy Schubert break; 386*be771a7bSCy Schubert case '2': 387*be771a7bSCy Schubert #if (defined(HAVE_EVP_SHA256) || defined(HAVE_NSS) || defined(HAVE_NETTLE)) && defined(USE_SHA2) 388*be771a7bSCy Schubert printf("SHA256 supported\n"); 389*be771a7bSCy Schubert exit(0); 390*be771a7bSCy Schubert #else 391*be771a7bSCy Schubert printf("SHA256 not supported\n"); 392*be771a7bSCy Schubert exit(1); 393*be771a7bSCy Schubert #endif 394*be771a7bSCy Schubert break; 395*be771a7bSCy Schubert case 'e': 396*be771a7bSCy Schubert #if defined(USE_ECDSA) 397*be771a7bSCy Schubert printf("ECDSA supported\n"); 398*be771a7bSCy Schubert exit(0); 399*be771a7bSCy Schubert #else 400*be771a7bSCy Schubert printf("ECDSA not supported\n"); 401*be771a7bSCy Schubert exit(1); 402*be771a7bSCy Schubert #endif 403*be771a7bSCy Schubert break; 404*be771a7bSCy Schubert case 'g': 405*be771a7bSCy Schubert #ifdef USE_GOST 406*be771a7bSCy Schubert if(sldns_key_EVP_load_gost_id()) { 407*be771a7bSCy Schubert printf("GOST supported\n"); 408*be771a7bSCy Schubert exit(0); 409*be771a7bSCy Schubert } else { 410*be771a7bSCy Schubert printf("GOST not supported\n"); 411*be771a7bSCy Schubert exit(1); 412*be771a7bSCy Schubert } 413*be771a7bSCy Schubert #else 414*be771a7bSCy Schubert printf("GOST not supported\n"); 415*be771a7bSCy Schubert exit(1); 416*be771a7bSCy Schubert #endif 417*be771a7bSCy Schubert break; 418*be771a7bSCy Schubert case 'c': 419*be771a7bSCy Schubert #ifdef CLIENT_SUBNET 420*be771a7bSCy Schubert printf("CLIENT_SUBNET supported\n"); 421*be771a7bSCy Schubert exit(0); 422*be771a7bSCy Schubert #else 423*be771a7bSCy Schubert printf("CLIENT_SUBNET not supported\n"); 424*be771a7bSCy Schubert exit(1); 425*be771a7bSCy Schubert #endif 426*be771a7bSCy Schubert break; 427*be771a7bSCy Schubert case 'i': 428*be771a7bSCy Schubert #ifdef USE_IPSECMOD 429*be771a7bSCy Schubert printf("IPSECMOD supported\n"); 430*be771a7bSCy Schubert exit(0); 431*be771a7bSCy Schubert #else 432*be771a7bSCy Schubert printf("IPSECMOD not supported\n"); 433*be771a7bSCy Schubert exit(1); 434*be771a7bSCy Schubert #endif 435*be771a7bSCy Schubert break; 436*be771a7bSCy Schubert case 'p': 437*be771a7bSCy Schubert playback_file = optarg; 438*be771a7bSCy Schubert break; 439*be771a7bSCy Schubert case 'o': 440*be771a7bSCy Schubert add_opts(optarg, &pass_argc, pass_argv); 441*be771a7bSCy Schubert break; 442*be771a7bSCy Schubert case '?': 443*be771a7bSCy Schubert case 'h': 444*be771a7bSCy Schubert default: 445*be771a7bSCy Schubert testbound_usage(); 446*be771a7bSCy Schubert exit(1); 447*be771a7bSCy Schubert } 448*be771a7bSCy Schubert } 449*be771a7bSCy Schubert argc -= optind; 450*be771a7bSCy Schubert /* argv += optind; not using further arguments */ 451*be771a7bSCy Schubert if(argc != 0) { 452*be771a7bSCy Schubert testbound_usage(); 453*be771a7bSCy Schubert exit(1); 454*be771a7bSCy Schubert } 455*be771a7bSCy Schubert log_info("Start of %s testbound program.", PACKAGE_STRING); 456*be771a7bSCy Schubert if(atexit(&remove_configfile) != 0) 457*be771a7bSCy Schubert fatal_exit("atexit() failed: %s", strerror(errno)); 458*be771a7bSCy Schubert 459*be771a7bSCy Schubert /* setup test environment */ 460*be771a7bSCy Schubert scen = setup_playback(playback_file, &pass_argc, pass_argv); 461*be771a7bSCy Schubert /* init fake event backend */ 462*be771a7bSCy Schubert fake_event_init(scen); 463*be771a7bSCy Schubert 464*be771a7bSCy Schubert pass_argv[pass_argc] = NULL; 465*be771a7bSCy Schubert echo_cmdline(pass_argc, pass_argv); 466*be771a7bSCy Schubert 467*be771a7bSCy Schubert /* reset getopt processing */ 468*be771a7bSCy Schubert optind = init_optind; 469*be771a7bSCy Schubert optarg = init_optarg; 470*be771a7bSCy Schubert 471*be771a7bSCy Schubert /* run the normal daemon */ 472*be771a7bSCy Schubert res = daemon_main(pass_argc, pass_argv); 473*be771a7bSCy Schubert 474*be771a7bSCy Schubert fake_event_cleanup(); 475*be771a7bSCy Schubert for(c=1; c<pass_argc; c++) 476*be771a7bSCy Schubert free(pass_argv[c]); 477*be771a7bSCy Schubert if(res == 0) { 478*be771a7bSCy Schubert log_info("Testbound Exit Success\n"); 479*be771a7bSCy Schubert /* remove configfile from here, the atexit() is for when 480*be771a7bSCy Schubert * there is a crash to remove the tmpdir file. 481*be771a7bSCy Schubert * This one removes the file while alloc and log locks are 482*be771a7bSCy Schubert * still valid, and can be logged (for memory calculation), 483*be771a7bSCy Schubert * it leaves the ptr NULL so the atexit does nothing. */ 484*be771a7bSCy Schubert remove_configfile(); 485*be771a7bSCy Schubert if(log_get_lock()) { 486*be771a7bSCy Schubert lock_basic_destroy((lock_basic_type*)log_get_lock()); 487*be771a7bSCy Schubert } 488*be771a7bSCy Schubert #ifdef HAVE_PTHREAD 489*be771a7bSCy Schubert /* dlopen frees its thread state (dlopen of gost engine) */ 490*be771a7bSCy Schubert pthread_exit(NULL); 491*be771a7bSCy Schubert #endif 492*be771a7bSCy Schubert } 493*be771a7bSCy Schubert return res; 494*be771a7bSCy Schubert } 495*be771a7bSCy Schubert 496*be771a7bSCy Schubert /* fake remote control */ 497*be771a7bSCy Schubert struct listen_port* daemon_remote_open_ports(struct config_file* 498*be771a7bSCy Schubert ATTR_UNUSED(cfg)) 499*be771a7bSCy Schubert { 500*be771a7bSCy Schubert return NULL; 501*be771a7bSCy Schubert } 502*be771a7bSCy Schubert 503*be771a7bSCy Schubert struct daemon_remote* daemon_remote_create(struct config_file* ATTR_UNUSED(cfg)) 504*be771a7bSCy Schubert { 505*be771a7bSCy Schubert return (struct daemon_remote*)calloc(1, sizeof(struct daemon_remote)); 506*be771a7bSCy Schubert } 507*be771a7bSCy Schubert 508*be771a7bSCy Schubert void daemon_remote_delete(struct daemon_remote* rc) 509*be771a7bSCy Schubert { 510*be771a7bSCy Schubert free(rc); 511*be771a7bSCy Schubert } 512*be771a7bSCy Schubert 513*be771a7bSCy Schubert void daemon_remote_clear(struct daemon_remote* ATTR_UNUSED(rc)) 514*be771a7bSCy Schubert { 515*be771a7bSCy Schubert /* nothing */ 516*be771a7bSCy Schubert } 517*be771a7bSCy Schubert 518*be771a7bSCy Schubert int daemon_remote_open_accept(struct daemon_remote* ATTR_UNUSED(rc), 519*be771a7bSCy Schubert struct listen_port* ATTR_UNUSED(ports), struct worker* worker) 520*be771a7bSCy Schubert { 521*be771a7bSCy Schubert struct replay_runtime* runtime = (struct replay_runtime*)worker->base; 522*be771a7bSCy Schubert runtime->daemon = worker->daemon; 523*be771a7bSCy Schubert return 1; 524*be771a7bSCy Schubert } 525*be771a7bSCy Schubert 526*be771a7bSCy Schubert int remote_accept_callback(struct comm_point* ATTR_UNUSED(c), 527*be771a7bSCy Schubert void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), 528*be771a7bSCy Schubert struct comm_reply* ATTR_UNUSED(repinfo)) 529*be771a7bSCy Schubert { 530*be771a7bSCy Schubert log_assert(0); 531*be771a7bSCy Schubert return 0; 532*be771a7bSCy Schubert } 533*be771a7bSCy Schubert 534*be771a7bSCy Schubert int remote_control_callback(struct comm_point* ATTR_UNUSED(c), 535*be771a7bSCy Schubert void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), 536*be771a7bSCy Schubert struct comm_reply* ATTR_UNUSED(repinfo)) 537*be771a7bSCy Schubert { 538*be771a7bSCy Schubert log_assert(0); 539*be771a7bSCy Schubert return 0; 540*be771a7bSCy Schubert } 541*be771a7bSCy Schubert 542*be771a7bSCy Schubert void remote_get_opt_ssl(char* ATTR_UNUSED(str), void* ATTR_UNUSED(arg)) 543*be771a7bSCy Schubert { 544*be771a7bSCy Schubert log_assert(0); 545*be771a7bSCy Schubert } 546*be771a7bSCy Schubert 547*be771a7bSCy Schubert #ifdef UB_ON_WINDOWS 548*be771a7bSCy Schubert void wsvc_command_option(const char* ATTR_UNUSED(wopt), 549*be771a7bSCy Schubert const char* ATTR_UNUSED(cfgfile), int ATTR_UNUSED(v), 550*be771a7bSCy Schubert int ATTR_UNUSED(c)) 551*be771a7bSCy Schubert { 552*be771a7bSCy Schubert log_assert(0); 553*be771a7bSCy Schubert } 554*be771a7bSCy Schubert #endif 555*be771a7bSCy Schubert 556*be771a7bSCy Schubert #ifdef UB_ON_WINDOWS 557*be771a7bSCy Schubert void wsvc_setup_worker(struct worker* ATTR_UNUSED(worker)) 558*be771a7bSCy Schubert { 559*be771a7bSCy Schubert /* do nothing */ 560*be771a7bSCy Schubert } 561*be771a7bSCy Schubert #endif 562*be771a7bSCy Schubert 563*be771a7bSCy Schubert #ifdef UB_ON_WINDOWS 564*be771a7bSCy Schubert void wsvc_desetup_worker(struct worker* ATTR_UNUSED(worker)) 565*be771a7bSCy Schubert { 566*be771a7bSCy Schubert /* do nothing */ 567*be771a7bSCy Schubert } 568*be771a7bSCy Schubert #endif 569*be771a7bSCy Schubert 570*be771a7bSCy Schubert #ifdef UB_ON_WINDOWS 571*be771a7bSCy Schubert void worker_win_stop_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), 572*be771a7bSCy Schubert void* ATTR_UNUSED(arg)) 573*be771a7bSCy Schubert { 574*be771a7bSCy Schubert log_assert(0); 575*be771a7bSCy Schubert } 576*be771a7bSCy Schubert 577*be771a7bSCy Schubert void wsvc_cron_cb(void* ATTR_UNUSED(arg)) 578*be771a7bSCy Schubert { 579*be771a7bSCy Schubert log_assert(0); 580*be771a7bSCy Schubert } 581*be771a7bSCy Schubert #endif /* UB_ON_WINDOWS */ 582*be771a7bSCy Schubert 583*be771a7bSCy Schubert int tcp_connect_errno_needs_log(struct sockaddr* ATTR_UNUSED(addr), 584*be771a7bSCy Schubert socklen_t ATTR_UNUSED(addrlen)) 585*be771a7bSCy Schubert { 586*be771a7bSCy Schubert return 1; 587*be771a7bSCy Schubert } 588*be771a7bSCy Schubert 589*be771a7bSCy Schubert int squelch_err_ssl_handshake(unsigned long ATTR_UNUSED(err)) 590*be771a7bSCy Schubert { 591*be771a7bSCy Schubert return 0; 592*be771a7bSCy Schubert } 593*be771a7bSCy Schubert 594*be771a7bSCy Schubert void listen_setup_locks(void) 595*be771a7bSCy Schubert { 596*be771a7bSCy Schubert /* nothing */ 597*be771a7bSCy Schubert } 598*be771a7bSCy Schubert 599*be771a7bSCy Schubert void listen_desetup_locks(void) 600*be771a7bSCy Schubert { 601*be771a7bSCy Schubert /* nothing */ 602*be771a7bSCy Schubert } 603*be771a7bSCy Schubert 604*be771a7bSCy Schubert void fast_reload_printq_list_delete( 605*be771a7bSCy Schubert struct fast_reload_printq* ATTR_UNUSED(list)) 606*be771a7bSCy Schubert { 607*be771a7bSCy Schubert /* nothing */ 608*be771a7bSCy Schubert } 609*be771a7bSCy Schubert 610*be771a7bSCy Schubert void fast_reload_worker_pickup_changes(struct worker* ATTR_UNUSED(worker)) 611*be771a7bSCy Schubert { 612*be771a7bSCy Schubert /* nothing */ 613*be771a7bSCy Schubert } 614*be771a7bSCy Schubert 615*be771a7bSCy Schubert #ifdef HAVE_NGTCP2 616*be771a7bSCy Schubert void* quic_sslctx_create(char* ATTR_UNUSED(key), char* ATTR_UNUSED(pem), 617*be771a7bSCy Schubert char* ATTR_UNUSED(verifypem)) 618*be771a7bSCy Schubert { 619*be771a7bSCy Schubert return NULL; 620*be771a7bSCy Schubert } 621*be771a7bSCy Schubert 622*be771a7bSCy Schubert void comm_point_doq_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(event), 623*be771a7bSCy Schubert void* ATTR_UNUSED(arg)) 624*be771a7bSCy Schubert { 625*be771a7bSCy Schubert /* nothing */ 626*be771a7bSCy Schubert } 627*be771a7bSCy Schubert 628*be771a7bSCy Schubert int doq_conn_cmp(const void* ATTR_UNUSED(key1), const void* ATTR_UNUSED(key2)) 629*be771a7bSCy Schubert { 630*be771a7bSCy Schubert return 0; 631*be771a7bSCy Schubert } 632*be771a7bSCy Schubert 633*be771a7bSCy Schubert int doq_conid_cmp(const void* ATTR_UNUSED(key1), const void* ATTR_UNUSED(key2)) 634*be771a7bSCy Schubert { 635*be771a7bSCy Schubert return 0; 636*be771a7bSCy Schubert } 637*be771a7bSCy Schubert 638*be771a7bSCy Schubert int doq_timer_cmp(const void* ATTR_UNUSED(key1), const void* ATTR_UNUSED(key2)) 639*be771a7bSCy Schubert { 640*be771a7bSCy Schubert return 0; 641*be771a7bSCy Schubert } 642*be771a7bSCy Schubert 643*be771a7bSCy Schubert int doq_stream_cmp(const void* ATTR_UNUSED(key1), const void* ATTR_UNUSED(key2)) 644*be771a7bSCy Schubert { 645*be771a7bSCy Schubert return 0; 646*be771a7bSCy Schubert } 647*be771a7bSCy Schubert 648*be771a7bSCy Schubert struct doq_table* doq_table_create(struct config_file* ATTR_UNUSED(cfg), 649*be771a7bSCy Schubert struct ub_randstate* ATTR_UNUSED(rnd)) 650*be771a7bSCy Schubert { 651*be771a7bSCy Schubert return calloc(1, sizeof(struct doq_table)); 652*be771a7bSCy Schubert } 653*be771a7bSCy Schubert 654*be771a7bSCy Schubert void doq_table_delete(struct doq_table* table) 655*be771a7bSCy Schubert { 656*be771a7bSCy Schubert free(table); 657*be771a7bSCy Schubert } 658*be771a7bSCy Schubert 659*be771a7bSCy Schubert void doq_timer_cb(void* ATTR_UNUSED(arg)) 660*be771a7bSCy Schubert { 661*be771a7bSCy Schubert /* nothing */ 662*be771a7bSCy Schubert } 663*be771a7bSCy Schubert 664*be771a7bSCy Schubert size_t doq_table_quic_size_get(struct doq_table* ATTR_UNUSED(table)) 665*be771a7bSCy Schubert { 666*be771a7bSCy Schubert return 0; 667*be771a7bSCy Schubert } 668*be771a7bSCy Schubert #endif 669