|
@@ -112,16 +112,27 @@ void DHTSetup::setup
|
|
|
localNode.reset(new DHTNode());
|
|
|
}
|
|
|
|
|
|
+ uint16_t port;
|
|
|
SharedHandle<DHTConnectionImpl> connection(new DHTConnectionImpl(family));
|
|
|
{
|
|
|
- SegList<int> sgl;
|
|
|
- util::parseIntSegments(sgl, e->getOption()->get(PREF_DHT_LISTEN_PORT));
|
|
|
- sgl.normalize();
|
|
|
- uint16_t port;
|
|
|
+ port = e->getBtRegistry()->getUdpPort();
|
|
|
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);
|
|
|
- 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");
|
|
|
}
|
|
|
localNode->setPort(port);
|
|
@@ -192,7 +203,6 @@ void DHTSetup::setup
|
|
|
DHTRegistry::getMutableData().messageReceiver = receiver;
|
|
|
DHTRegistry::getMutableData().messageFactory = factory;
|
|
|
e->getBtRegistry()->setUDPTrackerClient(udpTrackerClient);
|
|
|
- e->getBtRegistry()->setUdpPort(localNode->getPort());
|
|
|
} else {
|
|
|
DHTRegistry::getMutableData6().localNode = localNode;
|
|
|
DHTRegistry::getMutableData6().routingTable = routingTable;
|
|
@@ -290,6 +300,10 @@ void DHTSetup::setup
|
|
|
}
|
|
|
commands.insert(commands.end(), tempCommands->begin(), tempCommands->end());
|
|
|
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) {
|
|
|
A2_LOG_ERROR_EX(fmt("Exception caught while initializing DHT functionality."
|
|
|
" DHT is disabled."),
|
|
@@ -298,7 +312,6 @@ void DHTSetup::setup
|
|
|
DHTRegistry::clearData();
|
|
|
e->getBtRegistry()->setUDPTrackerClient
|
|
|
(SharedHandle<UDPTrackerClient>());
|
|
|
- e->getBtRegistry()->setUdpPort(0);
|
|
|
} else {
|
|
|
DHTRegistry::clearData6();
|
|
|
}
|