Use same port number for IPv4 and IPv6 DHT

pull/50/merge
Tatsuhiro Tsujikawa 2013-02-25 23:04:12 +09:00
parent 33037982dc
commit 4ac4fdf1e9
2 changed files with 23 additions and 9 deletions

View File

@ -81,7 +81,8 @@ class BtRegistry {
private: private:
std::map<a2_gid_t, SharedHandle<BtObject> > pool_; std::map<a2_gid_t, SharedHandle<BtObject> > pool_;
uint16_t tcpPort_; uint16_t tcpPort_;
// This is IPv4 port for DHT and UDP tracker. No IPv6 udpPort atm. // This is UDP port for DHT and UDP tracker. But currently UDP
// tracker is not supported in IPv6.
uint16_t udpPort_; uint16_t udpPort_;
SharedHandle<LpdMessageReceiver> lpdMessageReceiver_; SharedHandle<LpdMessageReceiver> lpdMessageReceiver_;
SharedHandle<UDPTrackerClient> udpTrackerClient_; SharedHandle<UDPTrackerClient> udpTrackerClient_;

View File

@ -112,16 +112,27 @@ void DHTSetup::setup
localNode.reset(new DHTNode()); localNode.reset(new DHTNode());
} }
uint16_t port;
SharedHandle<DHTConnectionImpl> connection(new DHTConnectionImpl(family)); SharedHandle<DHTConnectionImpl> connection(new DHTConnectionImpl(family));
{ {
SegList<int> sgl; port = e->getBtRegistry()->getUdpPort();
util::parseIntSegments(sgl, e->getOption()->get(PREF_DHT_LISTEN_PORT));
sgl.normalize();
uint16_t port;
const std::string& addr = const std::string& addr =
e->getOption()->get(family == AF_INET?PREF_DHT_LISTEN_ADDR: e->getOption()->get(family == AF_INET ? PREF_DHT_LISTEN_ADDR:
PREF_DHT_LISTEN_ADDR6); PREF_DHT_LISTEN_ADDR6);
if(!connection->bind(port, addr, sgl)) { // If UDP port is already used, use the same port
// number. Normally IPv4 port is available, then IPv6 port is
// (especially for port >= 1024). We don't loose much by doing
// this. We did the same thing in TCP socket. See BtSetup.cc.
bool rv;
if(port == 0) {
SegList<int> sgl;
util::parseIntSegments(sgl, e->getOption()->get(PREF_DHT_LISTEN_PORT));
sgl.normalize();
rv = connection->bind(port, addr, sgl);
} else {
rv = connection->bind(port, addr);
}
if(!rv) {
throw DL_ABORT_EX("Error occurred while binding UDP port for DHT"); throw DL_ABORT_EX("Error occurred while binding UDP port for DHT");
} }
localNode->setPort(port); localNode->setPort(port);
@ -192,7 +203,6 @@ void DHTSetup::setup
DHTRegistry::getMutableData().messageReceiver = receiver; DHTRegistry::getMutableData().messageReceiver = receiver;
DHTRegistry::getMutableData().messageFactory = factory; DHTRegistry::getMutableData().messageFactory = factory;
e->getBtRegistry()->setUDPTrackerClient(udpTrackerClient); e->getBtRegistry()->setUDPTrackerClient(udpTrackerClient);
e->getBtRegistry()->setUdpPort(localNode->getPort());
} else { } else {
DHTRegistry::getMutableData6().localNode = localNode; DHTRegistry::getMutableData6().localNode = localNode;
DHTRegistry::getMutableData6().routingTable = routingTable; DHTRegistry::getMutableData6().routingTable = routingTable;
@ -290,6 +300,10 @@ void DHTSetup::setup
} }
commands.insert(commands.end(), tempCommands->begin(), tempCommands->end()); commands.insert(commands.end(), tempCommands->begin(), tempCommands->end());
tempCommands->clear(); tempCommands->clear();
if(e->getBtRegistry()->getUdpPort() == 0) {
// We assign port last so that no exception gets in the way
e->getBtRegistry()->setUdpPort(port);
}
} catch(RecoverableException& ex) { } catch(RecoverableException& ex) {
A2_LOG_ERROR_EX(fmt("Exception caught while initializing DHT functionality." A2_LOG_ERROR_EX(fmt("Exception caught while initializing DHT functionality."
" DHT is disabled."), " DHT is disabled."),
@ -298,7 +312,6 @@ void DHTSetup::setup
DHTRegistry::clearData(); DHTRegistry::clearData();
e->getBtRegistry()->setUDPTrackerClient e->getBtRegistry()->setUDPTrackerClient
(SharedHandle<UDPTrackerClient>()); (SharedHandle<UDPTrackerClient>());
e->getBtRegistry()->setUdpPort(0);
} else { } else {
DHTRegistry::clearData6(); DHTRegistry::clearData6();
} }