diff --git a/ChangeLog b/ChangeLog index 6cc38d59..a481ca04 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2008-03-09 Tatsuhiro Tsujikawa + + Rewritten the functions for binding port. + * src/DHTConnectionImpl.{h, cc} + * src/PeerListenCommand.{h, cc} + * src/DHTSetup.cc + * src/BtSetup.cc + * test/DHTConnectionImplTest.cc + 2008-03-09 Tatsuhiro Tsujikawa type cleanup for allmost all remaining files. diff --git a/src/BtSetup.cc b/src/BtSetup.cc index c1eea18c..3dc7fc1a 100644 --- a/src/BtSetup.cc +++ b/src/BtSetup.cc @@ -115,13 +115,13 @@ Commands BtSetup::setup(RequestGroup* requestGroup, if(PeerListenCommand::getNumInstance() == 0) { PeerListenCommand* listenCommand = PeerListenCommand::getInstance(e); IntSequence seq = Util::parseIntRange(option->get(PREF_LISTEN_PORT)); - int32_t port = listenCommand->bindPort(seq); - if(port == -1) { - _logger->error(_("Errors occurred while binding port.\n")); - delete listenCommand; - } else { + uint16_t port; + if(listenCommand->bindPort(port, seq)) { BT_RUNTIME(btContext)->setListenPort(port); commands.push_back(listenCommand); + } else { + _logger->error(_("Errors occurred while binding port.\n")); + delete listenCommand; } } diff --git a/src/DHTConnectionImpl.cc b/src/DHTConnectionImpl.cc index ece6e2ae..3e0036c5 100644 --- a/src/DHTConnectionImpl.cc +++ b/src/DHTConnectionImpl.cc @@ -47,30 +47,35 @@ DHTConnectionImpl::DHTConnectionImpl():_socket(new SocketCore(SOCK_DGRAM)), DHTConnectionImpl::~DHTConnectionImpl() {} -uint16_t DHTConnectionImpl::bind(IntSequence& ports) +bool DHTConnectionImpl::bind(uint16_t& port, IntSequence& ports) { while(ports.hasNext()) { - uint16_t port = bind(ports.next()); - if(port > 0) { - return port; + int sport = ports.next(); + if(!(0 < sport && 0 <= UINT16_MAX)) { + continue; + } + port = sport; + if(bind(port)) { + return true; } } - return 0; + return false; } -uint16_t DHTConnectionImpl::bind(uint16_t port) +bool DHTConnectionImpl::bind(uint16_t& port) { try { _socket->bind(port); std::pair svaddr; _socket->getAddrInfo(svaddr); + port = svaddr.second; _logger->info("Bind socket for DHT. port=%u", port); - return svaddr.second; + return true; } catch(RecoverableException* e) { _logger->error("Failed to bind for DHT. port=%u", e, port); delete e; } - return 0; + return false; } ssize_t DHTConnectionImpl::receiveMessage(unsigned char* data, size_t len, std::string& host, uint16_t& port) diff --git a/src/DHTConnectionImpl.h b/src/DHTConnectionImpl.h index ecd484d6..7e3f94a5 100644 --- a/src/DHTConnectionImpl.h +++ b/src/DHTConnectionImpl.h @@ -54,9 +54,22 @@ public: virtual ~DHTConnectionImpl(); - uint16_t bind(IntSequence& ports); + /** + * Binds port. All number in ports are tried. + * If successful, the binded port is assigned to port and returns true. + * Otherwise return false and port is undefined in this case. + */ + bool bind(uint16_t& port, IntSequence& ports); - uint16_t bind(uint16_t port); + /** + * Binds port. The port number specified by port is used to bind. + * If successful, the binded port is assigned to port and returns true. + * Otherwise return false and port is undefined in this case. + * + * If you want to bind arbitrary port, give 0 as port and if successful, + * the binded port is assigned to port. + */ + bool bind(uint16_t& port); virtual ssize_t receiveMessage(unsigned char* data, size_t len, std::string& host, uint16_t& port); diff --git a/src/DHTSetup.cc b/src/DHTSetup.cc index 78a3bab4..85831dad 100644 --- a/src/DHTSetup.cc +++ b/src/DHTSetup.cc @@ -105,8 +105,8 @@ Commands DHTSetup::setup(DownloadEngine* e, const Option* option) SharedHandle connection = new DHTConnectionImpl(); { IntSequence seq = Util::parseIntRange(option->get(PREF_DHT_LISTEN_PORT)); - uint16_t port = connection->bind(seq); - if(port == 0) { + uint16_t port; + if(!connection->bind(port, seq)) { throw new DlAbortEx("Error occurred while binding port for DHT"); } localNode->setPort(port); diff --git a/src/PeerListenCommand.cc b/src/PeerListenCommand.cc index da666c8b..9403bffc 100644 --- a/src/PeerListenCommand.cc +++ b/src/PeerListenCommand.cc @@ -63,25 +63,27 @@ PeerListenCommand::~PeerListenCommand() --__numInstance; } -int32_t PeerListenCommand::bindPort(IntSequence& seq) +bool PeerListenCommand::bindPort(uint16_t& port, IntSequence& seq) { while(seq.hasNext()) { - int32_t port = seq.next(); + int sport = seq.next(); + if(!(0 < sport && sport <= UINT16_MAX)) { + continue; + } + port = sport; try { socket->bind(port); socket->beginListen(); socket->setNonBlockingMode(); - logger->info(MSG_LISTENING_PORT, - cuid, port); - return port; + logger->info(MSG_LISTENING_PORT, cuid, port); + return true; } catch(RecoverableException* ex) { - logger->error(MSG_BIND_FAILURE, - ex, cuid, port); + logger->error(MSG_BIND_FAILURE, ex, cuid, port); socket->closeConnection(); delete ex; } } - return -1; + return false; } bool PeerListenCommand::execute() { diff --git a/src/PeerListenCommand.h b/src/PeerListenCommand.h index ff83a52c..d3480651 100644 --- a/src/PeerListenCommand.h +++ b/src/PeerListenCommand.h @@ -61,7 +61,11 @@ public: virtual bool execute(); - int32_t bindPort(IntSequence& seq); + /** + * Binds port. If successful, the binded port number is assinged to port and + * returns true, otherwise port is undefined and returns false. + */ + bool bindPort(uint16_t& port, IntSequence& seq); void setLowestSpeedLimit(unsigned int speed) { diff --git a/test/DHTConnectionImplTest.cc b/test/DHTConnectionImplTest.cc index a6f9cb6c..5c0c3f5c 100644 --- a/test/DHTConnectionImplTest.cc +++ b/test/DHTConnectionImplTest.cc @@ -25,9 +25,12 @@ void DHTConnectionImplTest::testWriteAndReadData() { try { DHTConnectionImpl con1; - /*uint16_t con1port =*/ con1.bind(0); + uint16_t con1port = 0; + CPPUNIT_ASSERT(con1.bind(con1port)); + DHTConnectionImpl con2; - uint16_t con2port = con2.bind(0); + uint16_t con2port = 0; + CPPUNIT_ASSERT(con2.bind(con2port)); std::string message1 = "hello world."; con1.sendMessage(reinterpret_cast(message1.c_str()), @@ -43,9 +46,10 @@ void DHTConnectionImplTest::testWriteAndReadData() std::string(&readbuffer[0], &readbuffer[rlength])); } } catch(Exception* e) { + std::string m = e->getMsg(); std::cerr << *e << std::endl; delete e; - CPPUNIT_FAIL("exception thrown"); + CPPUNIT_FAIL(m); } }