mirror of
https://github.com/NLnetLabs/unbound.git
synced 2025-12-27 02:00:18 -05:00
RTT banding, more spoof resistance randomness.
git-svn-id: file:///svn/unbound/trunk@1019 be551aaa-1e26-0410-a405-d3ace91eadb9
This commit is contained in:
parent
87700fea40
commit
64627b1a63
4 changed files with 46 additions and 15 deletions
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue