improved multiple bitfield and have_all/have_none unit test and fixed peer_connection accordingly

This commit is contained in:
Arvid Norberg 2012-05-02 18:03:12 +00:00
parent bf3751640a
commit ada35c021a
2 changed files with 84 additions and 51 deletions

View File

@ -1869,7 +1869,7 @@ namespace libtorrent
// if we've already received a bitfield message // if we've already received a bitfield message
// we first need to count down all the pieces // we first need to count down all the pieces
// we believe the peer has first // we believe the peer has first
t->peer_lost(bits); t->peer_lost(m_have_piece);
} }
m_bitfield_received = true; m_bitfield_received = true;
@ -2718,6 +2718,9 @@ namespace libtorrent
#endif #endif
if (is_disconnecting()) return; if (is_disconnecting()) return;
if (m_bitfield_received)
t->peer_lost(m_have_piece);
m_have_all = true; m_have_all = true;
#ifdef TORRENT_VERBOSE_LOGGING #ifdef TORRENT_VERBOSE_LOGGING
@ -2781,9 +2784,16 @@ namespace libtorrent
} }
#endif #endif
if (is_disconnecting()) return; if (is_disconnecting()) return;
if (m_bitfield_received)
t->peer_lost(m_have_piece);
t->get_policy().set_seed(m_peer_info, false); t->get_policy().set_seed(m_peer_info, false);
m_bitfield_received = true; m_bitfield_received = true;
m_have_piece.clear_all();
m_num_pieces = 0;
// we're never interested in a peer that doesn't have anything // we're never interested in a peer that doesn't have anything
send_not_interested(); send_not_interested();

View File

@ -148,6 +148,24 @@ void send_unchoke(stream_socket& s)
, libtorrent::asio::transfer_all(), ec); , libtorrent::asio::transfer_all(), ec);
} }
void send_have_all(stream_socket& s)
{
std::cout << time_now_string() << " ==> have_all" << std::endl;
char msg[] = "\0\0\0\x01\x0e"; // have_all
error_code ec;
libtorrent::asio::write(s, libtorrent::asio::buffer(msg, 5)
, libtorrent::asio::transfer_all(), ec);
}
void send_have_none(stream_socket& s)
{
std::cout << time_now_string() << " ==> have_none" << std::endl;
char msg[] = "\0\0\0\x01\x0f"; // have_none
error_code ec;
libtorrent::asio::write(s, libtorrent::asio::buffer(msg, 5)
, libtorrent::asio::transfer_all(), ec);
}
void send_bitfield(stream_socket& s, char const* bits) void send_bitfield(stream_socket& s, char const* bits)
{ {
using namespace libtorrent::detail; using namespace libtorrent::detail;
@ -173,10 +191,8 @@ void do_handshake(stream_socket& s, sha1_hash const& ih, char* buffer)
{ {
char handshake[] = "\x13" "BitTorrent protocol\0\0\0\0\0\0\0\x04" char handshake[] = "\x13" "BitTorrent protocol\0\0\0\0\0\0\0\x04"
" " // space for info-hash " " // space for info-hash
"aaaaaaaaaaaaaaaaaaaa" // peer-id "aaaaaaaaaaaaaaaaaaaa"; // peer-id
"\0\0\0\x01\x0e"; // have_all
std::cout << time_now_string() << " ==> handshake" << std::endl; std::cout << time_now_string() << " ==> handshake" << std::endl;
std::cout << time_now_string() << " ==> have_all" << std::endl;
error_code ec; error_code ec;
std::memcpy(handshake + 28, ih.begin(), 20); std::memcpy(handshake + 28, ih.begin(), 20);
libtorrent::asio::write(s, libtorrent::asio::buffer(handshake, sizeof(handshake) - 1) libtorrent::asio::write(s, libtorrent::asio::buffer(handshake, sizeof(handshake) - 1)
@ -212,15 +228,11 @@ void do_handshake(stream_socket& s, sha1_hash const& ih, char* buffer)
TEST_CHECK(std::memcmp(buffer + 28, ih.begin(), 20) == 0); TEST_CHECK(std::memcmp(buffer + 28, ih.begin(), 20) == 0);
} }
// makes sure that pieces that are allowed and then boost::intrusive_ptr<torrent_info> setup_peer(stream_socket& s, sha1_hash& ih, boost::shared_ptr<session>& ses)
// rejected aren't requested again
void test_reject_fast()
{ {
std::cerr << " === test reject ===" << std::endl;
boost::intrusive_ptr<torrent_info> t = ::create_torrent(); boost::intrusive_ptr<torrent_info> t = ::create_torrent();
sha1_hash ih = t->info_hash(); ih = t->info_hash();
session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48900, 49000), "0.0.0.0", 0); ses.reset(new session(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48900, 49000), "0.0.0.0", 0));
error_code ec; error_code ec;
add_torrent_params p; add_torrent_params p;
p.flags &= ~add_torrent_params::flag_paused; p.flags &= ~add_torrent_params::flag_paused;
@ -231,16 +243,29 @@ void test_reject_fast()
remove("./tmp1_fast/temporary", ec); remove("./tmp1_fast/temporary", ec);
if (ec) fprintf(stderr, "remove(): %s\n", ec.message().c_str()); if (ec) fprintf(stderr, "remove(): %s\n", ec.message().c_str());
ec.clear(); ec.clear();
ses1.add_torrent(p, ec); ses->add_torrent(p, ec);
test_sleep(300); test_sleep(300);
s.connect(tcp::endpoint(address::from_string("127.0.0.1", ec), ses->listen_port()), ec);
return t;
}
// makes sure that pieces that are allowed and then
// rejected aren't requested again
void test_reject_fast()
{
std::cerr << " === test reject ===" << std::endl;
sha1_hash ih;
boost::shared_ptr<session> ses;
io_service ios; io_service ios;
stream_socket s(ios); stream_socket s(ios);
s.connect(tcp::endpoint(address::from_string("127.0.0.1", ec), ses1.listen_port()), ec); setup_peer(s, ih, ses);
char recv_buffer[1000]; char recv_buffer[1000];
do_handshake(s, ih, recv_buffer); do_handshake(s, ih, recv_buffer);
send_have_all(s);
std::vector<int> allowed_fast; std::vector<int> allowed_fast;
allowed_fast.push_back(0); allowed_fast.push_back(0);
@ -276,35 +301,23 @@ void test_reject_fast()
libtorrent::asio::write(s, libtorrent::asio::buffer(recv_buffer, 13) libtorrent::asio::write(s, libtorrent::asio::buffer(recv_buffer, 13)
, libtorrent::asio::transfer_all(), ec); , libtorrent::asio::transfer_all(), ec);
} }
s.close();
test_sleep(500);
} }
void test_respect_suggest() void test_respect_suggest()
{ {
std::cerr << " === test suggest ===" << std::endl; std::cerr << " === test suggest ===" << std::endl;
boost::intrusive_ptr<torrent_info> t = ::create_torrent();
sha1_hash ih = t->info_hash();
session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48900, 49000), "0.0.0.0", 0);
error_code ec;
add_torrent_params p;
p.flags &= ~add_torrent_params::flag_paused;
p.flags &= ~add_torrent_params::flag_auto_managed;
p.ti = t;
p.save_path = "./tmp1_fast";
remove("./tmp1_fast/temporary", ec);
if (ec) fprintf(stderr, "remove(): %s\n", ec.message().c_str());
ec.clear();
ses1.add_torrent(p, ec);
test_sleep(300);
sha1_hash ih;
boost::shared_ptr<session> ses;
io_service ios; io_service ios;
stream_socket s(ios); stream_socket s(ios);
s.connect(tcp::endpoint(address::from_string("127.0.0.1", ec), ses1.listen_port()), ec); setup_peer(s, ih, ses);
char recv_buffer[1000]; char recv_buffer[1000];
do_handshake(s, ih, recv_buffer); do_handshake(s, ih, recv_buffer);
send_have_all(s);
std::vector<int> suggested; std::vector<int> suggested;
suggested.push_back(0); suggested.push_back(0);
@ -347,38 +360,26 @@ void test_respect_suggest()
, libtorrent::asio::transfer_all(), ec); , libtorrent::asio::transfer_all(), ec);
} }
TEST_CHECK(fail_counter > 0); TEST_CHECK(fail_counter > 0);
s.close();
test_sleep(500);
} }
void test_multiple_bitfields() void test_multiple_bitfields()
{ {
std::cerr << " === test multiple bitfields ===" << std::endl; std::cerr << " === test multiple bitfields ===" << std::endl;
boost::intrusive_ptr<torrent_info> t = ::create_torrent(); sha1_hash ih;
sha1_hash ih = t->info_hash(); boost::shared_ptr<session> ses;
session ses1(fingerprint("LT", 0, 1, 0, 0), std::make_pair(48900, 49000), "0.0.0.0", 0);
error_code ec;
add_torrent_params p;
p.flags &= ~add_torrent_params::flag_paused;
p.flags &= ~add_torrent_params::flag_auto_managed;
p.ti = t;
p.save_path = "./tmp1_fast";
remove("./tmp1_fast/temporary", ec);
if (ec) fprintf(stderr, "remove(): %s\n", ec.message().c_str());
ec.clear();
ses1.add_torrent(p, ec);
test_sleep(300);
io_service ios; io_service ios;
stream_socket s(ios); stream_socket s(ios);
s.connect(tcp::endpoint(address::from_string("127.0.0.1", ec), ses1.listen_port()), ec); boost::intrusive_ptr<torrent_info> ti = setup_peer(s, ih, ses);
char recv_buffer[1000]; char recv_buffer[1000];
do_handshake(s, ih, recv_buffer); do_handshake(s, ih, recv_buffer);
std::string bitfield; std::string bitfield;
bitfield.resize(t->num_pieces(), '0'); bitfield.resize(ti->num_pieces(), '0');
send_bitfield(s, bitfield.c_str()); send_bitfield(s, bitfield.c_str());
bitfield[0] = '1'; bitfield[0] = '1';
send_bitfield(s, bitfield.c_str()); send_bitfield(s, bitfield.c_str());
@ -388,8 +389,29 @@ void test_multiple_bitfields()
send_bitfield(s, bitfield.c_str()); send_bitfield(s, bitfield.c_str());
s.close(); s.close();
test_sleep(500);
}
test_sleep(1000); void test_multiple_have_all()
{
std::cerr << " === test multiple have_all ===" << std::endl;
sha1_hash ih;
boost::shared_ptr<session> ses;
io_service ios;
stream_socket s(ios);
boost::intrusive_ptr<torrent_info> ti = setup_peer(s, ih, ses);
char recv_buffer[1000];
do_handshake(s, ih, recv_buffer);
send_have_all(s);
send_have_all(s);
send_have_none(s);
send_have_all(s);
s.close();
test_sleep(500);
} }
int test_main() int test_main()
@ -397,6 +419,7 @@ int test_main()
test_reject_fast(); test_reject_fast();
test_respect_suggest(); test_respect_suggest();
test_multiple_bitfields(); test_multiple_bitfields();
test_multiple_have_all();
return 0; return 0;
} }