Skip to content

Commit

Permalink
another fix to receiving malformed DHT error message
Browse files Browse the repository at this point in the history
  • Loading branch information
arvidn committed Dec 3, 2015
1 parent 8f0e61e commit 8732863
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/kademlia/rpc_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ bool rpc_manager::incoming(msg const& m, node_id* id)
{
// It's an error.
#ifndef TORRENT_DISABLE_LOGGING
bdecode_node err = m.message.dict_find("e");
bdecode_node err = m.message.dict_find_list("e");
if (err && err.list_size() >= 2
&& err.list_at(0).type() == bdecode_node::int_t
&& err.list_at(1).type() == bdecode_node::string_t)
Expand Down
8 changes: 4 additions & 4 deletions src/web_peer_connection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ web_peer_connection::web_peer_connection(peer_connection_args const& pack
if (!web.supports_keepalive) preferred_size *= 4;

prefer_contiguous_blocks((std::max)(preferred_size / tor->block_size(), 1));

// we want large blocks as well, so
// we can request more bytes at once
// this setting will merge adjacent requests
Expand Down Expand Up @@ -196,7 +196,7 @@ void web_peer_connection::disconnect(error_code const& ec
peer_connection::disconnect(ec, op, error);
if (t) t->disconnect_web_seed(this);
}

boost::optional<piece_block_progress>
web_peer_connection::downloading_piece_progress() const
{
Expand Down Expand Up @@ -948,7 +948,7 @@ void web_peer_connection::on_receive(error_code const& error
// block from the http receive buffer and then
// (if it completed) call incoming_piece() with
// m_piece as buffer.

int piece_size = int(m_piece.size());
int copy_size = (std::min)((std::min)(front_request.length - piece_size
, recv_buffer.left()), int(range_end - range_start - m_received_body));
Expand Down Expand Up @@ -1061,7 +1061,7 @@ void web_peer_connection::on_receive(error_code const& error
m_received_body = 0;
m_chunk_pos = 0;
m_partial_chunk_header = 0;

if (!t->need_loaded())
{
disconnect(errors::torrent_aborted, op_bittorrent);
Expand Down
67 changes: 64 additions & 3 deletions test/test_dht.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2397,14 +2397,75 @@ TORRENT_TEST(invalid_error_msg)
bool found = false;
for (int i = 0; i < int(observer.m_log.size()); ++i)
{
if (observer.m_log[i].find("INCOMING ERROR")
&& observer.m_log[i].find("(malformed)"))
if (observer.m_log[i].find("INCOMING ERROR") != std::string::npos
&& observer.m_log[i].find("(malformed)") != std::string::npos)
found = true;

printf("%s\n", observer.m_log[i].c_str());
}

TEST_EQUAL(found, false);
TEST_EQUAL(found, true);
}

TORRENT_TEST(rpc_invalid_error_msg)
{
dht_settings sett = test_settings();
mock_socket s;
obs observer;
counters cnt;

dht::routing_table table(node_id(), 8, sett, &observer);
dht::rpc_manager rpc(node_id(), sett, table, &s, &observer);
dht::node node(&s, sett, node_id(0), &observer, cnt);

udp::endpoint source(address::from_string("10.0.0.1"), 20);

// we need this to create an entry for this transaction ID, otherwise the
// incoming message will just be dropped
entry req;
req["y"] = "q";
req["q"] = "bogus_query";
req["t"] = "\0\0\0\0";

g_sent_packets.clear();
boost::intrusive_ptr<traversal_algorithm> algo(new dht::traversal_algorithm(
node, node_id()));

observer_ptr o(new (rpc.allocate_observer()) null_observer(algo, source, node_id()));
#if defined TORRENT_DEBUG || defined TORRENT_RELEASE_ASSERTS
o->m_in_constructor = false;
#endif
rpc.invoke(req, source, o);

// here's the incoming (malformed) error message
entry err;
err["y"] = "e";
err["e"].string() = "Malformed Error";
err["t"] = g_sent_packets.begin()->second["t"].string();
char msg_buf[1500];
int size = bencode(msg_buf, err);

bdecode_node decoded;
error_code ec;
bdecode(msg_buf, msg_buf + size, decoded, ec);
if (ec) fprintf(stderr, "bdecode failed: %s\n", ec.message().c_str());

dht::msg m(decoded, source);
node_id nid;
rpc.incoming(m, &nid);

bool found = false;
for (int i = 0; i < int(observer.m_log.size()); ++i)
{
if (observer.m_log[i].find("reply with") != std::string::npos
&& observer.m_log[i].find("(malformed)") != std::string::npos
&& observer.m_log[i].find("error") != std::string::npos)
found = true;

printf("%s\n", observer.m_log[i].c_str());
}

TEST_EQUAL(found, true);
}

#endif
Expand Down

0 comments on commit 8732863

Please sign in to comment.