packages/libs/libtorrent/patches/010-fix-dht_get_peers_crash.patch
florian 5c19185c8d [package] add gcc-4.4.0 related fixes from #5118
git-svn-id: svn://svn.openwrt.org/openwrt/packages@15907 3c298f89-4303-0410-b956-a3cf2f4a3e73
2009-05-18 09:13:58 +00:00

92 lines
3.0 KiB
Diff

# 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) {