DoS protection.

git-svn-id: file:///svn/unbound/trunk@1221 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards
2008-09-02 13:04:47 +00:00
parent 01cabbebc1
commit 960da40475
12 changed files with 598 additions and 63 deletions
+32
View File
@@ -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);
+18
View File
@@ -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);
+7
View File
@@ -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 */