Browse Source

enable configuration of new timeouts

renamed existing timeout to query_timeout, added client_timeout and
lookup_timeout
In the config spec, these are named timeout_XX instead of XX_timeout, so
they will automatically be shown next to each other in ordered output
Jelte Jansen 14 years ago
parent
commit
b3ec8dc352

+ 65 - 19
src/bin/resolver/resolver.cc

@@ -66,7 +66,9 @@ private:
 public:
     ResolverImpl() :
         config_session_(NULL),
-        timeout_(2000),
+        query_timeout_(2000),
+        client_timeout_(4000),
+        lookup_timeout_(30000),
         retries_(3),
         rec_query_(NULL)
     {}
@@ -78,7 +80,7 @@ public:
     void querySetup(DNSService& dnss) {
         assert(!rec_query_); // queryShutdown must be called first
         dlog("Query setup");
-        rec_query_ = new RecursiveQuery(dnss, upstream_, timeout_, retries_);
+        rec_query_ = new RecursiveQuery(dnss, upstream_, query_timeout_, retries_);
     }
 
     void queryShutdown() {
@@ -124,8 +126,13 @@ public:
     /// Addresses we listen on
     vector<addr_t> listen_;
 
-    /// Time in milliseconds, to timeout
-    int timeout_;
+    /// Timeout for outgoing queries in milliseconds
+    int query_timeout_;
+    /// Timeout for incoming client queries in milliseconds
+    int client_timeout_;
+    /// Timeout for lookup processing in milliseconds
+    int lookup_timeout_;
+    
     /// Number of retries after timeout
     unsigned retries_;
 
@@ -496,16 +503,34 @@ Resolver::updateConfig(ConstElementPtr config) {
         ConstElementPtr listenAddressesE(config->get("listen_on"));
         vector<addr_t> listenAddresses(parseAddresses(listenAddressesE));
         bool set_timeouts(false);
-        int timeout = impl_->timeout_;
+        int qtimeout = impl_->query_timeout_;
+        int ctimeout = impl_->client_timeout_;
+        int ltimeout = impl_->lookup_timeout_;
         unsigned retries = impl_->retries_;
-        ConstElementPtr timeoutE(config->get("timeout")),
-            retriesE(config->get("retries"));
-        if (timeoutE) {
+        ConstElementPtr qtimeoutE(config->get("timeout_query")),
+                        ctimeoutE(config->get("timeout_client")),
+                        ltimeoutE(config->get("timeout_lookup")),
+                        retriesE(config->get("retries"));
+        if (qtimeoutE) {
             // It should be safe to just get it, the config manager should
             // check for us
-            timeout = timeoutE->intValue();
-            if (timeout < -1) {
-                isc_throw(BadValue, "Timeout too small");
+            qtimeout = qtimeoutE->intValue();
+            if (qtimeout < -1) {
+                isc_throw(BadValue, "Query timeout too small");
+            }
+            set_timeouts = true;
+        }
+        if (ctimeoutE) {
+            ctimeout = ctimeoutE->intValue();
+            if (ctimeout < -1) {
+                isc_throw(BadValue, "Client timeout too small");
+            }
+            set_timeouts = true;
+        }
+        if (ltimeoutE) {
+            ltimeout = ltimeoutE->intValue();
+            if (ltimeout < -1) {
+                isc_throw(BadValue, "Lookup timeout too small");
             }
             set_timeouts = true;
         }
@@ -529,7 +554,7 @@ Resolver::updateConfig(ConstElementPtr config) {
             need_query_restart = true;
         }
         if (set_timeouts) {
-            setTimeouts(timeout, retries);
+            setTimeouts(qtimeout, ctimeout, ltimeout, retries);
             need_query_restart = true;
         }
 
@@ -605,15 +630,36 @@ Resolver::setListenAddresses(const vector<addr_t>& addresses) {
 }
 
 void
-Resolver::setTimeouts(int timeout, unsigned retries) {
-    dlog("Setting timeout to " + boost::lexical_cast<string>(timeout) +
-        " and retry count to " + boost::lexical_cast<string>(retries));
-    impl_->timeout_ = timeout;
+Resolver::setTimeouts(int query_timeout, int client_timeout,
+                      int lookup_timeout, unsigned retries) {
+    dlog("Setting query timeout to " + boost::lexical_cast<string>(query_timeout) +
+         ", client timeout to " + boost::lexical_cast<string>(client_timeout) +
+         ", lookup timeout to " + boost::lexical_cast<string>(lookup_timeout) +
+         " and retry count to " + boost::lexical_cast<string>(retries));
+    impl_->query_timeout_ = query_timeout;
+    impl_->client_timeout_ = client_timeout;
+    impl_->lookup_timeout_ = lookup_timeout;
     impl_->retries_ = retries;
 }
-pair<int, unsigned>
-Resolver::getTimeouts() const {
-    return (pair<int, unsigned>(impl_->timeout_, impl_->retries_));
+
+int
+Resolver::getQueryTimeout() const {
+    return impl_->query_timeout_;
+}
+
+int
+Resolver::getClientTimeout() const {
+    return impl_->client_timeout_;
+}
+
+int
+Resolver::getLookupTimeout() const {
+    return impl_->lookup_timeout_;
+}
+
+int
+Resolver::getRetries() const {
+    return impl_->retries_;
 }
 
 vector<addr_t>

+ 37 - 1
src/bin/resolver/resolver.h

@@ -127,7 +127,10 @@ public:
      * \param retries The number of retries (0 means try the first time only,
      *     do not retry).
      */
-    void setTimeouts(int timeout = -1, unsigned retries = 0);
+    void setTimeouts(int query_timeout = 2000,
+                     int client_timeout = 4000,
+                     int lookup_timeout = 30000,
+                     unsigned retries = 3);
 
     /**
      * \short Get info about timeouts.
@@ -136,6 +139,39 @@ public:
      */
     std::pair<int, unsigned> getTimeouts() const;
 
+    /**
+     * \brief Get the timeout for outgoing queries
+     *
+     * \returns Timeout for outgoing queries
+     */
+    int getQueryTimeout() const;
+
+    /**
+     * \brief Get the timeout for incoming client queries
+     *
+     * After this timeout, a SERVFAIL shall be sent back
+     * (internal resolving on the query will continue, see
+     * \c getLookupTimeout())
+     * 
+     * \returns Timeout for outgoing queries
+     */
+    int getClientTimeout() const;
+
+    /**
+     * \brief Get the timeout for lookups
+     *
+     * After this timeout, internal processing shall stop
+     */
+    int getLookupTimeout() const;
+
+    /**
+     * \brief Get the number of retries for outgoing queries
+     *
+     * If a query times out (value of \c getQueryTimeout()), we
+     * will retry this number of times
+     */
+    int getRetries() const;
+
 private:
     ResolverImpl* impl_;
     asiolink::DNSService* dnss_;

+ 13 - 1
src/bin/resolver/resolver.spec.pre.in

@@ -4,12 +4,24 @@
     "module_description": "Recursive service",
     "config_data": [
       {
-        "item_name": "timeout",
+        "item_name": "timeout_query",
         "item_type": "integer",
         "item_optional": False,
         "item_default": 2000
       },
       {
+        "item_name": "timeout_client",
+        "item_type": "integer",
+        "item_optional": False,
+        "item_default": 4000
+      },
+      {
+        "item_name": "timeout_lookup",
+        "item_type": "integer",
+        "item_optional": False,
+        "item_default": 30000
+      },
+      {
         "item_name": "retries",
         "item_type": "integer",
         "item_optional": False,

+ 31 - 11
src/bin/resolver/tests/resolver_config_unittest.cc

@@ -212,31 +212,51 @@ TEST_F(ResolverConfig, invalidListenAddresses) {
 
 // Just test it sets and gets the values correctly
 TEST_F(ResolverConfig, timeouts) {
-    server.setTimeouts(0, 1);
-    EXPECT_EQ(0, server.getTimeouts().first);
-    EXPECT_EQ(1, server.getTimeouts().second);
+    server.setTimeouts(0, 1, 2, 3);
+    EXPECT_EQ(0, server.getQueryTimeout());
+    EXPECT_EQ(1, server.getClientTimeout());
+    EXPECT_EQ(2, server.getLookupTimeout());
+    EXPECT_EQ(3, server.getRetries());
     server.setTimeouts();
-    EXPECT_EQ(-1, server.getTimeouts().first);
-    EXPECT_EQ(0, server.getTimeouts().second);
+    EXPECT_EQ(2000, server.getQueryTimeout());
+    EXPECT_EQ(4000, server.getClientTimeout());
+    EXPECT_EQ(30000, server.getLookupTimeout());
+    EXPECT_EQ(3, server.getRetries());
 }
 
 TEST_F(ResolverConfig, timeoutsConfig) {
     ElementPtr config = Element::fromJSON("{"
-            "\"timeout\": 1000,"
-            "\"retries\": 3"
+            "\"timeout_query\": 1000,"
+            "\"timeout_client\": 2000,"
+            "\"timeout_lookup\": 3000,"
+            "\"retries\": 4"
             "}");
     ConstElementPtr result(server.updateConfig(config));
     EXPECT_EQ(result->toWire(), isc::config::createAnswer()->toWire());
-    EXPECT_EQ(1000, server.getTimeouts().first);
-    EXPECT_EQ(3, server.getTimeouts().second);
+    EXPECT_EQ(1000, server.getQueryTimeout());
+    EXPECT_EQ(2000, server.getClientTimeout());
+    EXPECT_EQ(3000, server.getLookupTimeout());
+    EXPECT_EQ(4, server.getRetries());
 }
 
 TEST_F(ResolverConfig, invalidTimeoutsConfig) {
     invalidTest("{"
-        "\"timeout\": \"error\""
+        "\"timeout_query\": \"error\""
         "}");
     invalidTest("{"
-        "\"timeout\": -2"
+        "\"timeout_query\": -2"
+        "}");
+    invalidTest("{"
+        "\"timeout_client\": \"error\""
+        "}");
+    invalidTest("{"
+        "\"timeout_client\": -2"
+        "}");
+    invalidTest("{"
+        "\"timeout_lookup\": \"error\""
+        "}");
+    invalidTest("{"
+        "\"timeout_lookup\": -2"
         "}");
     invalidTest("{"
         "\"retries\": \"error\""