-# Fixes a crash when parsing a malformed get_peers (or find_node) response throws
-# an exception and fails to remove the corresponding transaction. Ticket #1622.
-Index: libtorrent/src/dht/dht_server.cc
-===================================================================
---- libtorrent/src/dht/dht_server.cc (revision 1087)
-+++ libtorrent/src/dht/dht_server.cc (working copy)
-@@ -335,36 +335,44 @@
- m_repliesReceived++;
- m_networkUp = true;
-
-- DhtTransaction* transaction = itr->second;
-+ // Make sure transaction is erased even if an exception is thrown.
-+ try {
-+ DhtTransaction* transaction = itr->second;
- #ifdef USE_EXTRA_DEBUG
-- if (DhtTransaction::key(sa, transactionId) != transaction->key(transactionId))
-- throw internal_error("DhtServer::process_response key mismatch.");
-+ if (DhtTransaction::key(sa, transactionId) != transaction->key(transactionId))
-+ throw internal_error("DhtServer::process_response key mismatch.");
- #endif
-
-- // If we contact a node but its ID is not the one we expect, ignore the reply
-- // to prevent interference from rogue nodes.
-- if ((id != transaction->id() && transaction->id() != m_router->zero_id))
-- return;
-+ // If we contact a node but its ID is not the one we expect, ignore the reply
-+ // to prevent interference from rogue nodes.
-+ if ((id != transaction->id() && transaction->id() != m_router->zero_id))
-+ return;
-
-- const Object& response = request.get_key("r");
-+ const Object& response = request.get_key("r");
-
-- switch (transaction->type()) {
-- case DhtTransaction::DHT_FIND_NODE:
-- parse_find_node_reply(transaction->as_find_node(), response.get_key_string("nodes"));
-- break;
-+ switch (transaction->type()) {
-+ case DhtTransaction::DHT_FIND_NODE:
-+ parse_find_node_reply(transaction->as_find_node(), response.get_key_string("nodes"));
-+ break;
-
-- case DhtTransaction::DHT_GET_PEERS:
-- parse_get_peers_reply(transaction->as_get_peers(), response);
-- break;
-+ case DhtTransaction::DHT_GET_PEERS:
-+ parse_get_peers_reply(transaction->as_get_peers(), response);
-+ break;
-
-- // Nothing to do for DHT_PING and DHT_ANNOUNCE_PEER
-- default:
-- break;
-+ // Nothing to do for DHT_PING and DHT_ANNOUNCE_PEER
-+ default:
-+ break;
-+ }
-+
-+ // Mark node responsive only if all processing was successful, without errors.
-+ m_router->node_replied(id, sa);
-+
-+ } catch (std::exception& e) {
-+ delete itr->second;
-+ m_transactions.erase(itr);
-+ throw;
- }
-
-- // Mark node responsive only if all processing was successful, without errors.
-- m_router->node_replied(id, sa);
--
- delete itr->second;
- m_transactions.erase(itr);
- }
-@@ -611,7 +619,17 @@
- else
- transaction->as_find_node()->complete(false);
-
-- find_node_next(transaction->as_find_node());
-+ try {
-+ find_node_next(transaction->as_find_node());
-+
-+ } catch (std::exception& e) {
-+ if (!quick) {
-+ delete itr->second;
-+ m_transactions.erase(itr);
-+ }
-+
-+ throw;
-+ }
- }
-
- if (quick) {