[package] add gcc-4.4.0 related fixes from #5118
[openwrt/svn-archive/archive.git] / libs / libtorrent / patches / 010-fix-dht_get_peers_crash.patch
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)
7 @@ -335,36 +335,44 @@
8 m_repliesReceived++;
9 m_networkUp = true;
10
11 - DhtTransaction* transaction = itr->second;
12 + // Make sure transaction is erased even if an exception is thrown.
13 + try {
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.");
20 #endif
21
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))
25 - return;
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))
29 + return;
30
31 - const Object& response = request.get_key("r");
32 + const Object& response = request.get_key("r");
33
34 - switch (transaction->type()) {
35 - case DhtTransaction::DHT_FIND_NODE:
36 - parse_find_node_reply(transaction->as_find_node(), response.get_key_string("nodes"));
37 - break;
38 + switch (transaction->type()) {
39 + case DhtTransaction::DHT_FIND_NODE:
40 + parse_find_node_reply(transaction->as_find_node(), response.get_key_string("nodes"));
41 + break;
42
43 - case DhtTransaction::DHT_GET_PEERS:
44 - parse_get_peers_reply(transaction->as_get_peers(), response);
45 - break;
46 + case DhtTransaction::DHT_GET_PEERS:
47 + parse_get_peers_reply(transaction->as_get_peers(), response);
48 + break;
49
50 - // Nothing to do for DHT_PING and DHT_ANNOUNCE_PEER
51 - default:
52 - break;
53 + // Nothing to do for DHT_PING and DHT_ANNOUNCE_PEER
54 + default:
55 + break;
56 + }
57 +
58 + // Mark node responsive only if all processing was successful, without errors.
59 + m_router->node_replied(id, sa);
60 +
61 + } catch (std::exception& e) {
62 + delete itr->second;
63 + m_transactions.erase(itr);
64 + throw;
65 }
66
67 - // Mark node responsive only if all processing was successful, without errors.
68 - m_router->node_replied(id, sa);
69 -
70 delete itr->second;
71 m_transactions.erase(itr);
72 }
73 @@ -611,7 +619,17 @@
74 else
75 transaction->as_find_node()->complete(false);
76
77 - find_node_next(transaction->as_find_node());
78 + try {
79 + find_node_next(transaction->as_find_node());
80 +
81 + } catch (std::exception& e) {
82 + if (!quick) {
83 + delete itr->second;
84 + m_transactions.erase(itr);
85 + }
86 +
87 + throw;
88 + }
89 }
90
91 if (quick) {