back-ported connection tester from aio-branch

This commit is contained in:
Arvid Norberg 2011-08-10 07:36:59 +00:00
parent 4abf581f0a
commit fdd214f20a
1 changed files with 94 additions and 26 deletions

View File

@ -342,13 +342,23 @@ struct peer_conn
if (seed)
{
if (msg == 6 && bytes_transferred == 13)
if (msg == 6)
{
if (bytes_transferred != 13)
{
close("REQUEST packet has invalid size", error_code());
return;
}
int piece = detail::read_int32(ptr);
int start = detail::read_int32(ptr);
int length = detail::read_int32(ptr);
write_piece(piece, start, length);
}
else if (msg == 3) // not-interested
{
close("DONE", error_code());
return;
}
else
{
// read another message
@ -428,10 +438,14 @@ void print_usage()
" this command takes two extra arguments:\n"
" 1. the size of the torrent in megabytes\n"
" 2. the file to save the .torrent file to\n\n"
" gen-data generate the data file(s) for the test torrent\n"
" this command takes two extra arguments:\n"
" 1. the torrent file that was previously generated\n"
" 2. the path to where the data should be stored\n"
" upload start an uploader test\n"
" download start a downloader test\n"
" dual start a download and upload test\n"
" these commands set takes 4 additional arguments\n"
" these commands set takes 4 additional arguments:\n"
" 1. num-connections - the number of connections to make to the target\n"
" 2. destination-IP - the IP address of the target\n"
" 3. destination-port - the port the target listens on\n"
@ -444,6 +458,24 @@ void print_usage()
exit(1);
}
void hasher_thread(libtorrent::create_torrent* t, int start_piece, int end_piece, int piece_size, bool print)
{
if (print) fprintf(stderr, "\n");
boost::uint32_t piece[0x4000 / 4];
for (int i = start_piece; i < end_piece; ++i)
{
hasher ph;
for (int j = 0; j < piece_size; j += 0x4000)
{
generate_block(piece, i, j, 0x4000);
ph.update((char*)piece, 0x4000);
}
t->set_hash(i, ph.final());
if (print && (i & 1)) fprintf(stderr, "\r%.1f %% ", float((i-start_piece) * 100) / float(end_piece-start_piece));
}
if (print) fprintf(stderr, "\n");
}
// size is in megabytes
void generate_torrent(std::vector<char>& buf, int size)
{
@ -452,6 +484,7 @@ void generate_torrent(std::vector<char>& buf, int size)
const int piece_size = 1024 * 1024;
const int num_pieces = size;
const size_type total_size = size_type(piece_size) * num_pieces;
/*
size_type s = total_size;
int i = 0;
while (s > 0)
@ -462,34 +495,49 @@ void generate_torrent(std::vector<char>& buf, int size)
fs.add_file(buf, (std::min)(s, size_type(20*1024*1024)));
s -= 20*1024*1024;
}
*/
fs.add_file("stress_test_file", total_size);
libtorrent::create_torrent t(fs, piece_size);
fprintf(stderr, "\n");
boost::uint32_t piece[0x4000 / 4];
for (int i = 0; i < num_pieces; ++i)
{
hasher ph;
for (int j = 0; j < piece_size; j += 0x4000)
{
generate_block(piece, i, j, 0x4000);
ph.update((char*)piece, 0x4000);
}
t.set_hash(i, ph.final());
if (i & 1) fprintf(stderr, "\r%.1f %% ", float(i * 100) / float(num_pieces));
}
fprintf(stderr, "\n");
// generate the hashes in 4 threads
thread t1(boost::bind(&hasher_thread, &t, 0, 1 * num_pieces / 4, piece_size, false));
thread t2(boost::bind(&hasher_thread, &t, 1 * num_pieces / 4, 2 * num_pieces / 4, piece_size, false));
thread t3(boost::bind(&hasher_thread, &t, 2 * num_pieces / 4, 3 * num_pieces / 4, piece_size, false));
thread t4(boost::bind(&hasher_thread, &t, 3 * num_pieces / 4, 4 * num_pieces / 4, piece_size, true));
t1.join();
t2.join();
t3.join();
t4.join();
std::back_insert_iterator<std::vector<char> > out(buf);
bencode(out, t.generate());
}
void generate_data(char const* path, int num_pieces, int piece_size)
{
FILE* f = fopen(path, "w+");
boost::uint32_t piece[0x4000 / 4];
for (int i = 0; i < num_pieces; ++i)
{
for (int j = 0; j < piece_size; j += 0x4000)
{
generate_block(piece, i, j, 0x4000);
fwrite(piece, 0x4000, 1, f);
}
if (i & 1) fprintf(stderr, "\r%.1f %% ", float(i * 100) / float(num_pieces));
}
fclose(f);
}
void io_thread(io_service* ios)
{
error_code ec;
ios->run(ec);
if (ec)
fprintf(stderr, "ERROR: %s\n", ec.message().c_str());
if (ec) fprintf(stderr, "ERROR: %s\n", ec.message().c_str());
}
int main(int argc, char* argv[])
@ -515,6 +563,18 @@ int main(int argc, char* argv[])
return 0;
}
else if (strcmp(argv[1], "gen-torrent") == 0)
{
if (argc != 4) print_usage();
error_code ec;
torrent_info ti(argv[2], ec);
if (ec)
{
fprintf(stderr, "ERROR LOADING .TORRENT: %s\n", ec.message().c_str());
return 1;
}
generate_data(argv[3], ti.num_pieces(), ti.piece_length());
}
else if (strcmp(argv[1], "upload") == 0)
{
if (argc != 6) print_usage();
@ -544,11 +604,15 @@ int main(int argc, char* argv[])
int port = atoi(argv[4]);
tcp::endpoint ep(addr, port);
#if !defined __APPLE__
// apparently darwin doesn't seems to let you bind to
// loopback on any other IP than 127.0.0.1
unsigned long ip = addr.to_ulong();
if ((ip & 0xff000000) == 0x7f000000)
{
local_bind = true;
}
#endif
torrent_info ti(argv[5], ec);
if (ec)
@ -558,16 +622,17 @@ int main(int argc, char* argv[])
}
std::list<peer_conn*> conns;
io_service ios;
const int num_threads = 2;
io_service ios[num_threads];
for (int i = 0; i < num_connections; ++i)
{
bool seed = false;
if (test_mode == upload_test) seed = true;
else if (test_mode == dual_test) seed = (i & 1);
conns.push_back(new peer_conn(ios, ti.num_pieces(), ti.piece_length() / 16 / 1024
conns.push_back(new peer_conn(ios[i % num_threads], ti.num_pieces(), ti.piece_length() / 16 / 1024
, ep, (char const*)&ti.info_hash()[0], seed));
libtorrent::sleep(1);
ios.poll_one(ec);
ios[i % num_threads].poll_one(ec);
if (ec)
{
fprintf(stderr, "ERROR: %s\n", ec.message().c_str());
@ -576,8 +641,8 @@ int main(int argc, char* argv[])
}
thread t1(boost::bind(&io_thread, &ios));
thread t2(boost::bind(&io_thread, &ios));
thread t1(boost::bind(&io_thread, &ios[0]));
thread t2(boost::bind(&io_thread, &ios[1]));
t1.join();
t2.join();
@ -600,9 +665,12 @@ int main(int argc, char* argv[])
delete p;
}
printf("=========================\ntotal sent: %.1f %% received: %.1f %%\n"
, total_sent * 0x4000 / float(ti.total_size())
, total_received * 0x4000 / float(ti.total_size()));
printf("=========================\n"
"total sent: %.1f %% received: %.1f %%\n"
"rate sent: %.1f MB/s received: %.1f MB/s\n"
, total_sent * 0x4000 * 100.f / float(ti.total_size())
, total_received * 0x4000 * 100.f / float(ti.total_size())
, up, down);
return 0;
}