Commit 6cd3fd38 authored by rakshasa's avatar rakshasa

Fixed dht when bind address is not bound while using IPv6.

parent 9204c700
......@@ -82,6 +82,8 @@ public:
bool is_bindable() const;
bool is_address_any() const;
bool is_valid_inet_class() const { return family() == af_inet || family() == af_inet6; }
// Should we need to set AF_UNSPEC?
void clear() { std::memset(this, 0, sizeof(socket_address)); set_family(); }
......@@ -339,11 +341,10 @@ socket_address::pretty_address_str() const {
return sa_inet()->address_str();
case af_inet6:
return sa_inet6()->address_str();
case af_unspec:
return std::string("unspec");
default:
if (port() == 0)
return std::string("no family");
else
return std::string("no family with port");
return std::string("invalid");
}
}
......
......@@ -43,6 +43,8 @@
#include "torrent/dht_manager.h"
#include "torrent/download_info.h"
#include "torrent/exceptions.h"
#include "torrent/utils/log.h"
#include "utils/sha1.h"
#include "manager.h"
......@@ -52,7 +54,7 @@
#include "dht_transaction.h"
#define LT_LOG_THIS(log_fmt, ...) \
lt_log_print_subsystem(torrent::LOG_DHT_ROUTER, "dht_router", log_fmt, __VA_ARGS__);
lt_log_print_hash(torrent::LOG_DHT_ROUTER, this->id(), "dht_router", log_fmt, __VA_ARGS__);
namespace torrent {
......@@ -91,12 +93,16 @@ DhtRouter::DhtRouter(const Object& cache, const rak::socket_address* sa) :
sha.final_c(data());
}
LT_LOG_THIS("creating (address:%s)", sa->pretty_address_str().c_str());
set_bucket(new DhtBucket(zero_id, ones_id));
m_routingTable.insert(std::make_pair(bucket()->id_range_end(), bucket()));
if (cache.has_key("nodes")) {
const Object::map_type& nodes = cache.get_key_map("nodes");
LT_LOG_THIS("adding nodes (size:%zu)", nodes.size());
for (Object::map_type::const_iterator itr = nodes.begin(); itr != nodes.end(); ++itr) {
if (itr->first.length() != HashString::size_data)
throw bencode_error("Loading cache: Invalid node hash.");
......@@ -137,6 +143,8 @@ DhtRouter::~DhtRouter() {
void
DhtRouter::start(int port) {
LT_LOG_THIS("starting (port:%d)", port);
m_server.start(port);
// Set timeout slot and schedule it to be called immediately for initial bootstrapping if necessary.
......
......@@ -49,6 +49,7 @@
#include "torrent/poll.h"
#include "torrent/object_static_map.h"
#include "torrent/throttle.h"
#include "torrent/utils/log.h"
#include "tracker/tracker_dht.h"
#include "dht_bucket.h"
......@@ -57,6 +58,9 @@
#include "manager.h"
#define LT_LOG_THIS(log_fmt, ...) \
lt_log_print_subsystem(torrent::LOG_DHT_SERVER, "dht_server", log_fmt, __VA_ARGS__);
namespace torrent {
const char* DhtServer::queries[] = {
......@@ -144,8 +148,15 @@ DhtServer::start(int port) {
throw resource_error("Could not set listening port to reuse address.");
rak::socket_address sa = *m_router->address();
if (sa.family() == rak::socket_address::af_unspec)
sa.sa_inet6()->clear();
sa.set_port(port);
LT_LOG_THIS("starting (address:%s)", sa.pretty_address_str().c_str());
// Figure out how to bind to both inet and inet6.
if (!get_fd().bind(sa))
throw resource_error("Could not bind datagram socket.");
......@@ -173,6 +184,8 @@ DhtServer::stop() {
if (!is_active())
return;
LT_LOG_THIS("stopping", 0);
clear_transactions();
priority_queue_erase(&taskScheduler, &m_taskTimeout);
......
......@@ -84,6 +84,17 @@ SocketFd::set_reuse_address(bool state) {
return setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) == 0;
}
bool
SocketFd::set_ipv6_v6only(bool state) {
check_valid();
if (!m_ipv6_socket)
return false;
int opt = state;
return setsockopt(m_fd, IPPROTO_IPV6, IPV6_V6ONLY, &opt, sizeof(opt)) == 0;
}
bool
SocketFd::set_send_buffer_size(uint32_t s) {
check_valid();
......@@ -124,8 +135,12 @@ SocketFd::open_stream() {
m_ipv6_socket = true;
int zero = 0;
return setsockopt(m_fd, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero)) != -1;
if (!set_ipv6_v6only(false)) {
close();
return false;
}
return true;
}
bool
......@@ -139,8 +154,12 @@ SocketFd::open_datagram() {
m_ipv6_socket = true;
int zero = 0;
return setsockopt(m_fd, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(zero)) != -1;
if (!set_ipv6_v6only(false)) {
close();
return false;
}
return true;
}
bool
......
......@@ -59,6 +59,7 @@ public:
bool set_nonblock();
bool set_reuse_address(bool state);
bool set_ipv6_v6only(bool state);
bool set_priority(priority_type p);
......
......@@ -71,20 +71,32 @@ DhtManager::initialize(const Object& dhtCache) {
}
}
void
bool
DhtManager::start(port_type port) {
LT_LOG_THIS("starting (port:%d)", port);
if (m_router == NULL)
throw internal_error("DhtManager::start called without initializing first.");
m_port = port;
m_router->start(port);
}
try {
m_router->start(port);
} catch (torrent::local_error& e) {
LT_LOG_THIS("start failed (error:%s)", e.what());
return false;
}
return true;
}
void
DhtManager::stop() {
if (m_router != NULL)
m_router->stop();
if (m_router == NULL)
return;
LT_LOG_THIS("stopping", 0);
m_router->stop();
}
bool
......
......@@ -82,7 +82,7 @@ public:
void initialize(const Object& dhtCache);
void start(port_type port);
bool start(port_type port);
void stop();
// Store DHT cache in the given container and return the container.
......
......@@ -251,6 +251,7 @@ log_initialize() {
LOG_LINK(LOG_DHT_ALL, LOG_DHT_MANAGER);
LOG_LINK(LOG_DHT_ALL, LOG_DHT_NODE);
LOG_LINK(LOG_DHT_ALL, LOG_DHT_ROUTER);
LOG_LINK(LOG_DHT_ALL, LOG_DHT_SERVER);
std::sort(log_children.begin(), log_children.end());
......
......@@ -117,6 +117,7 @@ enum {
LOG_DHT_MANAGER,
LOG_DHT_NODE,
LOG_DHT_ROUTER,
LOG_DHT_SERVER,
LOG_INSTRUMENTATION_MEMORY,
LOG_INSTRUMENTATION_MINCORE,
......
......@@ -192,6 +192,9 @@ const char* option_list_log_group[] = {
"dht_all",
"dht_manager",
"dht_node",
"dht_router",
"dht_server",
"instrumentation_memory",
"instrumentation_mincore",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment