From bed835af1ec1f0d55d6955a2589cc933553f73d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 22 Nov 2006 19:13:07 +0000 Subject: [PATCH] The TCP tester now also allows you to reorder random or specific packets. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19364 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/tests/kits/net/tcp_tester.cpp | 95 ++++++++++++++++++++++++++++--- 1 file changed, 87 insertions(+), 8 deletions(-) diff --git a/src/tests/kits/net/tcp_tester.cpp b/src/tests/kits/net/tcp_tester.cpp index 1b98d9c072..c6246dffd9 100644 --- a/src/tests/kits/net/tcp_tester.cpp +++ b/src/tests/kits/net/tcp_tester.cpp @@ -68,12 +68,15 @@ struct net_protocol_module_info *gTCPModule; struct net_socket *gServerSocket, *gClientSocket; static struct context sClientContext, sServerContext; +static vint32 sPacketNumber = 1; static set sDropList; static bigtime_t sRoundTripTime = 0; static bool sIncreasingRoundTrip = false; static bool sRandomRoundTrip = false; static bool sTCPDump = true; static bigtime_t sStartTime; +static double sRandomReorder = 0.0; +static set sReorderList; static struct net_domain sDomain = { "ipv4", @@ -739,9 +742,10 @@ domain_get_mtu(net_protocol *protocol, const struct sockaddr *address) status_t domain_receive_data(net_buffer *buffer) { - static uint32 packetNumber = 1; static bigtime_t lastTime = 0; + uint32 packetNumber = atomic_add(&sPacketNumber, 1); + bool drop = false; if (sDropList.find(packetNumber) != sDropList.end()) drop = true; @@ -749,7 +753,7 @@ domain_receive_data(net_buffer *buffer) if (!drop && (sRoundTripTime > 0 || sRandomRoundTrip || sIncreasingRoundTrip)) { bigtime_t add = 0; if (sRandomRoundTrip) - add = (bigtime_t)(1.0 * rand() / RAND_MAX * 500000); + add = (bigtime_t)(1.0 * rand() / RAND_MAX * 500000) - 250000; if (sIncreasingRoundTrip) sRoundTripTime += (bigtime_t)(1.0 * rand() / RAND_MAX * 150000); @@ -852,8 +856,6 @@ domain_receive_data(net_buffer *buffer) } else if (drop) printf("<**** DROPPED %ld ****>\n", packetNumber); - packetNumber++; - if (drop) { gNetBufferModule.free(buffer); return B_OK; @@ -916,6 +918,7 @@ int32 receiving_thread(void* _data) { struct context* context = (struct context*)_data; + struct net_buffer* reorderBuffer = NULL; while (true) { status_t status; @@ -926,11 +929,29 @@ receiving_thread(void* _data) if (status < B_OK) break; - context->lock.Lock(); - net_buffer* buffer = (net_buffer*)list_remove_head_item(&context->list); - context->lock.Unlock(); + while (true) { + context->lock.Lock(); + net_buffer* buffer = (net_buffer*)list_remove_head_item(&context->list); + context->lock.Unlock(); - sDomain.module->receive_data(buffer); + if (buffer == NULL) + break; + + if (sRandomReorder > 0.0 || sReorderList.find(sPacketNumber) != sReorderList.end() + && reorderBuffer == NULL + && (1.0 * rand() / RAND_MAX) > sRandomReorder) { + reorderBuffer = buffer; + } else { + if (sDomain.module->receive_data(buffer) < B_OK) + gNetBufferModule.free(buffer); + + if (reorderBuffer != NULL) { + if (sDomain.module->receive_data(reorderBuffer) < B_OK) + gNetBufferModule.free(reorderBuffer); + reorderBuffer = NULL; + } + } + } } return 0; @@ -1101,6 +1122,63 @@ do_drop(int argc, char** argv) } +static void +do_reorder(int argc, char** argv) +{ + if (argc == 1) { + // show list of dropped packets + if (sRandomReorder > 0.0) + printf("Reorder probability is %f\n", sRandomReorder); + + printf("Reorder packets:\n"); + + set::iterator iterator = sReorderList.begin(); + uint32 count = 0; + for (; iterator != sReorderList.end(); iterator++) { + printf("%4lu\n", *iterator); + count++; + } + + if (count == 0) + printf("\n"); + } else if (!strcmp(argv[1], "-f")) { + // flush reorder list + sReorderList.clear(); + puts("reorder list cleared."); + } else if (!strcmp(argv[1], "-r")) { + if (argc < 3) { + fprintf(stderr, "No reorder probability specified.\n"); + return; + } + + sRandomReorder = atof(argv[2]); + if (sRandomReorder < 0.0) + sRandomReorder = 0; + else if (sRandomReorder > 1.0) + sRandomReorder = 1.0; + } else if (isdigit(argv[1][0])) { + // add to reorder list + for (int i = 1; i < argc; i++) { + uint32 packet = strtoul(argv[i], NULL, 0); + if (packet == 0) { + fprintf(stderr, "invalid packet number: %s\n", argv[i]); + break; + } + + sReorderList.insert(packet); + } + } else { + // print usage + puts("usage: reorder [...]\n" + " or: reorder -r \n\n" + " or: reorder [-f]\n\n" + "Specifiying -f flushes the reorder list, -r sets the probability a packet\n" + "is reordered; if you called reorder without any arguments, the current\n" + "reorder list is dumped."); + } +} + + static void do_round_trip_time(int argc, char** argv) { @@ -1145,6 +1223,7 @@ static cmd_entry sBuiltinCommands[] = { {"send", do_send, "Sends data from the client to the server"}, {"dprintf", do_dprintf, "Toggles debug output"}, {"drop", do_drop, "Lets you drop packets during transfer"}, + {"reorder", do_reorder, "Lets you reorder packets during transfer"}, {"help", do_help, "prints this help text"}, {"rtt", do_round_trip_time, "Specifies the round trip time"}, {"quit", NULL, "exits the application"},