mirror of
https://github.com/NLnetLabs/unbound.git
synced 2026-08-25 00:52:29 +02:00
DoS protection.
git-svn-id: file:///svn/unbound/trunk@1221 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
@@ -61,6 +61,20 @@
|
||||
/** Global variable: the scenario. Saved here for when event_init is done. */
|
||||
static struct replay_scenario* saved_scenario = NULL;
|
||||
|
||||
/** add timers and the values do not overflow or become negative */
|
||||
static void
|
||||
timeval_add(struct timeval* d, struct timeval* add)
|
||||
{
|
||||
#ifndef S_SPLINT_S
|
||||
d->tv_sec += add->tv_sec;
|
||||
d->tv_usec += add->tv_usec;
|
||||
while(d->tv_usec > 1000000 ) {
|
||||
d->tv_usec -= 1000000;
|
||||
d->tv_sec++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
fake_event_init(struct replay_scenario* scen)
|
||||
{
|
||||
@@ -98,6 +112,7 @@ repevt_string(enum replay_event_type t)
|
||||
case repevt_front_query: return "QUERY";
|
||||
case repevt_front_reply: return "CHECK_ANSWER";
|
||||
case repevt_timeout: return "TIMEOUT";
|
||||
case repevt_time_passes: return "TIME_PASSES";
|
||||
case repevt_back_reply: return "REPLY";
|
||||
case repevt_back_query: return "CHECK_OUT_QUERY";
|
||||
case repevt_error: return "ERROR";
|
||||
@@ -408,6 +423,19 @@ fake_pending_callback(struct replay_runtime* runtime,
|
||||
ldns_buffer_free(c.buffer);
|
||||
}
|
||||
|
||||
/** pass time */
|
||||
static void
|
||||
time_passes(struct replay_runtime* runtime, struct replay_moment* mom)
|
||||
{
|
||||
timeval_add(&runtime->now_tv, &mom->elapse);
|
||||
runtime->now_secs = (uint32_t)runtime->now_tv.tv_sec;
|
||||
#ifndef S_SPLINT_S
|
||||
log_info("elapsed %d.%6.6d now %d.%6.6d",
|
||||
(int)mom->elapse.tv_sec, (int)mom->elapse.tv_usec,
|
||||
(int)runtime->now_tv.tv_sec, (int)runtime->now_tv.tv_usec);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* Advance to the next moment.
|
||||
*/
|
||||
@@ -471,6 +499,10 @@ do_moment_and_advance(struct replay_runtime* runtime)
|
||||
advance_moment(runtime);
|
||||
fake_pending_callback(runtime, mom, NETEVENT_CLOSED);
|
||||
break;
|
||||
case repevt_time_passes:
|
||||
time_passes(runtime, runtime->now);
|
||||
advance_moment(runtime);
|
||||
break;
|
||||
default:
|
||||
fatal_exit("testbound: unknown event type %d",
|
||||
runtime->now->evt_type);
|
||||
|
||||
@@ -221,6 +221,8 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
|
||||
readentry = 1;
|
||||
} else if(parse_keyword(&remain, "TIMEOUT")) {
|
||||
mom->evt_type = repevt_timeout;
|
||||
} else if(parse_keyword(&remain, "TIME_PASSES")) {
|
||||
mom->evt_type = repevt_time_passes;
|
||||
} else if(parse_keyword(&remain, "ERROR")) {
|
||||
mom->evt_type = repevt_error;
|
||||
} else {
|
||||
@@ -242,6 +244,22 @@ replay_moment_read(char* remain, FILE* in, const char* name, int* lineno,
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if(parse_keyword(&remain, "ELAPSE")) {
|
||||
double sec;
|
||||
errno = 0;
|
||||
sec = strtod(remain, &remain);
|
||||
if(sec == 0. && errno != 0) {
|
||||
log_err("line %d: could not parse ELAPSE: %s (%s)",
|
||||
*lineno, remain, strerror(errno));
|
||||
free(mom);
|
||||
return NULL;
|
||||
}
|
||||
#ifndef S_SPLINT_S
|
||||
mom->elapse.tv_sec = (int)sec;
|
||||
mom->elapse.tv_usec = (int)((sec - (double)mom->elapse.tv_sec)
|
||||
*1000000. + 0.5);
|
||||
#endif
|
||||
}
|
||||
|
||||
if(readentry) {
|
||||
mom->match = read_entry(in, name, lineno, ttl, or, prev);
|
||||
|
||||
@@ -58,6 +58,8 @@
|
||||
* o CHECK_OUT_QUERY - followed by entry (if copy-id it is also reply).
|
||||
* o REPLY - followed by entry
|
||||
* o TIMEOUT
|
||||
* o TIME_PASSES ELAPSE [seconds] - increase 'now' time counter, can be
|
||||
* a floating point number.
|
||||
* o ERROR
|
||||
* ; following entry starts on the next line, ENTRY_BEGIN.
|
||||
* ; more STEP items
|
||||
@@ -149,6 +151,8 @@ struct replay_moment {
|
||||
repevt_front_reply,
|
||||
/** timeout */
|
||||
repevt_timeout,
|
||||
/** time passes */
|
||||
repevt_time_passes,
|
||||
/** reply arrives from the network */
|
||||
repevt_back_reply,
|
||||
/** test fails if query to the network does not match */
|
||||
@@ -162,6 +166,9 @@ struct replay_moment {
|
||||
/** The sent packet must match this. Incoming events, the data. */
|
||||
struct entry* match;
|
||||
|
||||
/** the amount of time that passes */
|
||||
struct timeval elapse;
|
||||
|
||||
/** address that must be matched, or packet remote host address. */
|
||||
struct sockaddr_storage addr;
|
||||
/** length of addr, if 0, then any address will do */
|
||||
|
||||
Reference in New Issue
Block a user