]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
RTT banding, more spoof resistance randomness.
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 25 Mar 2008 15:33:24 +0000 (15:33 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 25 Mar 2008 15:33:24 +0000 (15:33 +0000)
git-svn-id: file:///svn/unbound/trunk@1019 be551aaa-1e26-0410-a405-d3ace91eadb9

doc/Changelog
iterator/iter_delegpt.h
iterator/iter_utils.c
iterator/iterator.h

index 06f00cebbe21078760124d07426974572a57d164..439312ee9d7b24b4d3ccacfcd9f937b479bcb299 100644 (file)
@@ -7,6 +7,8 @@
          sure nothing gets into the RRset cache. Also, this looks like a
          timeout (instead of an allocation failure) and this retries are
          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
        - -C config feature for harvest program. 
index ce0ce17539d2a979f6579be7db08526ca6fd30d4..25e8665718cb70c088ffffa05b18af8e73a1e367 100644 (file)
@@ -106,6 +106,8 @@ struct delegpt_addr {
        socklen_t addrlen;
        /** number of attempts for this addr */
        int attempts;
+       /** rtt stored here in the selection algorithm */
+       int sel_rtt;
 };
 
 /**
index d4be9da4aa90b1c1da4a770df3cc25d7a61fe952..9a0577dc06136d23ddfafc5edd366a9aa6d7ac2a 100644 (file)
@@ -156,38 +156,61 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env,
        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,
  * returns number of best targets (or 0, no suitable targets) */
 static int
 iter_filter_order(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* 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;
 
+       /* 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;
        while(a) {
-               /* filter out unsuitable targets */
-               thisrtt = iter_filter_unsuitable(iter_env, env, name, namelen, 
-                       now, a);
-               if(thisrtt == -1) {
+               /* skip unsuitable targets */
+               if(a->sel_rtt == -1) {
                        prev = a;
                        a = a->next_result;
                        continue;
                }
                /* classify the server address and determine what to do */
                swap_to_front = 0;
-               if(got_num == 0) {
-                       got_rtt = thisrtt;
-                       got_num = 1;
-                       swap_to_front = 1;
-               } else if(thisrtt == got_rtt) {
+               if(a->sel_rtt >= low_rtt && a->sel_rtt - low_rtt <= RTT_BAND) {
                        got_num++;
                        swap_to_front = 1;
-               } else if(thisrtt < got_rtt) {
-                       got_rtt = thisrtt;
-                       got_num = 1; /* start back at count of 1 */
+               } else if(a->sel_rtt<low_rtt && low_rtt-a->sel_rtt<=RTT_BAND) {
+                       got_num++;
                        swap_to_front = 1;
                }
                /* 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;
                }
        }
-       *best_rtt = got_rtt;
+       *selected_rtt = low_rtt;
        return got_num;
 }
 
index eeaf720ea3d3ea918faaacddbdd62031b61bfba6..45b51b6029a7cf059c8cbd09d1d336ff5de0aa2d 100644 (file)
@@ -66,6 +66,10 @@ struct iter_prep_list;
 #define USEFUL_SERVER_TOP_TIMEOUT      120000
 /** number of retries on outgoing queries */
 #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.