RTT banding, more spoof resistance randomness.

git-svn-id: file:///svn/unbound/trunk@1019 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
Wouter Wijngaards 2008-03-25 15:33:24 +00:00
parent 87700fea40
commit 64627b1a63
4 changed files with 46 additions and 15 deletions

View file

@ -7,6 +7,8 @@
sure nothing gets into the RRset cache. Also, this looks like a sure nothing gets into the RRset cache. Also, this looks like a
timeout (instead of an allocation failure) and this retries are timeout (instead of an allocation failure) and this retries are
done (which is useful in a spoofing situation). done (which is useful in a spoofing situation).
- RTT banding. Band size 400 msec, this makes band around zero (fast)
include unknown servers. This makes unbound explore unknown servers.
7 March 2008: Wouter 7 March 2008: Wouter
- -C config feature for harvest program. - -C config feature for harvest program.

View file

@ -106,6 +106,8 @@ struct delegpt_addr {
socklen_t addrlen; socklen_t addrlen;
/** number of attempts for this addr */ /** number of attempts for this addr */
int attempts; int attempts;
/** rtt stored here in the selection algorithm */
int sel_rtt;
}; };
/** /**

View file

@ -156,38 +156,61 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
return UNKNOWN_SERVER_NICENESS; return UNKNOWN_SERVER_NICENESS;
} }
/** lookup RTT information, and also store fastest rtt (if any) */
static int
iter_fill_rtt(struct iter_env* iter_env, struct module_env* env,
uint8_t* name, size_t namelen, uint32_t now, struct delegpt* dp,
int* best_rtt)
{
int got_it = 0;
struct delegpt_addr* a;
for(a=dp->result_list; a; a = a->next_result) {
a->sel_rtt = iter_filter_unsuitable(iter_env, env,
name, namelen, now, a);
if(a->sel_rtt != -1) {
if(!got_it) {
*best_rtt = a->sel_rtt;
got_it = 1;
} else if(a->sel_rtt < *best_rtt) {
*best_rtt = a->sel_rtt;
}
}
}
return got_it;
}
/** filter the addres list, putting best targets at front, /** filter the addres list, putting best targets at front,
* returns number of best targets (or 0, no suitable targets) */ * returns number of best targets (or 0, no suitable targets) */
static int static int
iter_filter_order(struct iter_env* iter_env, struct module_env* env, iter_filter_order(struct iter_env* iter_env, struct module_env* env,
uint8_t* name, size_t namelen, uint32_t now, struct delegpt* dp, uint8_t* name, size_t namelen, uint32_t now, struct delegpt* dp,
int* best_rtt) int* selected_rtt)
{ {
int got_num = 0, got_rtt = 0, thisrtt, swap_to_front; int got_num = 0, low_rtt = 0, swap_to_front;
struct delegpt_addr* a, *n, *prev=NULL; struct delegpt_addr* a, *n, *prev=NULL;
/* fillup sel_rtt and find best rtt in the bunch */
got_num = iter_fill_rtt(iter_env, env, name, namelen, now, dp,
&low_rtt);
if(got_num == 0)
return 0;
got_num = 0;
a = dp->result_list; a = dp->result_list;
while(a) { while(a) {
/* filter out unsuitable targets */ /* skip unsuitable targets */
thisrtt = iter_filter_unsuitable(iter_env, env, name, namelen, if(a->sel_rtt == -1) {
now, a);
if(thisrtt == -1) {
prev = a; prev = a;
a = a->next_result; a = a->next_result;
continue; continue;
} }
/* classify the server address and determine what to do */ /* classify the server address and determine what to do */
swap_to_front = 0; swap_to_front = 0;
if(got_num == 0) { if(a->sel_rtt >= low_rtt && a->sel_rtt - low_rtt <= RTT_BAND) {
got_rtt = thisrtt;
got_num = 1;
swap_to_front = 1;
} else if(thisrtt == got_rtt) {
got_num++; got_num++;
swap_to_front = 1; swap_to_front = 1;
} else if(thisrtt < got_rtt) { } else if(a->sel_rtt<low_rtt && low_rtt-a->sel_rtt<=RTT_BAND) {
got_rtt = thisrtt; got_num++;
got_num = 1; /* start back at count of 1 */
swap_to_front = 1; swap_to_front = 1;
} }
/* swap to front if necessary, or move to next result */ /* swap to front if necessary, or move to next result */
@ -202,7 +225,7 @@ iter_filter_order(struct iter_env* iter_env, struct module_env* env,
a = a->next_result; a = a->next_result;
} }
} }
*best_rtt = got_rtt; *selected_rtt = low_rtt;
return got_num; return got_num;
} }

View file

@ -66,6 +66,10 @@ struct iter_prep_list;
#define USEFUL_SERVER_TOP_TIMEOUT 120000 #define USEFUL_SERVER_TOP_TIMEOUT 120000
/** number of retries on outgoing queries */ /** number of retries on outgoing queries */
#define OUTBOUND_MSG_RETRY 4 #define OUTBOUND_MSG_RETRY 4
/** RTT band, within this amount from the best, servers are chosen randomly.
* Chosen so that the UNKNOWN_SERVER_NICENESS falls within the band of a
* fast server, this causes server exploration as a side benefit. msec. */
#define RTT_BAND 400
/** /**
* Global state for the iterator. * Global state for the iterator.