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
pull/1/head
Tatsuhiro Tsujikawa 2010-08-14 06:52:35 +00:00
parent 3d9bae9170
commit 8958b92d91
4 changed files with 62 additions and 19 deletions

View File

@ -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> 2010-08-14 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Added debug log Added debug log

View File

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

View File

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

View File

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