mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-09-13 21:37:43 +02:00
autotrust test routines.
git-svn-id: file:///svn/unbound/trunk@1771 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
@@ -51,6 +51,7 @@
|
||||
#include "util/data/msgparse.h"
|
||||
#include "util/data/msgreply.h"
|
||||
#include "util/data/msgencode.h"
|
||||
#include "util/config_file.h"
|
||||
#include "services/listen_dnsport.h"
|
||||
#include "services/outside_network.h"
|
||||
#include "testcode/replay.h"
|
||||
@@ -76,6 +77,18 @@ timeval_add(struct timeval* d, const struct timeval* add)
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
fake_temp_file(const char* adj, const char* id, char* buf, size_t len)
|
||||
{
|
||||
#ifdef USE_WINSOCK
|
||||
snprintf(buf, len, "testbound_%u%s%s.tmp",
|
||||
(unsigned)getpid(), adj, id);
|
||||
#else
|
||||
snprintf(buf, len, "/tmp/testbound_%u%s%s.tmp",
|
||||
(unsigned)getpid(), adj, id);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
fake_event_init(struct replay_scenario* scen)
|
||||
{
|
||||
@@ -116,6 +129,7 @@ repevt_string(enum replay_event_type t)
|
||||
case repevt_time_passes: return "TIME_PASSES";
|
||||
case repevt_back_reply: return "REPLY";
|
||||
case repevt_back_query: return "CHECK_OUT_QUERY";
|
||||
case repevt_autotrust_check: return "CHECK_AUTOTRUST";
|
||||
case repevt_error: return "ERROR";
|
||||
default: return "UNKNOWN";
|
||||
}
|
||||
@@ -437,6 +451,51 @@ time_passes(struct replay_runtime* runtime, struct replay_moment* mom)
|
||||
#endif
|
||||
}
|
||||
|
||||
/** check autotrust file contents */
|
||||
static void
|
||||
autotrust_check(struct replay_moment* mom)
|
||||
{
|
||||
char name[1024], line[1024];
|
||||
FILE *in;
|
||||
int lineno = 0, oke=1;
|
||||
struct config_strlist* p;
|
||||
line[sizeof(line)-1] = 0;
|
||||
log_assert(mom->autotrust_id);
|
||||
fake_temp_file("_auto_", mom->autotrust_id, name, sizeof(name));
|
||||
in = fopen(name, "r");
|
||||
if(!in) fatal_exit("could not open %s: %s", name, strerror(errno));
|
||||
for(p=mom->file_content; p; p=p->next) {
|
||||
lineno++;
|
||||
if(!fgets(line, (int)sizeof(line)-1, in)) {
|
||||
log_err("autotrust check failed, could not read line");
|
||||
log_err("file %s, line %d", name, lineno);
|
||||
log_err("should be: %s", p->str);
|
||||
fatal_exit("autotrust_check failed");
|
||||
}
|
||||
if(line[0]) line[strlen(line)-1] = 0; /* remove newline */
|
||||
if(strcmp(p->str, line) != 0) {
|
||||
log_err("mismatch in file %s, line %d", name, lineno);
|
||||
log_err("file has : %s", line);
|
||||
log_err("should be: %s", p->str);
|
||||
oke = 0;
|
||||
continue;
|
||||
}
|
||||
fprintf(stderr, "%s:%2d ok : %s\n", name, lineno, line);
|
||||
}
|
||||
if(fgets(line, (int)sizeof(line)-1, in)) {
|
||||
log_err("autotrust check failed, extra lines in %s after %d",
|
||||
name, lineno);
|
||||
do {
|
||||
fprintf(stderr, "file has: %s", line);
|
||||
} while(fgets(line, (int)sizeof(line)-1, in));
|
||||
oke = 0;
|
||||
}
|
||||
fclose(in);
|
||||
if(!oke)
|
||||
fatal_exit("autotrust_check STEP %d failed", mom->time_step);
|
||||
log_info("autotrust %s is OK", mom->autotrust_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Advance to the next moment.
|
||||
*/
|
||||
@@ -504,6 +563,10 @@ do_moment_and_advance(struct replay_runtime* runtime)
|
||||
time_passes(runtime, runtime->now);
|
||||
advance_moment(runtime);
|
||||
break;
|
||||
case repevt_autotrust_check:
|
||||
autotrust_check(runtime->now);
|
||||
advance_moment(runtime);
|
||||
break;
|
||||
default:
|
||||
fatal_exit("testbound: unknown event type %d",
|
||||
runtime->now->evt_type);
|
||||
|
||||
@@ -63,4 +63,13 @@ void fake_event_init(struct replay_scenario* scen);
|
||||
*/
|
||||
void fake_event_cleanup();
|
||||
|
||||
/**
|
||||
* Get filename to store temporary config stuff. The pid is added. in /tmp.
|
||||
* @param adj: adjective, like "_cfg_", "_auto_"
|
||||
* @param id: identifier, like "example.com".
|
||||
* @param buf: where to store.
|
||||
* @param len: length of buf.
|
||||
*/
|
||||
void fake_temp_file(const char* adj, const char* id, char* buf, size_t len);
|
||||
|
||||
#endif /* TESTCODE_FAKE_EVENT_H */
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
#include "config.h"
|
||||
#include "util/log.h"
|
||||
#include "util/net_help.h"
|
||||
#include "util/config_file.h"
|
||||
#include "testcode/replay.h"
|
||||
#include "testcode/ldns-testpkts.h"
|
||||
|
||||
@@ -73,6 +74,8 @@ replay_moment_delete(struct replay_moment* mom)
|
||||
if(mom->match) {
|
||||
delete_entry(mom->match);
|
||||
}
|
||||
free(mom->autotrust_id);
|
||||
config_delstrlist(mom->file_content);
|
||||
free(mom);
|
||||
}
|
||||
|
||||
@@ -173,6 +176,31 @@ replay_range_read(char* remain, FILE* in, const char* name, int* lineno,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/** Read FILE match content */
|
||||
static void
|
||||
read_file_content(FILE* in, int* lineno, struct replay_moment* mom)
|
||||
{
|
||||
char line[MAX_LINE_LEN];
|
||||
char* remain = line;
|
||||
struct config_strlist** last = &mom->file_content;
|
||||
line[MAX_LINE_LEN-1]=0;
|
||||
if(!fgets(line, MAX_LINE_LEN-1, in))
|
||||
fatal_exit("FILE_BEGIN expected at line %d", *lineno);
|
||||
if(!parse_keyword(&remain, "FILE_BEGIN"))
|
||||
fatal_exit("FILE_BEGIN expected at line %d", *lineno);
|
||||
while(fgets(line, MAX_LINE_LEN-1, in)) {
|
||||
(*lineno)++;
|
||||
if(strncmp(line, "FILE_END", 8) == 0) {
|
||||
return;
|
||||
}
|
||||
if(line[0]) line[strlen(line)-1] = 0; /* remove newline */
|
||||
if(!cfg_strlist_insert(last, strdup(line)))
|
||||
fatal_exit("malloc failure");
|
||||
last = &( (*last)->next );
|
||||
}
|
||||
fatal_exit("no FILE_END in input file");
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a replay moment 'STEP' from file.
|
||||
* @param remain: Rest of line (after STEP keyword).
|
||||
@@ -223,6 +251,14 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
|
||||
mom->evt_type = repevt_timeout;
|
||||
} else if(parse_keyword(&remain, "TIME_PASSES")) {
|
||||
mom->evt_type = repevt_time_passes;
|
||||
} else if(parse_keyword(&remain, "CHECK_AUTOTRUST")) {
|
||||
mom->evt_type = repevt_autotrust_check;
|
||||
while(isspace((int)*remain))
|
||||
remain++;
|
||||
if(strlen(remain)>0 && remain[strlen(remain)-1]=='\n')
|
||||
remain[strlen(remain)-1] = 0;
|
||||
mom->autotrust_id = strdup(remain);
|
||||
read_file_content(in, lineno, mom);
|
||||
} else if(parse_keyword(&remain, "ERROR")) {
|
||||
mom->evt_type = repevt_error;
|
||||
} else {
|
||||
|
||||
@@ -41,6 +41,15 @@
|
||||
* <pre>
|
||||
* File format for replay files.
|
||||
*
|
||||
* ; unbound.conf options.
|
||||
* ; ...
|
||||
* ; additional commandline options to pass to unbound
|
||||
* COMMANDLINE cmdline_option
|
||||
* ; autotrust key file contents, also adds auto-trust-anchor-file: "x" to cfg
|
||||
* AUTOTRUST_FILE id
|
||||
* ; contents of that file
|
||||
* AUTOTRUST_END
|
||||
* CONFIG_END
|
||||
* ; comment line.
|
||||
* SCENARIO_BEGIN name_of_scenario
|
||||
* RANGE_BEGIN start_time end_time
|
||||
@@ -60,6 +69,7 @@
|
||||
* o TIMEOUT
|
||||
* o TIME_PASSES ELAPSE [seconds] - increase 'now' time counter, can be
|
||||
* a floating point number.
|
||||
* o CHECK_AUTOTRUST [id] - followed by FILE_BEGIN [to match] FILE_END.
|
||||
* o ERROR
|
||||
* ; following entry starts on the next line, ENTRY_BEGIN.
|
||||
* ; more STEP items
|
||||
@@ -156,6 +166,8 @@ struct replay_moment {
|
||||
repevt_back_reply,
|
||||
/** test fails if query to the network does not match */
|
||||
repevt_back_query,
|
||||
/** check autotrust key file */
|
||||
repevt_autotrust_check,
|
||||
/** an error happens to outbound query */
|
||||
repevt_error
|
||||
}
|
||||
@@ -178,6 +190,11 @@ struct replay_moment {
|
||||
* Unused at this time.
|
||||
*/
|
||||
ldns_rr* qname;
|
||||
|
||||
/** the autotrust file id to check */
|
||||
char* autotrust_id;
|
||||
/** file contents to match, one string per line */
|
||||
struct config_strlist* file_content;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
+60
-20
@@ -43,6 +43,7 @@
|
||||
#include "testcode/replay.h"
|
||||
#include "testcode/fake_event.h"
|
||||
#include "daemon/remote.h"
|
||||
#include "util/config_file.h"
|
||||
|
||||
/**
|
||||
* include the main program from the unbound daemon.
|
||||
@@ -54,8 +55,8 @@
|
||||
|
||||
/** maximum line length for lines in the replay file. */
|
||||
#define MAX_LINE_LEN 1024
|
||||
/** the config file (removed at exit) */
|
||||
static char cfgfile[MAX_LINE_LEN];
|
||||
/** config files (removed at exit) */
|
||||
static struct config_strlist* cfgfiles = NULL;
|
||||
|
||||
/** give commandline usage for testbound. */
|
||||
static void
|
||||
@@ -122,27 +123,60 @@ echo_cmdline(int argc, char* argv[])
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
/** process config elements */
|
||||
/** spool autotrust file */
|
||||
static void
|
||||
setup_config(FILE* in, char* configfile, int* lineno,
|
||||
int* pass_argc, char* pass_argv[])
|
||||
spool_auto_file(FILE* in, int* lineno, FILE* cfg, char* id)
|
||||
{
|
||||
char line[MAX_LINE_LEN];
|
||||
char* parse;
|
||||
FILE* spool;
|
||||
/* find filename for new file */
|
||||
while(isspace((int)*id))
|
||||
id++;
|
||||
if(strlen(id)==0)
|
||||
fatal_exit("AUTROTRUST_FILE must have id, line %d", *lineno);
|
||||
id[strlen(id)-1]=0; /* remove newline */
|
||||
fake_temp_file("_auto_", id, line, sizeof(line));
|
||||
/* add option for the file */
|
||||
fprintf(cfg, "server: auto-trust-anchor-file: \"%s\"\n", line);
|
||||
/* open file and spool to it */
|
||||
spool = fopen(line, "w");
|
||||
if(!spool) fatal_exit("could not open %s: %s", line, strerror(errno));
|
||||
fprintf(stderr, "testbound is spooling key file: %s\n", line);
|
||||
if(!cfg_strlist_insert(&cfgfiles, strdup(line)))
|
||||
fatal_exit("out of memory");
|
||||
line[sizeof(line)-1] = 0;
|
||||
while(fgets(line, MAX_LINE_LEN-1, in)) {
|
||||
parse = line;
|
||||
(*lineno)++;
|
||||
while(isspace((int)*parse))
|
||||
parse++;
|
||||
if(strncmp(parse, "AUTOTRUST_END", 13) == 0) {
|
||||
fclose(spool);
|
||||
return;
|
||||
}
|
||||
fputs(line, spool);
|
||||
}
|
||||
fatal_exit("no AUTOTRUST_END in input file");
|
||||
}
|
||||
|
||||
/** process config elements */
|
||||
static void
|
||||
setup_config(FILE* in, int* lineno, int* pass_argc, char* pass_argv[])
|
||||
{
|
||||
char configfile[MAX_LINE_LEN];
|
||||
char line[MAX_LINE_LEN];
|
||||
char* parse;
|
||||
FILE* cfg;
|
||||
#ifdef USE_WINSOCK
|
||||
snprintf(configfile, MAX_LINE_LEN, "testbound_cfg_%u.tmp",
|
||||
(unsigned)getpid());
|
||||
#else
|
||||
snprintf(configfile, MAX_LINE_LEN, "/tmp/testbound_cfg_%u.tmp",
|
||||
(unsigned)getpid());
|
||||
#endif
|
||||
fake_temp_file("_cfg", "", configfile, sizeof(configfile));
|
||||
add_opts("-c", pass_argc, pass_argv);
|
||||
add_opts(configfile, pass_argc, pass_argv);
|
||||
cfg = fopen(configfile, "w");
|
||||
if(!cfg) fatal_exit("could not open %s: %s",
|
||||
configfile, strerror(errno));
|
||||
line[MAX_LINE_LEN-1] = 0;
|
||||
if(!cfg_strlist_insert(&cfgfiles, strdup(configfile)))
|
||||
fatal_exit("out of memory");
|
||||
line[sizeof(line)-1] = 0;
|
||||
/* some basic settings to not pollute the host system */
|
||||
fprintf(cfg, "server: use-syslog: no\n");
|
||||
fprintf(cfg, " directory: \"\"\n");
|
||||
@@ -161,6 +195,10 @@ setup_config(FILE* in, char* configfile, int* lineno,
|
||||
add_opts(parse+11, pass_argc, pass_argv);
|
||||
continue;
|
||||
}
|
||||
if(strncmp(parse, "AUTOTRUST_FILE", 14) == 0) {
|
||||
spool_auto_file(in, lineno, cfg, parse+14);
|
||||
continue;
|
||||
}
|
||||
if(strncmp(parse, "CONFIG_END", 10) == 0) {
|
||||
fclose(cfg);
|
||||
return;
|
||||
@@ -173,8 +211,7 @@ setup_config(FILE* in, char* configfile, int* lineno,
|
||||
|
||||
/** read playback file */
|
||||
static struct replay_scenario*
|
||||
setup_playback(const char* filename, char* configfile,
|
||||
int* pass_argc, char* pass_argv[])
|
||||
setup_playback(const char* filename, int* pass_argc, char* pass_argv[])
|
||||
{
|
||||
struct replay_scenario* scen = NULL;
|
||||
int lineno = 0;
|
||||
@@ -185,7 +222,7 @@ setup_playback(const char* filename, char* configfile,
|
||||
perror(filename);
|
||||
exit(1);
|
||||
}
|
||||
setup_config(in, configfile, &lineno, pass_argc, pass_argv);
|
||||
setup_config(in, &lineno, pass_argc, pass_argv);
|
||||
scen = replay_scenario_read(in, filename, &lineno);
|
||||
fclose(in);
|
||||
if(!scen)
|
||||
@@ -199,9 +236,13 @@ setup_playback(const char* filename, char* configfile,
|
||||
/** remove config file at exit */
|
||||
void remove_configfile(void)
|
||||
{
|
||||
unlink(cfgfile);
|
||||
struct config_strlist* p;
|
||||
for(p=cfgfiles; p; p=p->next)
|
||||
unlink(p->str);
|
||||
config_delstrlist(cfgfiles);
|
||||
cfgfiles = NULL;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Main fake event test program. Setup, teardown and report errors.
|
||||
* @param argc: arg count.
|
||||
@@ -221,7 +262,6 @@ main(int argc, char* argv[])
|
||||
log_init(NULL, 0, NULL);
|
||||
log_info("Start of %s testbound program.", PACKAGE_STRING);
|
||||
/* determine commandline options for the daemon */
|
||||
cfgfile[0] = 0;
|
||||
pass_argc = 1;
|
||||
pass_argv[0] = "unbound";
|
||||
add_opts("-d", &pass_argc, pass_argv);
|
||||
@@ -273,7 +313,7 @@ main(int argc, char* argv[])
|
||||
fatal_exit("atexit() failed: %s", strerror(errno));
|
||||
|
||||
/* setup test environment */
|
||||
scen = setup_playback(playback_file, cfgfile, &pass_argc, pass_argv);
|
||||
scen = setup_playback(playback_file, &pass_argc, pass_argv);
|
||||
/* init fake event backend */
|
||||
fake_event_init(scen);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user