1 # Fixes a crash when parsing a malformed get_peers (or find_node) response throws
2 # an exception and fails to remove the corresponding transaction. Ticket #1622.
3 Index: libtorrent/src/dht/dht_server.cc
4 ===================================================================
5 --- libtorrent/src/dht/dht_server.cc (revision 1087)
6 +++ libtorrent/src/dht/dht_server.cc (working copy)
11 - DhtTransaction* transaction = itr->second;
12 + // Make sure transaction is erased even if an exception is thrown.
14 + DhtTransaction* transaction = itr->second;
15 #ifdef USE_EXTRA_DEBUG
16 - if (DhtTransaction::key(sa, transactionId) != transaction->key(transactionId))
17 - throw internal_error("DhtServer::process_response key mismatch.");
18 + if (DhtTransaction::key(sa, transactionId) != transaction->key(transactionId))
19 + throw internal_error("DhtServer::process_response key mismatch.");
22 - // If we contact a node but its ID is not the one we expect, ignore the reply
23 - // to prevent interference from rogue nodes.
24 - if ((id != transaction->id() && transaction->id() != m_router->zero_id))
26 + // If we contact a node but its ID is not the one we expect, ignore the reply
27 + // to prevent interference from rogue nodes.
28 + if ((id != transaction->id() && transaction->id() != m_router->zero_id))
31 - const Object& response = request.get_key("r");
32 + const Object& response = request.get_key("r");
34 - switch (transaction->type()) {
35 - case DhtTransaction::DHT_FIND_NODE:
36 - parse_find_node_reply(transaction->as_find_node(), response.get_key_string("nodes"));
38 + switch (transaction->type()) {
39 + case DhtTransaction::DHT_FIND_NODE:
40 + parse_find_node_reply(transaction->as_find_node(), response.get_key_string("nodes"));
43 - case DhtTransaction::DHT_GET_PEERS:
44 - parse_get_peers_reply(transaction->as_get_peers(), response);
46 + case DhtTransaction::DHT_GET_PEERS:
47 + parse_get_peers_reply(transaction->as_get_peers(), response);
50 - // Nothing to do for DHT_PING and DHT_ANNOUNCE_PEER
53 + // Nothing to do for DHT_PING and DHT_ANNOUNCE_PEER
58 + // Mark node responsive only if all processing was successful, without errors.
59 + m_router->node_replied(id, sa);
61 + } catch (std::exception& e) {
63 + m_transactions.erase(itr);
67 - // Mark node responsive only if all processing was successful, without errors.
68 - m_router->node_replied(id, sa);
71 m_transactions.erase(itr);
75 transaction->as_find_node()->complete(false);
77 - find_node_next(transaction->as_find_node());
79 + find_node_next(transaction->as_find_node());
81 + } catch (std::exception& e) {
84 + m_transactions.erase(itr);