diff --git a/include/libtorrent/alert_types.hpp b/include/libtorrent/alert_types.hpp index a5298b38f..747c9352f 100644 --- a/include/libtorrent/alert_types.hpp +++ b/include/libtorrent/alert_types.hpp @@ -737,13 +737,26 @@ namespace libtorrent // internal invalid_request_alert(aux::stack_allocator& alloc , torrent_handle const& h, tcp::endpoint const& ep - , peer_id const& peer_id, peer_request const& r); + , peer_id const& peer_id, peer_request const& r + , bool we_have, bool peer_interested, bool withheld); TORRENT_DEFINE_ALERT(invalid_request_alert, 25); virtual std::string message() const; + // the request we received from the peer peer_request request; + + // true if we have this piece + bool we_have; + + // true if the peer indicated that it was interested to download before + // sending the request + bool peer_interested; + + // if this is true, the peer is not allowed to download this piece because + // of superseeding rules. + bool withheld; }; // This alert is generated when a torrent switches from being a downloader to a seed. diff --git a/src/alert.cpp b/src/alert.cpp index a161f23bf..f73a40340 100644 --- a/src/alert.cpp +++ b/src/alert.cpp @@ -484,16 +484,26 @@ namespace libtorrent { invalid_request_alert::invalid_request_alert(aux::stack_allocator& alloc , torrent_handle const& h, tcp::endpoint const& ep - , peer_id const& peer_id, peer_request const& r) + , peer_id const& peer_id, peer_request const& r + , bool we_have, bool peer_interested, bool withheld) : peer_alert(alloc, h, ep, peer_id) , request(r) + , we_have(we_have) + , peer_interested(peer_interested) + , withheld(withheld) {} std::string invalid_request_alert::message() const { char ret[200]; - snprintf(ret, sizeof(ret), "%s peer sent an invalid piece request (piece: %u start: %u len: %u)" - , peer_alert::message().c_str(), request.piece, request.start, request.length); + snprintf(ret, sizeof(ret), "%s peer sent an invalid piece request " + "(piece: %u start: %u len: %u)%s" + , peer_alert::message().c_str(), request.piece, request.start + , request.length + , withheld ? ": super seeding withheld piece" + : !we_have ? ": we don't have piece" + : !peer_interested ? ": peer is not interested" + : ""); return ret; } diff --git a/src/peer_connection.cpp b/src/peer_connection.cpp index 5e4bc2d8b..9b369109e 100644 --- a/src/peer_connection.cpp +++ b/src/peer_connection.cpp @@ -2193,7 +2193,8 @@ namespace libtorrent if (t->alerts().should_post()) { t->alerts().emplace_alert( - t->get_handle(), m_remote, m_peer_id, r); + t->get_handle(), m_remote, m_peer_id, r + , t->has_piece_passed(r.piece), bool(m_peer_interested), true); } return; } @@ -2248,6 +2249,28 @@ namespace libtorrent , m_accept_fast.end(), r.piece); if (fast_iter != m_accept_fast.end()) fast_idx = fast_iter - m_accept_fast.begin(); + if (!m_peer_interested) + { +#if defined TORRENT_LOGGING + peer_log("*** INVALID_REQUEST [ peer is not interested " + " t: %d n: %d h: %d block_limit: %d ]" + , int(t->torrent_file().piece_size(r.piece)) + , t->torrent_file().num_pieces() + , t->has_piece_passed(r.piece) + , t->block_size()); + peer_log("*** artificial INTERESTED message"); +#endif + if (t->alerts().should_post()) + { + t->alerts().emplace_alert( + t->get_handle(), m_remote, m_peer_id, r + , t->has_piece_passed(r.piece), bool(m_peer_interested), false); + } + + // be lenient and pretend that the peer said it was interested + incoming_interested(); + } + // make sure this request // is legal and that the peer // is not choked @@ -2260,7 +2283,6 @@ namespace libtorrent || r.start >= t->torrent_file().piece_size(r.piece) || r.length <= 0 || r.length + r.start > t->torrent_file().piece_size(r.piece) - || !m_peer_interested || r.length > t->block_size()) { m_counters.inc_stats_counter(counters::invalid_piece_requests); @@ -2284,7 +2306,8 @@ namespace libtorrent if (t->alerts().should_post()) { t->alerts().emplace_alert( - t->get_handle(), m_remote, m_peer_id, r); + t->get_handle(), m_remote, m_peer_id, r + , t->has_piece_passed(r.piece), bool(m_peer_interested), false); } // every ten invalid request, remind the peer that it's choked