--- /dev/null
+# 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) {
--- /dev/null
+diff -urN libtorrent-0.12.4.orig/src/protocol/extensions.cc libtorrent-0.12.4/src/protocol/extensions.cc
+--- libtorrent-0.12.4.orig/src/protocol/extensions.cc 2009-05-01 11:21:41.646024324 +0000
++++ libtorrent-0.12.4/src/protocol/extensions.cc 2009-05-01 11:41:30.107790553 +0000
+@@ -39,6 +39,8 @@
+ #include <limits>
+ #include <sstream>
+
++#include <cstdio>
++
+ #include "download/available_list.h"
+ #include "download/download_main.h"
+ #include "protocol/peer_connection_base.h"
+diff -urN libtorrent-0.12.4.orig/src/torrent/poll_epoll.cc libtorrent-0.12.4/src/torrent/poll_epoll.cc
+--- libtorrent-0.12.4.orig/src/torrent/poll_epoll.cc 2009-05-01 11:21:41.656024827 +0000
++++ libtorrent-0.12.4/src/torrent/poll_epoll.cc 2009-05-01 11:40:31.152785407 +0000
+@@ -38,6 +38,7 @@
+
+ #include <cerrno>
+ #include <cstring>
++#include <cstdio>
+
+ #include <unistd.h>
+ #include <torrent/exceptions.h>
+diff -urN libtorrent-0.12.4.orig/src/tracker/tracker_dht.cc libtorrent-0.12.4/src/tracker/tracker_dht.cc
+--- libtorrent-0.12.4.orig/src/tracker/tracker_dht.cc 2009-05-01 11:21:41.658024592 +0000
++++ libtorrent-0.12.4/src/tracker/tracker_dht.cc 2009-05-01 11:41:43.124798870 +0000
+@@ -37,6 +37,7 @@
+ #include "config.h"
+
+ #include <sstream>
++#include <cstdio>
+
+ #include "dht/dht_router.h"
+ #include "torrent/connection_manager.h"
+diff -urN libtorrent-0.12.4.orig/src/tracker/tracker_udp.cc libtorrent-0.12.4/src/tracker/tracker_udp.cc
+--- libtorrent-0.12.4.orig/src/tracker/tracker_udp.cc 2009-05-01 11:21:41.658024592 +0000
++++ libtorrent-0.12.4/src/tracker/tracker_udp.cc 2009-05-01 11:39:57.184784529 +0000
+@@ -38,6 +38,7 @@
+
+ #include <sigc++/adaptors/bind.h>
+ #include <torrent/connection_manager.h>
++#include <cstdio>
+
+ #include "download/download_info.h"
+ #include "net/address_list.h"