Prechádzať zdrojové kódy

2010-08-14 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>

	Listen both IPv4 and IPv6 for BitTorrent protocol.
	* src/BtSetup.cc
	* src/PeerListenCommand.cc
	* src/PeerListenCommand.h
Tatsuhiro Tsujikawa 15 rokov pred
rodič
commit
8958b92d91
4 zmenil súbory, kde vykonal 62 pridanie a 19 odobranie
  1. 7 0
      ChangeLog
  2. 30 10
      src/BtSetup.cc
  3. 21 7
      src/PeerListenCommand.cc
  4. 4 2
      src/PeerListenCommand.h

+ 7 - 0
ChangeLog

@@ -1,3 +1,10 @@
+2010-08-14  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
+
+	Listen both IPv4 and IPv6 for BitTorrent protocol.
+	* src/BtSetup.cc
+	* src/PeerListenCommand.cc
+	* src/PeerListenCommand.h
+
 2010-08-14  Tatsuhiro Tsujikawa  <t-tujikawa@users.sourceforge.net>
 
 	Added debug log

+ 30 - 10
src/BtSetup.cc

@@ -83,6 +83,7 @@
 #include "CheckIntegrityEntry.h"
 #include "ServerStatMan.h"
 #include "DlAbortEx.h"
+#include "array_fun.h"
 
 namespace aria2 {
 
@@ -183,19 +184,38 @@ void BtSetup::setup(std::vector<Command*>& commands,
     }
   }
   if(PeerListenCommand::getNumInstance() == 0) {
-    PeerListenCommand* listenCommand = PeerListenCommand::getInstance(e);
-    IntSequence seq =util::parseIntRange(e->getOption()->get(PREF_LISTEN_PORT));
-    uint16_t port;
-    if(listenCommand->bindPort(port, seq)) {
-      btRuntime->setListenPort(port);
-      // Add command to DownloadEngine directly.
-      e->addCommand(listenCommand);
-    } else {
-      delete listenCommand;
+    static int families[] = { AF_INET, AF_INET6 };
+    for(size_t i = 0; i < A2_ARRAY_LEN(families); ++i) {
+      PeerListenCommand* listenCommand =
+        PeerListenCommand::getInstance(e, families[i]);
+      bool ret;
+      uint16_t port;
+      if(btRuntime->getListenPort()) {
+        IntSequence seq =
+          util::parseIntRange(util::uitos(btRuntime->getListenPort()));
+        ret = listenCommand->bindPort(port, seq);
+      } else {
+        IntSequence seq =
+          util::parseIntRange(e->getOption()->get(PREF_LISTEN_PORT));
+        ret = listenCommand->bindPort(port, seq);
+      }
+      if(ret) {
+        btRuntime->setListenPort(port);
+        // Add command to DownloadEngine directly.
+        e->addCommand(listenCommand);
+      } else {
+        delete listenCommand;
+      }
+    }
+    if(PeerListenCommand::getNumInstance() == 0) {
       throw DL_ABORT_EX(_("Errors occurred while binding port.\n"));
     }
   } else {
-    PeerListenCommand* listenCommand = PeerListenCommand::getInstance(e);
+    PeerListenCommand* listenCommand =
+      PeerListenCommand::getInstance(e, AF_INET);
+    if(!listenCommand) {
+      listenCommand = PeerListenCommand::getInstance(e, AF_INET6);
+    }
     btRuntime->setListenPort(listenCommand->getPort());
   }
   if(option->getAsBool(PREF_BT_ENABLE_LPD) &&

+ 21 - 7
src/PeerListenCommand.cc

@@ -58,9 +58,13 @@ unsigned int PeerListenCommand::numInstance_ = 0;
 
 PeerListenCommand* PeerListenCommand::instance_ = 0;
 
-PeerListenCommand::PeerListenCommand(cuid_t cuid, DownloadEngine* e):
+PeerListenCommand* PeerListenCommand::instance6_ = 0;
+
+PeerListenCommand::PeerListenCommand
+(cuid_t cuid, DownloadEngine* e, int family):
   Command(cuid),
   e_(e),
+  family_(family),
   lowestSpeedLimit_(20*1024)
 {
   ++numInstance_;
@@ -86,10 +90,11 @@ bool PeerListenCommand::bindPort(uint16_t& port, IntSequence& seq)
     }
     port = (*portItr);
     try {
-      socket_->bind(port);
+      socket_->bind(A2STR::NIL, port, family_);
       socket_->beginListen();
       socket_->setNonBlockingMode();
-      getLogger()->notice("BitTorrent: listening to port %d", port);
+      getLogger()->notice("IPv%d BitTorrent: listening to port %d",
+                          family_ == AF_INET?4:6, port);
       return true;
     } catch(RecoverableException& ex) {
       getLogger()->error(MSG_BIND_FAILURE, ex,
@@ -144,12 +149,21 @@ bool PeerListenCommand::execute() {
   return false;
 }
 
-PeerListenCommand* PeerListenCommand::getInstance(DownloadEngine* e)
+PeerListenCommand* PeerListenCommand::getInstance(DownloadEngine* e, int family)
 {
-  if(numInstance_ == 0) {
-    instance_ = new PeerListenCommand(e->newCUID(), e);
+  if(family == AF_INET) {
+    if(!instance_) {
+      instance_ = new PeerListenCommand(e->newCUID(), e, family);
+    }
+    return instance_;
+  } else if(family == AF_INET6) {
+    if(!instance6_) {
+      instance6_ = new PeerListenCommand(e->newCUID(), e, family);
+    }
+    return instance6_;
+  } else {
+    return 0;
   }
-  return instance_;
 }
 
 } // namespace aria2

+ 4 - 2
src/PeerListenCommand.h

@@ -47,6 +47,7 @@ class SocketCore;
 class PeerListenCommand : public Command {
 private:
   DownloadEngine* e_;
+  int family_;
   SharedHandle<SocketCore> socket_;
   unsigned int lowestSpeedLimit_;
 
@@ -54,8 +55,9 @@ private:
 
   static PeerListenCommand* instance_;
 
+  static PeerListenCommand* instance6_;
 public:
-  PeerListenCommand(cuid_t cuid, DownloadEngine* e);
+  PeerListenCommand(cuid_t cuid, DownloadEngine* e, int family);
 
   virtual ~PeerListenCommand();
   
@@ -75,7 +77,7 @@ public:
     lowestSpeedLimit_ = speed;
   }
 
-  static PeerListenCommand* getInstance(DownloadEngine* e);
+  static PeerListenCommand* getInstance(DownloadEngine* e, int family);
 
   static unsigned int getNumInstance()
   {