Просмотр исходного кода

Use AsyncNameResolverMan in DHTEntryPointNameResolveCommand

Tatsuhiro Tsujikawa 12 лет назад
Родитель
Сommit
b5a6c39262

+ 1 - 7
src/AbstractCommand.cc

@@ -107,13 +107,7 @@ AbstractCommand::AbstractCommand
   requestGroup_->increaseStreamCommand();
   requestGroup_->increaseNumCommand();
 #ifdef ENABLE_ASYNC_DNS
-  if(!net::getIPv4AddrConfigured()) {
-    asyncNameResolverMan_->setIPv4(false);
-  }
-  if(!net::getIPv6AddrConfigured() ||
-     e_->getOption()->getAsBool(PREF_DISABLE_IPV6)) {
-    asyncNameResolverMan_->setIPv6(false);
-  }
+  configureAsyncNameResolverMan(asyncNameResolverMan_.get(), e_->getOption());
 #endif // ENABLE_ASYNC_DNS
 }
 

+ 25 - 1
src/AsyncNameResolverMan.cc

@@ -39,6 +39,9 @@
 #include "message.h"
 #include "fmt.h"
 #include "LogFactory.h"
+#include "Option.h"
+#include "SocketCore.h"
+#include "prefs.h"
 
 namespace aria2 {
 
@@ -186,5 +189,26 @@ const std::string& AsyncNameResolverMan::getLastError() const
   return A2STR::NIL;
 }
 
-} // namespace aria2
+void AsyncNameResolverMan::reset(DownloadEngine* e, Command* command)
+{
+  disableNameResolverCheck(e, command);
+  assert(resolverCheck_ == 0);
+  for(size_t i = 0; i < numResolver_; ++i) {
+    asyncNameResolver_[i].reset();
+  }
+  numResolver_ = 0;
+}
 
+void configureAsyncNameResolverMan(AsyncNameResolverMan* asyncNameResolverMan,
+                                   Option* option)
+{
+  if(!net::getIPv4AddrConfigured()) {
+    asyncNameResolverMan->setIPv4(false);
+  }
+  if(!net::getIPv6AddrConfigured() ||
+     option->getAsBool(PREF_DISABLE_IPV6)) {
+    asyncNameResolverMan->setIPv6(false);
+  }
+}
+
+} // namespace aria2

+ 6 - 0
src/AsyncNameResolverMan.h

@@ -47,6 +47,7 @@ namespace aria2 {
 class AsyncNameResolver;
 class DownloadEngine;
 class Command;
+class Option;
 
 class AsyncNameResolverMan {
 public:
@@ -85,6 +86,8 @@ public:
   int getStatus() const;
   // Returns last error string
   const std::string& getLastError() const;
+  // Resets state. Also removes resolvers from DownloadEngine.
+  void reset(DownloadEngine* e, Command* command);
 private:
   void startAsyncFamily(const std::string& hostname,
                         int family,
@@ -101,6 +104,9 @@ private:
   bool ipv6_;
 };
 
+void configureAsyncNameResolverMan(AsyncNameResolverMan* asyncNameResolverMan,
+                                   Option* option);
+
 } // namespace aria2
 
 #endif // D_ASYNC_NAME_RESOLVER_MAN_H

+ 57 - 74
src/DHTEntryPointNameResolveCommand.cc

@@ -49,8 +49,9 @@
 #include "Logger.h"
 #include "LogFactory.h"
 #include "fmt.h"
+#include "SocketCore.h"
 #ifdef ENABLE_ASYNC_DNS
-#include "AsyncNameResolver.h"
+#include "AsyncNameResolverMan.h"
 #endif // ENABLE_ASYNC_DNS
 
 namespace aria2 {
@@ -60,14 +61,20 @@ DHTEntryPointNameResolveCommand::DHTEntryPointNameResolveCommand
  const std::vector<std::pair<std::string, uint16_t> >& entryPoints):
   Command(cuid),
   e_(e),
+  asyncNameResolverMan_(new AsyncNameResolverMan()),
   entryPoints_(entryPoints.begin(), entryPoints.end()),
+  numSuccess_(0),
   bootstrapEnabled_(false)
-{}
+{
+#ifdef ENABLE_ASYNC_DNS
+  configureAsyncNameResolverMan(asyncNameResolverMan_.get(), e_->getOption());
+#endif // ENABLE_ASYNC_DNS
+}
 
 DHTEntryPointNameResolveCommand::~DHTEntryPointNameResolveCommand()
 {
 #ifdef ENABLE_ASYNC_DNS
-  disableNameResolverCheck(resolver_);
+  asyncNameResolverMan_->disableNameResolverCheck(e_, this);
 #endif // ENABLE_ASYNC_DNS
 }
 
@@ -76,46 +83,42 @@ bool DHTEntryPointNameResolveCommand::execute()
   if(e_->getRequestGroupMan()->downloadFinished() || e_->isHaltRequested()) {
     return true;
   }
-#ifdef ENABLE_ASYNC_DNS
-  if(!resolver_) {
-    int family;
-    if(e_->getOption()->getAsBool(PREF_ENABLE_ASYNC_DNS6)) {
-      family = AF_UNSPEC;
-    } else {
-      family = AF_INET;
-    }
-    resolver_.reset(new AsyncNameResolver(family
-#ifdef HAVE_ARES_ADDR_NODE
-                                          , e_->getAsyncDNSServers()
-#endif // HAVE_ARES_ADDR_NODE
-                                          ));
-  }
-#endif // ENABLE_ASYNC_DNS
   try {
 #ifdef ENABLE_ASYNC_DNS
     if(e_->getOption()->getAsBool(PREF_ASYNC_DNS)) {
       while(!entryPoints_.empty()) {
         std::string hostname = entryPoints_.front().first;
-        try {
-          if(util::isNumericHost(hostname)) {
-            std::pair<std::string, uint16_t> p
-              (hostname, entryPoints_.front().second);
-            resolvedEntryPoints_.push_back(p);
-            addPingTask(p);
-          } else if(resolveHostname(hostname, resolver_)) {
-            hostname = resolver_->getResolvedAddresses().front();
-            std::pair<std::string, uint16_t> p(hostname,
-                                               entryPoints_.front().second);
-            resolvedEntryPoints_.push_back(p);
-            addPingTask(p);
-          } else {
-            e_->addCommand(this);
-            return false;
+        if(util::isNumericHost(hostname)) {
+          ++numSuccess_;
+          std::pair<std::string, uint16_t> p(hostname,
+                                             entryPoints_.front().second);
+          addPingTask(p);
+        } else {
+          try {
+            if(resolveHostname(hostname)) {
+              std::vector<std::string> addrs;
+              asyncNameResolverMan_->getResolvedAddress(addrs);
+              if(addrs.empty()) {
+                A2_LOG_ERROR(fmt("No address returned for %s",
+                                 hostname.c_str()));
+              } else {
+                A2_LOG_INFO(fmt(MSG_NAME_RESOLUTION_COMPLETE,
+                                getCuid(), hostname.c_str(),
+                                addrs.front().c_str()));
+                ++numSuccess_;
+                std::pair<std::string, uint16_t> p
+                  (addrs.front(), entryPoints_.front().second);
+                addPingTask(p);
+              }
+            } else {
+              e_->addCommand(this);
+              return false;
+            }
+          } catch(RecoverableException& e) {
+            A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, e);
           }
-        } catch(RecoverableException& e) {
-          A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, e);
+          asyncNameResolverMan_->reset(e_, this);
         }
-        resolver_->reset();
         entryPoints_.pop_front();
       }
     } else
@@ -129,9 +132,9 @@ bool DHTEntryPointNameResolveCommand::execute()
             std::vector<std::string> addrs;
             res.resolve(addrs, hostname);
 
+            ++numSuccess_;
             std::pair<std::string, uint16_t> p(addrs.front(),
                                                entryPoints_.front().second);
-            resolvedEntryPoints_.push_back(p);
             addPingTask(p);
           } catch(RecoverableException& e) {
             A2_LOG_ERROR_EX(EX_EXCEPTION_CAUGHT, e);
@@ -139,7 +142,7 @@ bool DHTEntryPointNameResolveCommand::execute()
           entryPoints_.pop_front();
         }
       }
-    if(bootstrapEnabled_ && resolvedEntryPoints_.size()) {
+    if(bootstrapEnabled_ && numSuccess_) {
       taskQueue_->addPeriodicTask1(taskFactory_->createNodeLookupTask
                                    (localNode_->getID()));
       taskQueue_->addPeriodicTask1(taskFactory_->createBucketRefreshTask());
@@ -163,46 +166,26 @@ void DHTEntryPointNameResolveCommand::addPingTask
 #ifdef ENABLE_ASYNC_DNS
 
 bool DHTEntryPointNameResolveCommand::resolveHostname
-(const std::string& hostname,
- const SharedHandle<AsyncNameResolver>& resolver)
+(const std::string& hostname)
 {
-  switch(resolver->getStatus()) {
-  case AsyncNameResolver::STATUS_READY:
-      A2_LOG_INFO(fmt(MSG_RESOLVING_HOSTNAME,
-                      getCuid(),
-                      hostname.c_str()));
-    resolver->resolve(hostname);
-    setNameResolverCheck(resolver);
-    return false;
-  case AsyncNameResolver::STATUS_SUCCESS:
-    A2_LOG_INFO(fmt(MSG_NAME_RESOLUTION_COMPLETE,
-                    getCuid(),
-                    resolver->getHostname().c_str(),
-                    resolver->getResolvedAddresses().front().c_str()));
-    return true;
-    break;
-  case AsyncNameResolver::STATUS_ERROR:
-    throw DL_ABORT_EX
-      (fmt(MSG_NAME_RESOLUTION_FAILED,
-           getCuid(),
-           hostname.c_str(),
-           resolver->getError().c_str()));
-  default:
-    return false;
+  if(!asyncNameResolverMan_->started()) {
+    asyncNameResolverMan_->startAsync(hostname, e_, this);
+  } else {
+    switch(asyncNameResolverMan_->getStatus()) {
+    case -1:
+      throw DL_ABORT_EX2
+        (fmt(MSG_NAME_RESOLUTION_FAILED, getCuid(), hostname.c_str(),
+             asyncNameResolverMan_->getLastError().c_str()),
+         error_code::NAME_RESOLVE_ERROR);
+    case 0:
+      return false;
+    case 1:
+      return true;
+    }
   }
+  return false;
 }
 
-void DHTEntryPointNameResolveCommand::setNameResolverCheck
-(const SharedHandle<AsyncNameResolver>& resolver)
-{
-  e_->addNameResolverCheck(resolver, this);
-}
-
-void DHTEntryPointNameResolveCommand::disableNameResolverCheck
-(const SharedHandle<AsyncNameResolver>& resolver)
-{
-  e_->deleteNameResolverCheck(resolver, this);
-}
 #endif // ENABLE_ASYNC_DNS
 
 void DHTEntryPointNameResolveCommand::setBootstrapEnabled(bool f)

+ 4 - 9
src/DHTEntryPointNameResolveCommand.h

@@ -52,7 +52,7 @@ class DHTRoutingTable;
 class DHTNode;
 class DownloadEngine;
 #ifdef ENABLE_ASYNC_DNS
-class AsyncNameResolver;
+class AsyncNameResolverMan;
 #endif // ENABLE_ASYNC_DNS
 
 class DHTEntryPointNameResolveCommand:public Command {
@@ -60,7 +60,7 @@ private:
   DownloadEngine* e_;
 
 #ifdef ENABLE_ASYNC_DNS
-  SharedHandle<AsyncNameResolver> resolver_;
+  SharedHandle<AsyncNameResolverMan> asyncNameResolverMan_;
 #endif // ENABLE_ASYNC_DNS
 
   SharedHandle<DHTTaskQueue> taskQueue_;
@@ -73,19 +73,14 @@ private:
 
   std::deque<std::pair<std::string, uint16_t> > entryPoints_;
 
-  std::vector<std::pair<std::string, uint16_t> > resolvedEntryPoints_;
+  int numSuccess_;
 
   bool bootstrapEnabled_;
 
   void addPingTask(const std::pair<std::string, uint16_t>& addr);
 
 #ifdef ENABLE_ASYNC_DNS
-  bool resolveHostname(const std::string& hostname,
-                       const SharedHandle<AsyncNameResolver>& resolver);
-
-  void setNameResolverCheck(const SharedHandle<AsyncNameResolver>& resolver);
-
-  void disableNameResolverCheck(const SharedHandle<AsyncNameResolver>& resolver);
+  bool resolveHostname(const std::string& hostname);
 #endif // ENABLE_ASYNC_DNS
 
 public: