From 48b85ba586e1f53aa9a9de67c64fd90086e32915 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Thu, 12 Apr 2012 05:00:20 +0000 Subject: [PATCH] added more asserts in an attempt to track down invalid policy peer pointers in the piece picker. also fixed a web seed related crash when geoip support is enabled --- include/libtorrent/piece_picker.hpp | 4 ++++ src/peer_connection.cpp | 4 +++- src/piece_picker.cpp | 27 +++++++++++++++++++++++++++ src/torrent.cpp | 9 +++++++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/include/libtorrent/piece_picker.hpp b/include/libtorrent/piece_picker.hpp index 599b67b90..313a480d2 100644 --- a/include/libtorrent/piece_picker.hpp +++ b/include/libtorrent/piece_picker.hpp @@ -117,6 +117,10 @@ namespace libtorrent // the state of this block enum { state_none, state_requested, state_writing, state_finished }; unsigned state:2; +#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS + // to allow verifying the invariant of blocks belonging to the right piece + int piece_index; +#endif }; // the peers that are downloading this piece diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 61328f357..38451eb07 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -346,6 +346,7 @@ namespace libtorrent , m_holepunch_mode(false) , m_ignore_stats(false) , m_corked(false) + , m_has_metadata(true) #if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS , m_in_constructor(true) , m_disconnect_started(false) @@ -3869,13 +3870,14 @@ namespace libtorrent if (peer_info_struct()) { policy::peer* pi = peer_info_struct(); + TORRENT_ASSERT(pi->in_use); p.source = pi->source; p.failcount = pi->failcount; p.num_hashfails = pi->hashfails; p.flags |= pi->on_parole ? peer_info::on_parole : 0; p.flags |= pi->optimistically_unchoked ? peer_info::optimistic_unchoke : 0; #ifndef TORRENT_DISABLE_GEO_IP - p.inet_as = pi->inet_as->first; + p.inet_as = pi->inet_as ? pi->inet_as->first : 0xffff; #endif } else diff --git a/src/piece_picker.cpp b/src/piece_picker.cpp index 27335dc65..d71c7b9fe 100644 --- a/src/piece_picker.cpp +++ b/src/piece_picker.cpp @@ -189,6 +189,9 @@ namespace libtorrent ret.info[i].num_peers = 0; ret.info[i].state = block_info::state_none; ret.info[i].peer = 0; +#if defined TORRENT_DEBUG || TORRENT_RELEASE_ASSERTS + ret.info[i].piece_index = piece; +#endif } return ret; } @@ -304,6 +307,7 @@ namespace libtorrent int num_writing = 0; for (int k = 0; k < num_blocks; ++k) { + TORRENT_ASSERT(i->info[k].piece_index == i->index); if (i->info[k].state == block_info::state_finished) { ++num_finished; @@ -827,6 +831,7 @@ namespace libtorrent int num_blocks = blocks_in_piece(i->index); for (int k = 0; k < num_blocks; ++k) { + TORRENT_ASSERT(i->info[k].piece_index == index); TORRENT_ASSERT(i->info[k].state == block_info::state_finished); TORRENT_ASSERT(i->info[k].num_peers == 0); } @@ -1613,6 +1618,7 @@ namespace libtorrent for (int j = 0; j < num_blocks_in_piece; ++j) { block_info const& info = i->info[j]; + TORRENT_ASSERT(info.piece_index == i->index); if (info.state != block_info::state_requested || info.peer == peer) continue; @@ -1650,6 +1656,7 @@ namespace libtorrent for (int j = 0; j < num_blocks_in_piece; ++j) { block_info const& info = i->info[j]; + TORRENT_ASSERT(info.piece_index == i->index); if (info.state != block_info::state_none) continue; std::vector::iterator k = std::find( interesting_blocks.begin(), interesting_blocks.end() @@ -1695,6 +1702,7 @@ namespace libtorrent for (int j = 0; j < num_blocks_in_piece; ++j) { block_info const& info = k->info[j]; + TORRENT_ASSERT(info.piece_index == k->index); if (info.state == block_info::state_finished) continue; TORRENT_ASSERT(info.peer != 0); } @@ -1753,6 +1761,7 @@ namespace libtorrent for (int j = 0; j < num_blocks_in_piece; ++j) { piece_picker::block_info const& info = p.info[j]; + TORRENT_ASSERT(info.piece_index == p.index); if (info.state != piece_picker::block_info::state_none && info.peer != peer) { @@ -1882,6 +1891,7 @@ namespace libtorrent { // ignore completed blocks and already requested blocks block_info const& info = dp.info[j]; + TORRENT_ASSERT(info.piece_index == dp.index); if (info.state != block_info::state_none) continue; backup_blocks2.push_back(piece_block(dp.index, j)); } @@ -1892,6 +1902,7 @@ namespace libtorrent { // ignore completed blocks and already requested blocks block_info const& info = dp.info[j]; + TORRENT_ASSERT(info.piece_index == dp.index); if (info.state != block_info::state_none) continue; // if the piece is fast and the peer is slow, or vice versa, @@ -1985,6 +1996,7 @@ namespace libtorrent #ifdef TORRENT_DEBUG for (int k = 0; k < max_blocks; ++k) { + TORRENT_ASSERT(i->info[k].piece_index == index); TORRENT_ASSERT(i->info[k].state == block_info::state_finished || i->info[k].state == block_info::state_writing); } @@ -2033,6 +2045,7 @@ namespace libtorrent std::vector::const_iterator i = find_dl_piece(block.piece_index); TORRENT_ASSERT(i != m_downloads.end()); + TORRENT_ASSERT(i->info[block.block_index].piece_index == block.piece_index); return i->info[block.block_index].state == block_info::state_requested; } @@ -2046,6 +2059,7 @@ namespace libtorrent if (m_piece_map[block.piece_index].downloading == 0) return false; std::vector::const_iterator i = find_dl_piece(block.piece_index); TORRENT_ASSERT(i != m_downloads.end()); + TORRENT_ASSERT(i->info[block.block_index].piece_index == block.piece_index); return i->info[block.block_index].state == block_info::state_finished || i->info[block.block_index].state == block_info::state_writing; } @@ -2060,6 +2074,7 @@ namespace libtorrent if (m_piece_map[block.piece_index].downloading == 0) return false; std::vector::const_iterator i = find_dl_piece(block.piece_index); TORRENT_ASSERT(i != m_downloads.end()); + TORRENT_ASSERT(i->info[block.block_index].piece_index == block.piece_index); return i->info[block.block_index].state == block_info::state_finished; } @@ -2088,6 +2103,7 @@ namespace libtorrent downloading_piece& dp = add_download_piece(block.piece_index); dp.state = state; block_info& info = dp.info[block.block_index]; + TORRENT_ASSERT(info.piece_index == block.piece_index); info.state = block_info::state_requested; info.peer = peer; info.num_peers = 1; @@ -2102,6 +2118,7 @@ namespace libtorrent std::vector::iterator i = find_dl_piece(block.piece_index); TORRENT_ASSERT(i != m_downloads.end()); block_info& info = i->info[block.block_index]; + TORRENT_ASSERT(info.piece_index == block.piece_index); if (info.state == block_info::state_writing || info.state == block_info::state_finished) return false; @@ -2135,6 +2152,7 @@ namespace libtorrent TORRENT_ASSERT(i != m_downloads.end()); block_info const& info = i->info[block.block_index]; + TORRENT_ASSERT(info.piece_index == block.piece_index); return info.num_peers; } @@ -2181,6 +2199,7 @@ namespace libtorrent downloading_piece& dp = add_download_piece(block.piece_index); dp.state = none; block_info& info = dp.info[block.block_index]; + TORRENT_ASSERT(info.piece_index == block.piece_index); info.state = block_info::state_writing; info.peer = peer; info.num_peers = 0; @@ -2194,6 +2213,8 @@ namespace libtorrent TORRENT_ASSERT(i != m_downloads.end()); block_info& info = i->info[block.block_index]; + TORRENT_ASSERT(info.piece_index == block.piece_index); + info.peer = peer; if (info.state == block_info::state_requested) --i->requested; TORRENT_ASSERT(i->requested >= 0); @@ -2203,6 +2224,7 @@ namespace libtorrent ++i->writing; info.state = block_info::state_writing; + TORRENT_ASSERT(info.piece_index == block.piece_index); // all other requests for this block should have been // cancelled now @@ -2228,6 +2250,7 @@ namespace libtorrent if (i == m_downloads.end()) return; block_info& info = i->info[block.block_index]; + TORRENT_ASSERT(info.piece_index == block.piece_index); TORRENT_ASSERT(info.state == block_info::state_writing); TORRENT_ASSERT(info.num_peers == 0); @@ -2289,6 +2312,7 @@ namespace libtorrent downloading_piece& dp = add_download_piece(block.piece_index); dp.state = none; block_info& info = dp.info[block.block_index]; + TORRENT_ASSERT(info.piece_index == block.piece_index); info.peer = peer; TORRENT_ASSERT(info.state == block_info::state_none); TORRENT_ASSERT(info.num_peers == 0); @@ -2308,6 +2332,7 @@ namespace libtorrent std::vector::iterator i = find_dl_piece(block.piece_index); TORRENT_ASSERT(i != m_downloads.end()); block_info& info = i->info[block.block_index]; + TORRENT_ASSERT(info.piece_index == block.piece_index); if (info.state == block_info::state_finished) return; @@ -2352,6 +2377,7 @@ namespace libtorrent TORRENT_ASSERT(block.block_index >= 0); + TORRENT_ASSERT(i->info[block.block_index].piece_index == block.piece_index); if (i->info[block.block_index].state == block_info::state_none) return 0; @@ -2381,6 +2407,7 @@ namespace libtorrent TORRENT_ASSERT(i != m_downloads.end()); block_info& info = i->info[block.block_index]; + TORRENT_ASSERT(info.piece_index == block.piece_index); TORRENT_ASSERT(info.state != block_info::state_none); diff --git a/src/torrent.cpp b/src/torrent.cpp index 93532ebd4..343baa30d 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -4503,6 +4503,14 @@ namespace libtorrent if (m_ses.is_aborted()) return; +#ifndef TORRENT_DISABLE_GEO_IP + int as = m_ses.as_for_ip(host->endpoint().address()); +#ifdef TORRENT_DEBUG + web->peer_info.inet_as_num = as; +#endif + web->peer_info.inet_as = m_ses.lookup_as(as); +#endif + if (int(m_connections.size()) >= m_max_connections || m_ses.num_connections() >= m_ses.settings().connections_limit) return; @@ -5351,6 +5359,7 @@ namespace libtorrent i != end(); ++i) { peer_connection* peer = *i; + TORRENT_ASSERT(peer->m_in_use == 1337); // incoming peers that haven't finished the handshake should // not be included in this list