forked from premiere/premiere-libtorrent
generalize command line parsing of connection_tester and add feature to serve corrupt pieces every now and then
This commit is contained in:
parent
9e5edf3413
commit
b5cf2e8439
|
@ -66,6 +66,10 @@ void generate_block(boost::uint32_t* buffer, int piece, int start, int length)
|
|||
int local_if_counter = 0;
|
||||
bool local_bind = false;
|
||||
|
||||
// if this is true, one block in 1000 will be sent corrupt.
|
||||
// this only applies to dual and upload tests
|
||||
bool test_corruption = false;
|
||||
|
||||
// number of seeds we've spawned. The test is terminated
|
||||
// when this reaches zero, for dual tests
|
||||
static boost::detail::atomic_count num_seeds(0);
|
||||
|
@ -103,6 +107,7 @@ struct peer_conn
|
|||
, num_pieces(num_pieces)
|
||||
, start_time(time_now_hires())
|
||||
{
|
||||
corruption_counter = rand() % 1000;
|
||||
if (seed) ++num_seeds;
|
||||
pieces.reserve(num_pieces);
|
||||
if (local_bind)
|
||||
|
@ -134,6 +139,7 @@ struct peer_conn
|
|||
boost::uint32_t write_buffer[17*1024/4];
|
||||
boost::uint32_t buffer[17*1024/4];
|
||||
int read_pos;
|
||||
int corruption_counter;
|
||||
|
||||
enum state_t
|
||||
{
|
||||
|
@ -518,6 +524,16 @@ struct peer_conn
|
|||
void write_piece(int piece, int start, int length)
|
||||
{
|
||||
generate_block(write_buffer, piece, start, length);
|
||||
|
||||
if (test_corruption)
|
||||
{
|
||||
--corruption_counter;
|
||||
if (corruption_counter == 0)
|
||||
{
|
||||
corruption_counter = 1000;
|
||||
memset(write_buffer, 0, 10);
|
||||
}
|
||||
}
|
||||
char* ptr = write_buf_proto;
|
||||
write_uint32(9 + length, ptr);
|
||||
assert(length == 0x4000);
|
||||
|
@ -543,34 +559,36 @@ struct peer_conn
|
|||
|
||||
void print_usage()
|
||||
{
|
||||
fprintf(stderr, "usage: connection_tester command ...\n\n"
|
||||
fprintf(stderr, "usage: connection_tester command [options]\n\n"
|
||||
"command is one of:\n"
|
||||
" gen-torrent generate a test torrent\n"
|
||||
" this command takes two extra arguments:\n"
|
||||
" 1. the size of the torrent in megabytes\n"
|
||||
" 2. the number of files in the test torrent\n"
|
||||
" 3. the file to save the .torrent file to\n\n"
|
||||
" options for this command:\n"
|
||||
" -s <size> the size of the torrent in megabytes\n"
|
||||
" -n <num-files> the number of files in the test torrent\n"
|
||||
" -t <file> 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"
|
||||
" options for this command:\n"
|
||||
" -t <file> the torrent file that was previously generated\n"
|
||||
" -P <path> the path to where the data should be stored\n\n"
|
||||
" gen-test-torrents generate many test torrents (cannot be used for up/down tests)\n"
|
||||
" 1. number of torrents to generate\n"
|
||||
" 2. number of files in each torrent\n"
|
||||
" 3. base name of torrent files (index is appended)\n"
|
||||
" options for this command:\n"
|
||||
" -N <num-torrents> number of torrents to generate\n"
|
||||
" -n <num-files> number of files in each torrent\n"
|
||||
" -t <name> base name of torrent files (index is appended)\n\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"
|
||||
" 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"
|
||||
" 4. torrent-file - the torrent file previously generated by gen-torrent\n\n"
|
||||
" options for these commands:\n"
|
||||
" -c <num-conns> the number of connections to make to the target\n"
|
||||
" -d <dst> the IP address of the target\n"
|
||||
" -p <dst-port> the port the target listens on\n"
|
||||
" -t <torrent-file> the torrent file previously generated by gen-torrent\n\n"
|
||||
" -C send corrupt pieces sometimes (applies to upload and dual)\n\n"
|
||||
"examples:\n\n"
|
||||
"connection_tester gen-torrent 1024 4 test.torrent\n"
|
||||
"connection_tester upload 200 127.0.0.1 6881 test.torrent\n"
|
||||
"connection_tester download 200 127.0.0.1 6881 test.torrent\n"
|
||||
"connection_tester dual 200 127.0.0.1 6881 test.torrent\n");
|
||||
"connection_tester gen-torrent -s 1024 -n 4 -t test.torrent\n"
|
||||
"connection_tester upload -c 200 -d 127.0.0.1 -p 6881 -t test.torrent\n"
|
||||
"connection_tester download -c 200 -d 127.0.0.1 -p 6881 -t test.torrent\n"
|
||||
"connection_tester dual -c 200 -d 127.0.0.1 -p 6881 -t test.torrent\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
@ -662,55 +680,101 @@ int main(int argc, char* argv[])
|
|||
{
|
||||
if (argc <= 1) print_usage();
|
||||
|
||||
if (strcmp(argv[1], "gen-torrent") == 0)
|
||||
{
|
||||
if (argc != 5) print_usage();
|
||||
char const* command = argv[1];
|
||||
int size = 1000;
|
||||
int num_files = 10;
|
||||
int num_torrents = 1;
|
||||
char const* torrent_file = "benchmark.torrent";
|
||||
char const* data_path = ".";
|
||||
int num_connections = 50;
|
||||
char const* destination_ip = "127.0.0.1";
|
||||
int destination_port = 6881;
|
||||
|
||||
int size = atoi(argv[2]);
|
||||
int num_files = atoi(argv[3]);
|
||||
argv += 2;
|
||||
argc -= 2;
|
||||
|
||||
while (argc > 0)
|
||||
{
|
||||
char const* optname = argv[0];
|
||||
++argv;
|
||||
--argc;
|
||||
|
||||
if (optname[0] != '-' || strlen(optname) != 2)
|
||||
{
|
||||
fprintf(stderr, "unknown option: %s\n", optname);
|
||||
continue;
|
||||
}
|
||||
|
||||
// options with no arguments
|
||||
switch (optname[1])
|
||||
{
|
||||
case 'C': test_corruption = true; continue;
|
||||
}
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
fprintf(stderr, "missing argument for option: %s\n", optname);
|
||||
break;
|
||||
}
|
||||
|
||||
char const* optarg = argv[0];
|
||||
++argv;
|
||||
--argc;
|
||||
|
||||
switch (optname[1])
|
||||
{
|
||||
case 's': size = atoi(optarg); break;
|
||||
case 'n': num_files = atoi(optarg); break;
|
||||
case 'N': num_torrents = atoi(optarg); break;
|
||||
case 't': torrent_file = optarg; break;
|
||||
case 'P': data_path = optarg; break;
|
||||
case 'c': num_connections = atoi(optarg); break;
|
||||
case 'p': destination_port = atoi(optarg); break;
|
||||
case 'd': destination_ip = optarg; break;
|
||||
default: fprintf(stderr, "unknown option: %s\n", optname);
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(command, "gen-torrent") == 0)
|
||||
{
|
||||
std::vector<char> tmp;
|
||||
generate_torrent(tmp, size ? size : 1024, num_files ? num_files : 1);
|
||||
|
||||
FILE* output = stdout;
|
||||
if (strcmp("-", argv[4]) != 0)
|
||||
output = fopen(argv[4], "wb+");
|
||||
if (strcmp("-", torrent_file) != 0)
|
||||
output = fopen(torrent_file, "wb+");
|
||||
fprintf(stderr, "writing file to: %s\n", torrent_file);
|
||||
fwrite(&tmp[0], 1, tmp.size(), output);
|
||||
if (output != stdout)
|
||||
fclose(output);
|
||||
|
||||
return 0;
|
||||
}
|
||||
else if (strcmp(argv[1], "gen-data") == 0)
|
||||
else if (strcmp(command, "gen-data") == 0)
|
||||
{
|
||||
if (argc != 4) print_usage();
|
||||
error_code ec;
|
||||
torrent_info ti(argv[2], ec);
|
||||
torrent_info ti(torrent_file, 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());
|
||||
generate_data(data_path, ti.num_pieces(), ti.piece_length());
|
||||
return 0;
|
||||
}
|
||||
else if (strcmp(argv[1], "gen-test-torrents") == 0)
|
||||
else if (strcmp(command, "gen-test-torrents") == 0)
|
||||
{
|
||||
if (argc != 5) print_usage();
|
||||
|
||||
int num_torrents = atoi(argv[2]);
|
||||
int num_files = atoi(argv[3]);
|
||||
char const* name = argv[4];
|
||||
std::vector<char> buf;
|
||||
for (int i = 0; i < num_torrents; ++i)
|
||||
{
|
||||
char torrent_name[100];
|
||||
snprintf(torrent_name, sizeof(torrent_name), "%s-%d.torrent", name, i);
|
||||
snprintf(torrent_name, sizeof(torrent_name), "%s-%d.torrent", torrent_file, i);
|
||||
|
||||
file_storage fs;
|
||||
for (int j = 0; j < num_files; ++j)
|
||||
{
|
||||
char file_name[100];
|
||||
snprintf(file_name, sizeof(file_name), "%s-%d/file-%d", name, i, j);
|
||||
snprintf(file_name, sizeof(file_name), "%s-%d/file-%d", torrent_file, i, j);
|
||||
fs.add_file(file_name, size_type(j + i + 1) * 251);
|
||||
}
|
||||
// 1 MiB piece size
|
||||
|
@ -741,33 +805,32 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
else if (strcmp(argv[1], "upload") == 0)
|
||||
else if (strcmp(command, "upload") == 0)
|
||||
{
|
||||
if (argc != 6) print_usage();
|
||||
test_mode = upload_test;
|
||||
}
|
||||
else if (strcmp(argv[1], "download") == 0)
|
||||
else if (strcmp(command, "download") == 0)
|
||||
{
|
||||
if (argc != 6) print_usage();
|
||||
test_mode = download_test;
|
||||
}
|
||||
else if (strcmp(argv[1], "dual") == 0)
|
||||
else if (strcmp(command, "dual") == 0)
|
||||
{
|
||||
if (argc != 6) print_usage();
|
||||
test_mode = dual_test;
|
||||
}
|
||||
else print_usage();
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "unknown command: %s\n\n", command);
|
||||
print_usage();
|
||||
}
|
||||
|
||||
int num_connections = atoi(argv[2]);
|
||||
error_code ec;
|
||||
address_v4 addr = address_v4::from_string(argv[3], ec);
|
||||
address_v4 addr = address_v4::from_string(destination_ip, ec);
|
||||
if (ec)
|
||||
{
|
||||
fprintf(stderr, "ERROR RESOLVING %s: %s\n", argv[3], ec.message().c_str());
|
||||
fprintf(stderr, "ERROR RESOLVING %s: %s\n", destination_ip, ec.message().c_str());
|
||||
return 1;
|
||||
}
|
||||
int port = atoi(argv[4]);
|
||||
tcp::endpoint ep(addr, port);
|
||||
tcp::endpoint ep(addr, destination_port);
|
||||
|
||||
#if !defined __APPLE__
|
||||
// apparently darwin doesn't seems to let you bind to
|
||||
|
@ -779,7 +842,7 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
#endif
|
||||
|
||||
torrent_info ti(argv[5], ec);
|
||||
torrent_info ti(torrent_file, ec);
|
||||
if (ec)
|
||||
{
|
||||
fprintf(stderr, "ERROR LOADING .TORRENT: %s\n", ec.message().c_str());
|
||||
|
|
Loading…
Reference in New Issue