2006-08-01 17:27:08 +02:00
|
|
|
/*
|
|
|
|
|
2018-04-09 09:04:33 +02:00
|
|
|
Copyright (c) 2006-2018, Arvid Norberg & Daniel Wallin
|
2006-08-01 17:27:08 +02:00
|
|
|
All rights reserved.
|
|
|
|
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
|
|
modification, are permitted provided that the following conditions
|
|
|
|
are met:
|
|
|
|
|
|
|
|
* Redistributions of source code must retain the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer.
|
|
|
|
* Redistributions in binary form must reproduce the above copyright
|
|
|
|
notice, this list of conditions and the following disclaimer in
|
|
|
|
the documentation and/or other materials provided with the distribution.
|
|
|
|
* Neither the name of the author nor the names of its
|
|
|
|
contributors may be used to endorse or promote products derived
|
|
|
|
from this software without specific prior written permission.
|
|
|
|
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
|
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <libtorrent/kademlia/find_data.hpp>
|
2008-09-20 19:42:25 +02:00
|
|
|
#include <libtorrent/kademlia/node.hpp>
|
2015-05-10 06:54:02 +02:00
|
|
|
#include <libtorrent/kademlia/dht_observer.hpp>
|
2006-08-01 17:27:08 +02:00
|
|
|
#include <libtorrent/io.hpp>
|
2008-05-03 18:05:42 +02:00
|
|
|
#include <libtorrent/socket.hpp>
|
2009-09-20 02:23:36 +02:00
|
|
|
#include <libtorrent/socket_io.hpp>
|
2016-05-23 14:15:39 +02:00
|
|
|
|
|
|
|
#ifndef TORRENT_DISABLE_LOGGING
|
2016-06-04 16:01:43 +02:00
|
|
|
#include <libtorrent/hex.hpp> // to_hex
|
2016-05-23 14:15:39 +02:00
|
|
|
#endif
|
|
|
|
|
2017-04-12 19:00:57 +02:00
|
|
|
namespace libtorrent { namespace dht {
|
2006-08-01 17:27:08 +02:00
|
|
|
|
|
|
|
void find_data_observer::reply(msg const& m)
|
|
|
|
{
|
2017-05-29 18:20:52 +02:00
|
|
|
bdecode_node const r = m.message.dict_find_dict("r");
|
2009-09-20 02:23:36 +02:00
|
|
|
if (!r)
|
|
|
|
{
|
2015-05-16 21:29:49 +02:00
|
|
|
#ifndef TORRENT_DISABLE_LOGGING
|
2016-12-27 16:12:57 +01:00
|
|
|
get_observer()->log(dht_logger::traversal, "[%u] missing response dict"
|
|
|
|
, algorithm()->id());
|
2009-09-20 02:23:36 +02:00
|
|
|
#endif
|
2015-09-01 04:37:46 +02:00
|
|
|
timeout();
|
2009-09-20 02:23:36 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-02-27 21:52:46 +01:00
|
|
|
bdecode_node const id = r.dict_find_string("id");
|
2015-03-12 06:20:12 +01:00
|
|
|
if (!id || id.string_length() != 20)
|
2009-09-20 02:23:36 +02:00
|
|
|
{
|
2015-05-16 21:29:49 +02:00
|
|
|
#ifndef TORRENT_DISABLE_LOGGING
|
2016-12-27 16:12:57 +01:00
|
|
|
get_observer()->log(dht_logger::traversal, "[%u] invalid id in response"
|
|
|
|
, algorithm()->id());
|
2009-09-20 02:23:36 +02:00
|
|
|
#endif
|
2015-09-01 04:37:46 +02:00
|
|
|
timeout();
|
2009-09-20 02:23:36 +02:00
|
|
|
return;
|
|
|
|
}
|
2017-02-27 21:52:46 +01:00
|
|
|
bdecode_node const token = r.dict_find_string("token");
|
2009-09-20 02:23:36 +02:00
|
|
|
if (token)
|
|
|
|
{
|
2015-05-22 04:42:26 +02:00
|
|
|
static_cast<find_data*>(algorithm())->got_write_token(
|
2016-08-13 13:04:53 +02:00
|
|
|
node_id(id.string_ptr()), token.string_value().to_string());
|
2009-09-20 02:23:36 +02:00
|
|
|
}
|
|
|
|
|
2013-12-15 00:25:38 +01:00
|
|
|
traversal_observer::reply(m);
|
2009-10-07 22:51:02 +02:00
|
|
|
done();
|
2006-08-01 17:27:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
find_data::find_data(
|
2015-05-09 21:00:22 +02:00
|
|
|
node& dht_node
|
2016-09-11 07:58:48 +02:00
|
|
|
, node_id const& target
|
2013-12-27 05:28:25 +01:00
|
|
|
, nodes_callback const& ncallback)
|
2015-05-09 21:00:22 +02:00
|
|
|
: traversal_algorithm(dht_node, target)
|
2008-12-23 21:04:12 +01:00
|
|
|
, m_nodes_callback(ncallback)
|
2006-08-01 17:27:08 +02:00
|
|
|
, m_done(false)
|
|
|
|
{
|
2013-09-09 09:08:02 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void find_data::start()
|
|
|
|
{
|
2015-09-23 19:21:41 +02:00
|
|
|
// if the user didn't add seed-nodes manually, grab k (bucket size)
|
|
|
|
// nodes from routing table.
|
2013-09-09 09:08:02 +02:00
|
|
|
if (m_results.empty())
|
2015-09-23 19:21:41 +02:00
|
|
|
{
|
|
|
|
std::vector<node_entry> nodes;
|
2016-10-14 14:03:09 +02:00
|
|
|
m_node.m_table.find_node(target(), nodes, routing_table::include_failed);
|
2015-09-23 19:21:41 +02:00
|
|
|
|
2016-09-12 02:49:15 +02:00
|
|
|
for (auto const& n : nodes)
|
2015-09-23 19:21:41 +02:00
|
|
|
{
|
2016-09-12 02:49:15 +02:00
|
|
|
add_entry(n.id, n.ep(), observer::flag_initial);
|
2015-09-23 19:21:41 +02:00
|
|
|
}
|
|
|
|
}
|
2013-09-09 09:08:02 +02:00
|
|
|
|
|
|
|
traversal_algorithm::start();
|
2006-08-01 17:27:08 +02:00
|
|
|
}
|
|
|
|
|
2016-08-13 13:04:53 +02:00
|
|
|
void find_data::got_write_token(node_id const& n, std::string write_token)
|
2014-02-28 05:02:48 +01:00
|
|
|
{
|
2015-05-16 21:29:49 +02:00
|
|
|
#ifndef TORRENT_DISABLE_LOGGING
|
2016-09-12 02:49:15 +02:00
|
|
|
auto logger = get_node().observer();
|
|
|
|
if (logger != nullptr && logger->should_log(dht_logger::traversal))
|
2016-09-12 15:20:15 +02:00
|
|
|
{
|
2016-09-12 02:49:15 +02:00
|
|
|
logger->log(dht_logger::traversal
|
2016-12-27 16:12:57 +01:00
|
|
|
, "[%u] adding write token '%s' under id '%s'"
|
|
|
|
, id(), aux::to_hex(write_token).c_str()
|
2016-09-12 02:49:15 +02:00
|
|
|
, aux::to_hex(n).c_str());
|
2016-09-12 15:20:15 +02:00
|
|
|
}
|
2014-02-28 05:02:48 +01:00
|
|
|
#endif
|
2016-08-13 13:04:53 +02:00
|
|
|
m_write_tokens[n] = std::move(write_token);
|
2014-02-28 05:02:48 +01:00
|
|
|
}
|
|
|
|
|
2016-09-03 03:05:11 +02:00
|
|
|
observer_ptr find_data::new_observer(udp::endpoint const& ep
|
|
|
|
, node_id const& id)
|
2010-11-05 20:06:50 +01:00
|
|
|
{
|
2016-09-03 03:05:11 +02:00
|
|
|
auto o = m_node.m_rpc.allocate_observer<find_data_observer>(self(), ep, id);
|
2016-06-18 14:31:07 +02:00
|
|
|
#if TORRENT_USE_ASSERTS
|
2016-09-03 03:05:11 +02:00
|
|
|
if (o) o->m_in_constructor = false;
|
2010-11-05 20:06:50 +01:00
|
|
|
#endif
|
2019-06-02 19:26:49 +02:00
|
|
|
return o;
|
2010-11-05 20:06:50 +01:00
|
|
|
}
|
|
|
|
|
2013-12-27 05:28:25 +01:00
|
|
|
char const* find_data::name() const { return "find_data"; }
|
2006-08-01 17:27:08 +02:00
|
|
|
|
|
|
|
void find_data::done()
|
|
|
|
{
|
2009-10-07 22:51:02 +02:00
|
|
|
m_done = true;
|
|
|
|
|
2015-05-16 21:29:49 +02:00
|
|
|
#ifndef TORRENT_DISABLE_LOGGING
|
2016-09-12 02:49:15 +02:00
|
|
|
auto logger = get_node().observer();
|
|
|
|
if (logger != nullptr)
|
2016-09-12 15:20:15 +02:00
|
|
|
{
|
2016-12-27 16:12:57 +01:00
|
|
|
logger->log(dht_logger::traversal, "[%u] %s DONE"
|
|
|
|
, id(), name());
|
2016-09-12 15:20:15 +02:00
|
|
|
}
|
2010-11-05 20:06:50 +01:00
|
|
|
#endif
|
|
|
|
|
2016-09-12 15:20:15 +02:00
|
|
|
std::vector<std::pair<node_entry, std::string>> results;
|
2008-12-23 21:04:12 +01:00
|
|
|
int num_results = m_node.m_table.bucket_size();
|
2017-11-12 00:50:24 +01:00
|
|
|
for (auto i = m_results.begin()
|
2008-12-23 21:04:12 +01:00
|
|
|
, end(m_results.end()); i != end && num_results > 0; ++i)
|
|
|
|
{
|
2010-11-05 20:06:50 +01:00
|
|
|
observer_ptr const& o = *i;
|
2017-08-05 15:45:28 +02:00
|
|
|
if (!(o->flags & observer::flag_alive))
|
2014-02-28 05:02:48 +01:00
|
|
|
{
|
2015-05-16 21:29:49 +02:00
|
|
|
#ifndef TORRENT_DISABLE_LOGGING
|
2016-09-12 02:49:15 +02:00
|
|
|
if (logger != nullptr && logger->should_log(dht_logger::traversal))
|
2016-09-12 15:20:15 +02:00
|
|
|
{
|
2016-12-27 16:12:57 +01:00
|
|
|
logger->log(dht_logger::traversal, "[%u] not alive: %s"
|
|
|
|
, id(), print_endpoint(o->target_ep()).c_str());
|
2016-09-12 15:20:15 +02:00
|
|
|
}
|
2014-02-28 05:02:48 +01:00
|
|
|
#endif
|
|
|
|
continue;
|
|
|
|
}
|
2016-09-12 15:20:15 +02:00
|
|
|
auto j = m_write_tokens.find(o->id());
|
2014-02-28 05:02:48 +01:00
|
|
|
if (j == m_write_tokens.end())
|
|
|
|
{
|
2015-05-16 21:29:49 +02:00
|
|
|
#ifndef TORRENT_DISABLE_LOGGING
|
2016-09-12 02:49:15 +02:00
|
|
|
if (logger != nullptr && logger->should_log(dht_logger::traversal))
|
2016-09-12 15:20:15 +02:00
|
|
|
{
|
2016-12-27 16:12:57 +01:00
|
|
|
logger->log(dht_logger::traversal, "[%u] no write token: %s"
|
|
|
|
, id(), print_endpoint(o->target_ep()).c_str());
|
2016-09-12 15:20:15 +02:00
|
|
|
}
|
2014-02-28 05:02:48 +01:00
|
|
|
#endif
|
|
|
|
continue;
|
|
|
|
}
|
2017-11-12 00:50:24 +01:00
|
|
|
results.emplace_back(node_entry(o->id(), o->target_ep()), j->second);
|
2015-05-16 21:29:49 +02:00
|
|
|
#ifndef TORRENT_DISABLE_LOGGING
|
2016-09-12 02:49:15 +02:00
|
|
|
if (logger != nullptr && logger->should_log(dht_logger::traversal))
|
2016-09-12 15:20:15 +02:00
|
|
|
{
|
2016-12-27 16:12:57 +01:00
|
|
|
logger->log(dht_logger::traversal, "[%u] %s"
|
|
|
|
, id(), print_endpoint(o->target_ep()).c_str());
|
2016-09-12 15:20:15 +02:00
|
|
|
}
|
2014-02-28 05:02:48 +01:00
|
|
|
#endif
|
2008-12-23 21:04:12 +01:00
|
|
|
--num_results;
|
|
|
|
}
|
2014-02-28 05:02:48 +01:00
|
|
|
|
2013-12-27 05:28:25 +01:00
|
|
|
if (m_nodes_callback) m_nodes_callback(results);
|
2010-11-05 20:06:50 +01:00
|
|
|
|
|
|
|
traversal_algorithm::done();
|
2006-08-01 17:27:08 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
} } // namespace libtorrent::dht
|