From 1f4bfd765bb608da1134e3a39b313d1648d7a4b9 Mon Sep 17 00:00:00 2001 From: Nick Banks Date: Fri, 28 Aug 2020 12:43:34 -0700 Subject: [PATCH] Perf Protocol Refactor (#785) --- scripts/RemoteTests.json | 32 ++-- src/perf/lib/CMakeLists.txt | 5 +- src/perf/lib/PerfCommon.h | 44 ++--- src/perf/lib/PerfServer.cpp | 281 ++++++++++++++++++++++++++++ src/perf/lib/PerfServer.h | 96 ++++++++++ src/perf/lib/RpsClient.cpp | 19 +- src/perf/lib/RpsClient.h | 5 +- src/perf/lib/RpsServer.cpp | 205 -------------------- src/perf/lib/RpsServer.h | 74 -------- src/perf/lib/ThroughputClient.cpp | 17 +- src/perf/lib/ThroughputClient.h | 4 +- src/perf/lib/ThroughputServer.cpp | 202 -------------------- src/perf/lib/ThroughputServer.h | 69 ------- src/perf/lib/perflib.kernel.vcxproj | 5 +- src/perf/lib/quicmain.cpp | 55 +++--- 15 files changed, 473 insertions(+), 640 deletions(-) create mode 100644 src/perf/lib/PerfServer.cpp create mode 100644 src/perf/lib/PerfServer.h delete mode 100644 src/perf/lib/RpsServer.cpp delete mode 100644 src/perf/lib/RpsServer.h delete mode 100644 src/perf/lib/ThroughputServer.cpp delete mode 100644 src/perf/lib/ThroughputServer.h diff --git a/scripts/RemoteTests.json b/scripts/RemoteTests.json index b9053f1f4..1493967ac 100644 --- a/scripts/RemoteTests.json +++ b/scripts/RemoteTests.json @@ -7,7 +7,7 @@ "Arch": ["x64", "x86", "arm", "arm64"], "Exe": "quicperf", "Arguments": { - "All": "-TestName:Throughput -ServerMode:1 -port:4433 -peer_uni:1 -connections:10", + "All": "-ServerMode:1", "Loopback": "-selfsign:1", "Remote": "-thumbprint:$Thumbprint -machine_cert:1 -cert_store:My" } @@ -18,7 +18,7 @@ "Arch": ["x64", "x86", "arm", "arm64"], "Exe": "quicperf", "Arguments": { - "All": "-TestName:Throughput -target:$RemoteAddress -port:4433 -bind:$LocalAddress:4434 -ip:4 -core:0 -uni:1 -length:2000000000", + "All": "-ServerMode:0 -TestName:Throughput -target:$RemoteAddress -bind:$LocalAddress:4434 -ip:4 -core:0 -uni:1 -length:2000000000", "Loopback": "", "Remote": "" } @@ -32,7 +32,7 @@ }, "Remote": { "On": "", - "Off": "-encrypt:0" + "Off": "" }, "Default": "On" }, @@ -44,7 +44,7 @@ }, "Remote": { "On": "", - "Off": "-sendbuf:0" + "Off": "" }, "Default": "Off" } @@ -63,7 +63,7 @@ "Arch": ["x64", "arm"], "Exe": "quicperf", "Arguments": { - "All": "-TestName:Throughput -ServerMode:1 -port:4433 -selfsign:1 -peer_uni:1 -connections:10", + "All": "-ServerMode:1 -selfsign:1", "Loopback": "", "Remote": "" } @@ -74,7 +74,7 @@ "Arch": ["x64", "arm"], "Exe": "quicperf", "Arguments": { - "All": "-TestName:Throughput -target:$RemoteAddress -port:4433 -uni:1 -length:2000000000", + "All": "-ServerMode:0 -TestName:Throughput -target:$RemoteAddress -uni:1 -length:2000000000", "Loopback": "", "Remote": "" } @@ -88,7 +88,7 @@ }, "Remote": { "On": "", - "Off": "-encrypt:0" + "Off": "" }, "Default": "On" }, @@ -100,7 +100,7 @@ }, "Remote": { "On": "", - "Off": "-sendbuf:0" + "Off": "" }, "Default": "Off" } @@ -119,7 +119,7 @@ "Arch": ["x64", "x86", "arm", "arm64"], "Exe": "quicperf", "Arguments": { - "All": "-TestName:RPS -ServerMode:1 -iter:10", + "All": "-ServerMode:1", "Loopback": "-selfsign:1", "Remote": "-thumbprint:$Thumbprint -machine_cert:1 -cert_store:My" } @@ -130,7 +130,7 @@ "Arch": ["x64", "x86", "arm", "arm64"], "Exe": "quicperf", "Arguments": { - "All": "-TestName:RPS -target:$RemoteAddress", + "All": "-ServerMode:0 -TestName:RPS -target:$RemoteAddress", "Loopback": "", "Remote": "" } @@ -160,17 +160,17 @@ { "Name": "ResponseSize", "Local": { - "0": "", - "512": "", - "4096": "", - "16384": "" - }, - "Remote": { "0": "-response:0", "512": "-response:512", "4096": "-response:4096", "16384": "-response:16384" }, + "Remote": { + "0": "", + "512": "", + "4096": "", + "16384": "" + }, "Default": "4096" } ], diff --git a/src/perf/lib/CMakeLists.txt b/src/perf/lib/CMakeLists.txt index 7e6e210a9..a34a31934 100644 --- a/src/perf/lib/CMakeLists.txt +++ b/src/perf/lib/CMakeLists.txt @@ -2,11 +2,10 @@ # Licensed under the MIT License. set(SOURCES + PerfServer.cpp quicmain.cpp - ThroughputServer.cpp - ThroughputClient.cpp - RpsServer.cpp RpsClient.cpp + ThroughputClient.cpp ) # Allow CLOG to preprocess all the source files. diff --git a/src/perf/lib/PerfCommon.h b/src/perf/lib/PerfCommon.h index 7bcea4154..5054afa1e 100644 --- a/src/perf/lib/PerfCommon.h +++ b/src/perf/lib/PerfCommon.h @@ -12,28 +12,24 @@ Abstract: #pragma once -#define THROUGHPUT_DEFAULT_PORT 4433 -#define THROUGHPUT_ALPN "tput" -#define THROUGHPUT_DEFAULT_DISCONNECT_TIMEOUT (10 * 1000) -#define THROUGHPUT_DEFAULT_IDLE_TIMEOUT 1000 -#define THROUGHPUT_SERVER_PEER_UNI 1 -#define THROUGHPUT_CLIENT_UNI 1 -#define THROUGHPUT_DEFAULT_IO_SIZE_BUFFERED 0x10000 -#define THROUGHPUT_DEFAULT_IO_SIZE_NONBUFFERED 0x100000 -#define THROGHTPUT_DEFAULT_SEND_COUNT_BUFFERED 1 -#define THROUGHPUT_DEFAULT_SEND_COUNT_NONBUFFERED 8 +#define PERF_ALPN "perf" +#define PERF_DEFAULT_PORT 4433 +#define PERF_DEFAULT_DISCONNECT_TIMEOUT (10 * 1000) +#define PERF_DEFAULT_IDLE_TIMEOUT (30 * 1000) +#define PERF_DEFAULT_STREAM_COUNT 100 -#define RPS_ALPN "rps" -#define RPS_MAX_CLIENT_PORT_COUNT 256 -#define RPS_MAX_BIDI_STREAM_COUNT 100 -#define RPS_DEFAULT_PORT 4433 -#define RPS_DEFAULT_DISCONNECT_TIMEOUT (10 * 1000) -#define RPS_DEFAULT_IDLE_TIMEOUT 30000 -#define RPS_DEFAULT_ITERATIONS 1 -#define RPS_DEFAULT_RUN_TIME 10000 -#define RPS_DEFAULT_CONNECTION_COUNT 1000 -#define RPS_DEFAULT_PARALLEL_REQUEST_COUNT 2 -#define RPS_DEFAULT_REQUEST_LENGTH 0 -#define RPS_DEFAULT_RESPONSE_LENGTH 0 -#define RPS_ALL_CONNECT_TIMEOUT 10000 -#define RPS_IDLE_WAIT 2000 +#define PERF_DEFAULT_IO_SIZE_BUFFERED 0x10000 +#define PERF_DEFAULT_IO_SIZE_NONBUFFERED 0x100000 +#define PERF_DEFAULT_SEND_COUNT_BUFFERED 1 +#define PERF_DEFAULT_SEND_COUNT_NONBUFFERED 8 + +#define TPUT_DEFAULT_IDLE_TIMEOUT (1 * 1000) + +#define RPS_MAX_CLIENT_PORT_COUNT 256 +#define RPS_DEFAULT_RUN_TIME (10 * 1000) +#define RPS_DEFAULT_CONNECTION_COUNT 1000 +#define RPS_DEFAULT_PARALLEL_REQUEST_COUNT 2 +#define RPS_DEFAULT_REQUEST_LENGTH 0 +#define RPS_DEFAULT_RESPONSE_LENGTH 0 +#define RPS_ALL_CONNECT_TIMEOUT 10000 +#define RPS_IDLE_WAIT 2000 diff --git a/src/perf/lib/PerfServer.cpp b/src/perf/lib/PerfServer.cpp new file mode 100644 index 000000000..d408a9c24 --- /dev/null +++ b/src/perf/lib/PerfServer.cpp @@ -0,0 +1,281 @@ +/*++ + + Copyright (c) Microsoft Corporation. + Licensed under the MIT License. + +Abstract: + + QUIC Perf Server Implementation. + +--*/ + +#include "PerfServer.h" + +#ifdef QUIC_CLOG +#include "PerfServer.cpp.clog.h" +#endif + +static +void +PrintHelp( + ) { + WriteOutput( + "\n" + "Perf Server options:\n" + "\n" + " -port:<####> The UDP port of the server. (def:%u)\n" + " -selfsign:<0/1> Uses a self-signed server certificate.\n" + " -thumbprint: The hash or thumbprint of the certificate to use.\n" + " -cert_store: The certificate store to search for the thumbprint in.\n" + " -machine_cert:<0/1> Use the machine, or current user's, certificate store. (def:0)\n" + "\n", + PERF_DEFAULT_PORT + ); +} + +PerfServer::PerfServer( + _In_ PerfSelfSignedConfiguration* SelfSignedConfig + ) : SelfSignedConfig{SelfSignedConfig} { + if (Session.IsValid()) { + Session.SetAutoCleanup(); + Session.SetPeerBidiStreamCount(PERF_DEFAULT_STREAM_COUNT); + Session.SetPeerUnidiStreamCount(PERF_DEFAULT_STREAM_COUNT); + Session.SetDisconnectTimeout(PERF_DEFAULT_DISCONNECT_TIMEOUT); + Session.SetIdleTimeout(PERF_DEFAULT_IDLE_TIMEOUT); + } +} + +PerfServer::~PerfServer() { + if (DataBufferBuffered) { + QUIC_FREE(DataBufferBuffered); + } + if (DataBufferNonBuffered) { + QUIC_FREE(DataBufferNonBuffered); + } +} + +QUIC_STATUS +PerfServer::Init( + _In_ int argc, + _In_reads_(argc) _Null_terminated_ char* argv[] + ) { + if (argc > 0 && (IsArg(argv[0], "?") || IsArg(argv[0], "help"))) { + PrintHelp(); + return QUIC_STATUS_INVALID_PARAMETER; + } + + if (!Listener.IsValid()) { + return Listener.GetInitStatus(); + } + + TryGetValue(argc, argv, "port", &Port); + + QUIC_STATUS Status = SecurityConfig.Initialize(argc, argv, Registration, SelfSignedConfig); + if (QUIC_FAILED(Status)) { + PrintHelp(); + return Status; + } + + DataBufferBuffered = (QUIC_BUFFER*)QUIC_ALLOC_NONPAGED(sizeof(QUIC_BUFFER) + PERF_DEFAULT_IO_SIZE_BUFFERED); + if (!DataBufferBuffered) { + return QUIC_STATUS_OUT_OF_MEMORY; + } + DataBufferBuffered->Length = PERF_DEFAULT_IO_SIZE_BUFFERED; + DataBufferBuffered->Buffer = (uint8_t*)(DataBufferBuffered + 1); + for (uint32_t i = 0; i < PERF_DEFAULT_IO_SIZE_BUFFERED; ++i) { + DataBufferBuffered->Buffer[i] = (uint8_t)i; + } + + DataBufferNonBuffered = (QUIC_BUFFER*)QUIC_ALLOC_NONPAGED(sizeof(QUIC_BUFFER) + PERF_DEFAULT_IO_SIZE_NONBUFFERED); + if (!DataBufferNonBuffered) { + return QUIC_STATUS_OUT_OF_MEMORY; + } + DataBufferNonBuffered->Length = PERF_DEFAULT_IO_SIZE_BUFFERED; + DataBufferNonBuffered->Buffer = (uint8_t*)(DataBufferNonBuffered + 1); + for (uint32_t i = 0; i < PERF_DEFAULT_IO_SIZE_BUFFERED; ++i) { + DataBufferNonBuffered->Buffer[i] = (uint8_t)i; + } + + return QUIC_STATUS_SUCCESS; +} + +QUIC_STATUS +PerfServer::Start( + _In_ QUIC_EVENT* _StopEvent + ) { + QUIC_ADDR Address; + QuicAddrSetFamily(&Address, AF_UNSPEC); + QuicAddrSetPort(&Address, Port); + + StopEvent = _StopEvent; + + return + Listener.Start( + &Address, + [](HQUIC Handle, void* Context, QUIC_LISTENER_EVENT* Event) -> QUIC_STATUS { + return ((PerfServer*)Context)->ListenerCallback(Handle, Event); + }, + this); +} + +QUIC_STATUS +PerfServer::Wait( + _In_ int Timeout + ) { + if (Timeout > 0) { + QuicEventWaitWithTimeout(*StopEvent, Timeout); + } else { + QuicEventWaitForever(*StopEvent); + } + Session.Shutdown(QUIC_CONNECTION_SHUTDOWN_FLAG_NONE, 0); + return QUIC_STATUS_SUCCESS; +} + +QUIC_STATUS +PerfServer::ListenerCallback( + _In_ HQUIC /*ListenerHandle*/, + _Inout_ QUIC_LISTENER_EVENT* Event + ) { + switch (Event->Type) { + case QUIC_LISTENER_EVENT_NEW_CONNECTION: { + BOOLEAN value = TRUE; + if (QUIC_FAILED( + MsQuic->SetParam( + Event->NEW_CONNECTION.Connection, + QUIC_PARAM_LEVEL_CONNECTION, + QUIC_PARAM_CONN_DISABLE_1RTT_ENCRYPTION, + sizeof(value), + &value))) { + WriteOutput("MsQuic->SetParam (CONN_DISABLE_1RTT_ENCRYPTION) failed!\n"); + } + QUIC_CONNECTION_CALLBACK_HANDLER Handler = + [](HQUIC Conn, void* Context, QUIC_CONNECTION_EVENT* Event) -> QUIC_STATUS { + return ((PerfServer*)Context)-> + ConnectionCallback( + Conn, + Event); + }; + MsQuic->SetCallbackHandler(Event->NEW_CONNECTION.Connection, (void*)Handler, this); + Event->NEW_CONNECTION.SecurityConfig = SecurityConfig; + break; + } + } + return QUIC_STATUS_SUCCESS; +} + +QUIC_STATUS +PerfServer::ConnectionCallback( + _In_ HQUIC ConnectionHandle, + _Inout_ QUIC_CONNECTION_EVENT* Event + ) { + switch (Event->Type) { + case QUIC_CONNECTION_EVENT_SHUTDOWN_COMPLETE: + MsQuic->ConnectionClose(ConnectionHandle); + break; + case QUIC_CONNECTION_EVENT_PEER_STREAM_STARTED: { + auto Context = StreamContextAllocator.Alloc(this, Event->PEER_STREAM_STARTED.Flags & QUIC_STREAM_OPEN_FLAG_UNIDIRECTIONAL); + if (!Context) { + return QUIC_STATUS_OUT_OF_MEMORY; + } + QUIC_STREAM_CALLBACK_HANDLER Handler = + [](HQUIC Stream, void* Context, QUIC_STREAM_EVENT* Event) -> QUIC_STATUS { + return ((PerfServer::StreamContext*)Context)->Server-> + StreamCallback( + (PerfServer::StreamContext*)Context, + Stream, + Event); + }; + MsQuic->SetCallbackHandler(Event->PEER_STREAM_STARTED.Stream, (void*)Handler, Context); + break; + } + default: + break; + } + return QUIC_STATUS_SUCCESS; +} + +QUIC_STATUS +PerfServer::StreamCallback( + _In_ PerfServer::StreamContext* Context, + _In_ HQUIC StreamHandle, + _Inout_ QUIC_STREAM_EVENT* Event + ) { + switch (Event->Type) { + case QUIC_STREAM_EVENT_RECEIVE: + if (!Context->ResponseSizeSet) { + uint8_t* Dest = (uint8_t*)&Context->ResponseSize; + uint64_t Offset = Event->RECEIVE.AbsoluteOffset; + for (uint32_t i = 0; Offset < sizeof(uint64_t) && i < Event->RECEIVE.BufferCount; ++i) { + uint32_t Length = min((uint32_t)(sizeof(uint64_t) - Offset), Event->RECEIVE.Buffers[i].Length); + memcpy(Dest + Offset, Event->RECEIVE.Buffers[i].Buffer, Length); + Offset += Length; + } + if (Offset == sizeof(uint64_t)) { + Context->ResponseSize = QuicByteSwapUint64(Context->ResponseSize); + Context->ResponseSizeSet = true; + } + } + break; + case QUIC_STREAM_EVENT_SEND_COMPLETE: + Context->OutstandingSends--; + if (!Event->SEND_COMPLETE.Canceled) { + SendResponse(Context, StreamHandle); + } + break; + case QUIC_STREAM_EVENT_PEER_SEND_SHUTDOWN: + if (!Context->ResponseSizeSet) { + MsQuic->StreamShutdown(StreamHandle, QUIC_STREAM_SHUTDOWN_FLAG_ABORT, 0); + } else if (Context->ResponseSize != 0) { + if (Context->Unidirectional) { + // TODO - Not supported right now + MsQuic->StreamShutdown(StreamHandle, QUIC_STREAM_SHUTDOWN_FLAG_ABORT, 0); + } else { + SendResponse(Context, StreamHandle); + } + } else if (!Context->Unidirectional) { + MsQuic->StreamShutdown(StreamHandle, QUIC_STREAM_SHUTDOWN_FLAG_GRACEFUL, 0); + } + break; + case QUIC_STREAM_EVENT_PEER_SEND_ABORTED: + case QUIC_STREAM_EVENT_PEER_RECEIVE_ABORTED: + MsQuic->StreamShutdown(StreamHandle, QUIC_STREAM_SHUTDOWN_FLAG_ABORT, 0); + break; + case QUIC_STREAM_EVENT_SHUTDOWN_COMPLETE: { + MsQuic->StreamClose(StreamHandle); + StreamContextAllocator.Free(Context); + break; + default: + break; + } + } + return QUIC_STATUS_SUCCESS; +} + +void +PerfServer::SendResponse( + _In_ PerfServer::StreamContext* Context, + _In_ HQUIC StreamHandle + ) +{ + while (Context->BytesSent < Context->ResponseSize && + Context->OutstandingSends < Context->MaxOutstandingSends) { + + uint64_t BytesLeftToSend = Context->ResponseSize - Context->BytesSent; + uint32_t IoSize = Context->IoSize; + QUIC_BUFFER* Buffer = DataBufferNonBuffered; // TODO - Support buffered + QUIC_SEND_FLAGS Flags = QUIC_SEND_FLAG_NONE; + + if ((uint64_t)IoSize >= BytesLeftToSend) { + IoSize = (uint32_t)BytesLeftToSend; + Context->LastBuffer.Buffer = Buffer->Buffer; + Context->LastBuffer.Length = IoSize; + Buffer = &Context->LastBuffer; + Flags = QUIC_SEND_FLAG_FIN; + } + + Context->BytesSent += IoSize; + Context->OutstandingSends++; + + MsQuic->StreamSend(StreamHandle, Buffer, 1, Flags, nullptr); + } +} diff --git a/src/perf/lib/PerfServer.h b/src/perf/lib/PerfServer.h new file mode 100644 index 000000000..45cc29f7f --- /dev/null +++ b/src/perf/lib/PerfServer.h @@ -0,0 +1,96 @@ +/*++ + + Copyright (c) Microsoft Corporation. + Licensed under the MIT License. + +Abstract: + + QUIC Perf Server declaration. Defines the functions and + variables used in the PerfServer class. + +--*/ + +#pragma once + +#include "PerfHelpers.h" +#include "PerfBase.h" +#include "PerfCommon.h" + +class PerfServer : public PerfBase { +public: + PerfServer( + _In_ PerfSelfSignedConfiguration* SelfSignedConfig + ); + + ~PerfServer() override; + + QUIC_STATUS + Init( + _In_ int argc, + _In_reads_(argc) _Null_terminated_ char* argv[] + ) override; + + QUIC_STATUS + Start( + _In_ QUIC_EVENT* StopEvent + ) override; + + QUIC_STATUS + Wait( + int Timeout + ) override; + +private: + + struct StreamContext { + StreamContext( + PerfServer* Server, bool Unidirectional) : + Server{Server}, Unidirectional{Unidirectional} { } + PerfServer* Server; + bool Unidirectional; + bool BufferedIo{false}; + bool ResponseSizeSet{false}; + uint64_t ResponseSize{0}; + uint64_t BytesSent{0}; + uint32_t OutstandingSends{0}; + uint32_t MaxOutstandingSends{PERF_DEFAULT_SEND_COUNT_NONBUFFERED}; + uint32_t IoSize{PERF_DEFAULT_IO_SIZE_NONBUFFERED}; + QUIC_BUFFER LastBuffer; + }; + + QUIC_STATUS + ListenerCallback( + _In_ HQUIC ListenerHandle, + _Inout_ QUIC_LISTENER_EVENT* Event + ); + + QUIC_STATUS + ConnectionCallback( + _In_ HQUIC ConnectionHandle, + _Inout_ QUIC_CONNECTION_EVENT* Event + ); + + QUIC_STATUS + StreamCallback( + _In_ StreamContext* Context, + _In_ HQUIC StreamHandle, + _Inout_ QUIC_STREAM_EVENT* Event + ); + + void + SendResponse( + _In_ StreamContext* Context, + _In_ HQUIC StreamHandle + ); + + MsQuicRegistration Registration; + MsQuicSession Session {Registration, PERF_ALPN}; + MsQuicListener Listener {Session}; + PerfSelfSignedConfiguration* SelfSignedConfig; + PerfSecurityConfig SecurityConfig; + uint16_t Port {PERF_DEFAULT_PORT}; + QUIC_EVENT* StopEvent {nullptr}; + QUIC_BUFFER* DataBufferBuffered {nullptr}; + QUIC_BUFFER* DataBufferNonBuffered {nullptr}; + QuicPoolAllocator StreamContextAllocator; +}; diff --git a/src/perf/lib/RpsClient.cpp b/src/perf/lib/RpsClient.cpp index b82b0c7d5..1bea46dab 100644 --- a/src/perf/lib/RpsClient.cpp +++ b/src/perf/lib/RpsClient.cpp @@ -23,17 +23,20 @@ PrintHelp( "\n" "RPS Client options:\n" "\n" + " -target:<####> The target server to connect to.\n" " -runtime:<####> The total runtime (in ms). (def:%u)\n" " -port:<####> The UDP port of the server. (def:%u)\n" " -conns:<####> The number of connections to use. (def:%u)\n" " -parallel:<####> The number of parallel requests per connection. (def:%u)\n" " -request:<####> The length of request payloads. (def:%u)\n" + " -response:<####> The length of request payloads. (def:%u)\n" "\n", RPS_DEFAULT_RUN_TIME, - THROUGHPUT_DEFAULT_PORT, + PERF_DEFAULT_PORT, RPS_DEFAULT_CONNECTION_COUNT, RPS_DEFAULT_PARALLEL_REQUEST_COUNT, - RPS_DEFAULT_REQUEST_LENGTH + RPS_DEFAULT_REQUEST_LENGTH, + RPS_DEFAULT_RESPONSE_LENGTH ); } @@ -41,8 +44,8 @@ RpsClient::RpsClient() { QuicEventInitialize(&AllConnected, TRUE, FALSE); if (Session.IsValid()) { Session.SetAutoCleanup(); - Session.SetDisconnectTimeout(RPS_DEFAULT_DISCONNECT_TIMEOUT); - Session.SetIdleTimeout(RPS_DEFAULT_IDLE_TIMEOUT); + Session.SetDisconnectTimeout(PERF_DEFAULT_DISCONNECT_TIMEOUT); + Session.SetIdleTimeout(PERF_DEFAULT_IDLE_TIMEOUT); } } @@ -86,15 +89,17 @@ RpsClient::Init( TryGetValue(argc, argv, "port", &Port); TryGetValue(argc, argv, "conns", &ConnectionCount); TryGetValue(argc, argv, "request", &RequestLength); + TryGetValue(argc, argv, "response", &ResponseLength); - RequestBuffer = (QUIC_BUFFER*)QUIC_ALLOC_NONPAGED(sizeof(QUIC_BUFFER) + RequestLength); + RequestBuffer = (QUIC_BUFFER*)QUIC_ALLOC_NONPAGED(sizeof(QUIC_BUFFER) + sizeof(uint64_t) + RequestLength); if (!RequestBuffer) { return QUIC_STATUS_OUT_OF_MEMORY; } - RequestBuffer->Length = RequestLength; + RequestBuffer->Length = sizeof(uint64_t) + RequestLength; RequestBuffer->Buffer = (uint8_t*)(RequestBuffer + 1); + *(uint64_t*)(RequestBuffer->Buffer) = QuicByteSwapUint64(ResponseLength); for (uint32_t i = 0; i < RequestLength; ++i) { - RequestBuffer->Buffer[i] = (uint8_t)i; + RequestBuffer->Buffer[sizeof(uint64_t) + i] = (uint8_t)i; } return QUIC_STATUS_SUCCESS; diff --git a/src/perf/lib/RpsClient.h b/src/perf/lib/RpsClient.h index bf3ba8e25..b178b7ad2 100644 --- a/src/perf/lib/RpsClient.h +++ b/src/perf/lib/RpsClient.h @@ -59,13 +59,14 @@ private: ); MsQuicRegistration Registration; - MsQuicSession Session{Registration, RPS_ALPN}; - uint16_t Port {RPS_DEFAULT_PORT}; + MsQuicSession Session{Registration, PERF_ALPN}; + uint16_t Port {PERF_DEFAULT_PORT}; UniquePtr Target; uint32_t RunTime {RPS_DEFAULT_RUN_TIME}; uint32_t ConnectionCount {RPS_DEFAULT_CONNECTION_COUNT}; uint32_t ParallelRequests {RPS_DEFAULT_PARALLEL_REQUEST_COUNT}; uint32_t RequestLength {RPS_DEFAULT_REQUEST_LENGTH}; + uint32_t ResponseLength {RPS_DEFAULT_RESPONSE_LENGTH}; QUIC_BUFFER* RequestBuffer {nullptr}; QUIC_EVENT* CompletionEvent {nullptr}; QUIC_ADDR LocalAddresses[RPS_MAX_CLIENT_PORT_COUNT]; diff --git a/src/perf/lib/RpsServer.cpp b/src/perf/lib/RpsServer.cpp deleted file mode 100644 index 90ca03ea9..000000000 --- a/src/perf/lib/RpsServer.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/*++ - - Copyright (c) Microsoft Corporation. - Licensed under the MIT License. - -Abstract: - - QUIC Perf RPS Server Implementation. - ---*/ - -#include "RpsServer.h" - -#ifdef QUIC_CLOG -#include "RpsServer.cpp.clog.h" -#endif - -static -void -PrintHelp( - ) { - WriteOutput( - "\n" - "RPS Server options:\n" - "\n" - " -iter:<####> The number of client iterations run. (def:%u)\n" - " -port:<####> The UDP port of the server. (def:%u)\n" - " -thumbprint: The hash or thumbprint of the certificate to use.\n" - " -cert_store: The certificate store to search for the thumbprint in.\n" - " -machine_cert:<0/1> Use the machine, or current user's, certificate store. (def:0)\n" - " -response:<####> The length of response payloads. (def:%u)\n" - "\n", - RPS_DEFAULT_ITERATIONS, - RPS_DEFAULT_PORT, - RPS_DEFAULT_RESPONSE_LENGTH - ); -} - -RpsServer::RpsServer( - _In_ PerfSelfSignedConfiguration* SelfSignedConfig - ) : SelfSignedConfig(SelfSignedConfig) { - if (Session.IsValid()) { - Session.SetAutoCleanup(); - Session.SetPeerBidiStreamCount(RPS_MAX_BIDI_STREAM_COUNT); - Session.SetDisconnectTimeout(RPS_DEFAULT_DISCONNECT_TIMEOUT); - Session.SetIdleTimeout(RPS_DEFAULT_IDLE_TIMEOUT); - } -} - -RpsServer::~RpsServer() { - if (ResponseBuffer) { - QUIC_FREE(ResponseBuffer); - } -} - -QUIC_STATUS -RpsServer::Init( - _In_ int argc, - _In_reads_(argc) _Null_terminated_ char* argv[] - ) { - if (argc > 0 && (IsArg(argv[0], "?") || IsArg(argv[0], "help"))) { - PrintHelp(); - return QUIC_STATUS_INVALID_PARAMETER; - } - - if (!Listener.IsValid()) { - return Listener.GetInitStatus(); - } - - TryGetValue(argc, argv, "iter", &Iterations); - TryGetValue(argc, argv, "port", &Port); - TryGetValue(argc, argv, "response", &ResponseLength); - - ResponseBuffer = (QUIC_BUFFER*)QUIC_ALLOC_NONPAGED(sizeof(QUIC_BUFFER) + ResponseLength); - if (!ResponseBuffer) { - return QUIC_STATUS_OUT_OF_MEMORY; - } - ResponseBuffer->Length = ResponseLength; - ResponseBuffer->Buffer = (uint8_t*)(ResponseBuffer + 1); - for (uint32_t i = 0; i < ResponseLength; ++i) { - ResponseBuffer->Buffer[i] = (uint8_t)i; - } - - return SecurityConfig.Initialize(argc, argv, Registration, SelfSignedConfig); -} - -QUIC_STATUS -RpsServer::Start( - _In_ QUIC_EVENT* StopEvent - ) { - QUIC_ADDR Address; - QuicAddrSetFamily(&Address, AF_UNSPEC); - QuicAddrSetPort(&Address, Port); - - CompletionEvent = StopEvent; - - return - Listener.Start( - &Address, - [](HQUIC Handle, void* Context, QUIC_LISTENER_EVENT* Event) -> QUIC_STATUS { - return ((RpsServer*)Context)->ListenerCallback(Handle, Event); - }, - this); -} - -QUIC_STATUS -RpsServer::Wait( - _In_ int Timeout - ) { - if (Timeout > 0) { - QuicEventWaitWithTimeout(*CompletionEvent, Timeout); - } else { - QuicEventWaitForever(*CompletionEvent); - } - Session.Shutdown(QUIC_CONNECTION_SHUTDOWN_FLAG_NONE, 0); - return QUIC_STATUS_SUCCESS; -} - -QUIC_STATUS -RpsServer::ListenerCallback( - _In_ HQUIC /* ListenerHandle */, - _Inout_ QUIC_LISTENER_EVENT* Event - ) { - switch (Event->Type) { - case QUIC_LISTENER_EVENT_NEW_CONNECTION: { - Event->NEW_CONNECTION.SecurityConfig = SecurityConfig; - QUIC_CONNECTION_CALLBACK_HANDLER Handler = - [](HQUIC Conn, void* Context, QUIC_CONNECTION_EVENT* Event) -> QUIC_STATUS { - return ((RpsServer*)Context)-> - ConnectionCallback( - Conn, - Event); - }; - BOOLEAN Opt = FALSE; - MsQuic->SetParam( - Event->NEW_CONNECTION.Connection, - QUIC_PARAM_LEVEL_CONNECTION, - QUIC_PARAM_CONN_SEND_BUFFERING, - sizeof(Opt), - &Opt); - MsQuic->SetCallbackHandler( - Event->NEW_CONNECTION.Connection, - (void*)Handler, - this); - InterlockedIncrement((volatile long*)&ActiveConnectionCount); - break; - } - default: - break; - } - return QUIC_STATUS_SUCCESS; -} - -QUIC_STATUS -RpsServer::ConnectionCallback( - _In_ HQUIC ConnectionHandle, - _Inout_ QUIC_CONNECTION_EVENT* Event - ) { - switch (Event->Type) { - case QUIC_CONNECTION_EVENT_SHUTDOWN_COMPLETE: - MsQuic->ConnectionClose(ConnectionHandle); - if (InterlockedDecrement((volatile long*)&ActiveConnectionCount) == 0) { - if (InterlockedDecrement((volatile long*)&Iterations) == 0) { - QuicEventSet(*CompletionEvent); - } - } - break; - case QUIC_CONNECTION_EVENT_PEER_STREAM_STARTED: { - QUIC_STREAM_CALLBACK_HANDLER Handler = - [](HQUIC Stream, void* Context, QUIC_STREAM_EVENT* Event) -> QUIC_STATUS { - return ((RpsServer*)Context)-> - StreamCallback( - Stream, - Event); - }; - MsQuic->SetCallbackHandler(Event->PEER_STREAM_STARTED.Stream, (void*)Handler, this); - break; - } - default: - break; - } - return QUIC_STATUS_SUCCESS; -} - -QUIC_STATUS -RpsServer::StreamCallback( - _In_ HQUIC StreamHandle, - _Inout_ QUIC_STREAM_EVENT* Event - ) { - switch (Event->Type) { - case QUIC_STREAM_EVENT_PEER_SEND_SHUTDOWN: - MsQuic->StreamSend(StreamHandle, ResponseBuffer, 1, QUIC_SEND_FLAG_FIN, nullptr); - break; - case QUIC_STREAM_EVENT_PEER_SEND_ABORTED: - case QUIC_STREAM_EVENT_PEER_RECEIVE_ABORTED: - MsQuic->StreamShutdown(StreamHandle, QUIC_STREAM_SHUTDOWN_FLAG_ABORT, 0); - break; - case QUIC_STREAM_EVENT_SHUTDOWN_COMPLETE: - MsQuic->StreamClose(StreamHandle); - break; - default: - break; - } - return QUIC_STATUS_SUCCESS; -} diff --git a/src/perf/lib/RpsServer.h b/src/perf/lib/RpsServer.h deleted file mode 100644 index e4eacebd7..000000000 --- a/src/perf/lib/RpsServer.h +++ /dev/null @@ -1,74 +0,0 @@ -/*++ - - Copyright (c) Microsoft Corporation. - Licensed under the MIT License. - -Abstract: - - QUIC Perf RPS Server declaration. Defines the functions and variables used - in the RpsServer class. - ---*/ - -#pragma once - -#include "PerfHelpers.h" -#include "PerfBase.h" -#include "PerfCommon.h" - -class RpsServer : public PerfBase { -public: - RpsServer( - _In_ PerfSelfSignedConfiguration* SelfSignedConfig - ); - - ~RpsServer() override; - - QUIC_STATUS - Init( - _In_ int argc, - _In_reads_(argc) _Null_terminated_ char* argv[] - ) override; - - QUIC_STATUS - Start( - _In_ QUIC_EVENT* StopEvent - ) override; - - QUIC_STATUS - Wait( - int Timeout - ) override; - -private: - - QUIC_STATUS - ListenerCallback( - _In_ HQUIC ListenerHandle, - _Inout_ QUIC_LISTENER_EVENT* Event - ); - - QUIC_STATUS - ConnectionCallback( - _In_ HQUIC ConnectionHandle, - _Inout_ QUIC_CONNECTION_EVENT* Event - ); - - QUIC_STATUS - StreamCallback( - _In_ HQUIC StreamHandle, - _Inout_ QUIC_STREAM_EVENT* Event - ); - - MsQuicRegistration Registration; - MsQuicSession Session {Registration, RPS_ALPN}; - MsQuicListener Listener {Session}; - PerfSelfSignedConfiguration* SelfSignedConfig; - PerfSecurityConfig SecurityConfig; - uint32_t Iterations {RPS_DEFAULT_ITERATIONS}; - uint16_t Port {RPS_DEFAULT_PORT}; - uint32_t ResponseLength {RPS_DEFAULT_RESPONSE_LENGTH}; - uint32_t ActiveConnectionCount {0}; - QUIC_BUFFER* ResponseBuffer {nullptr}; - QUIC_EVENT* CompletionEvent {nullptr}; -}; diff --git a/src/perf/lib/ThroughputClient.cpp b/src/perf/lib/ThroughputClient.cpp index 53ebacb86..d6a00ddcc 100644 --- a/src/perf/lib/ThroughputClient.cpp +++ b/src/perf/lib/ThroughputClient.cpp @@ -23,6 +23,7 @@ PrintHelp( "\n" "Throughput Client options:\n" "\n" + " -target:<####> The target server to connect to.\n" #if _WIN32 " -comp:<####> The compartment ID to run in.\n" " -core:<####> The CPU core to use for the main thread.\n" @@ -36,9 +37,9 @@ PrintHelp( " -iosize:<####> The size of each send request queued. (buffered def:%u) (nonbuffered def:%u)\n" " -iocount:<####> The number of outstanding send requests to queue per stream. (buffered def:%u) (nonbuffered def:%u)\n" "\n", - THROUGHPUT_DEFAULT_PORT, - THROUGHPUT_DEFAULT_IO_SIZE_BUFFERED, THROUGHPUT_DEFAULT_IO_SIZE_NONBUFFERED, - THROGHTPUT_DEFAULT_SEND_COUNT_BUFFERED, THROUGHPUT_DEFAULT_SEND_COUNT_NONBUFFERED + PERF_DEFAULT_PORT, + PERF_DEFAULT_IO_SIZE_BUFFERED, PERF_DEFAULT_IO_SIZE_NONBUFFERED, + PERF_DEFAULT_SEND_COUNT_BUFFERED, PERF_DEFAULT_SEND_COUNT_NONBUFFERED ); } @@ -46,6 +47,7 @@ ThroughputClient::ThroughputClient( ) { QuicZeroMemory(&LocalIpAddr, sizeof(LocalIpAddr)); if (Session.IsValid()) { + Session.SetIdleTimeout(TPUT_DEFAULT_IDLE_TIMEOUT); Session.SetAutoCleanup(); } } @@ -115,10 +117,10 @@ ThroughputClient::Init( TryGetValue(argc, argv, "sendbuf", &UseSendBuffer); - IoSize = UseSendBuffer ? THROUGHPUT_DEFAULT_IO_SIZE_BUFFERED : THROUGHPUT_DEFAULT_IO_SIZE_NONBUFFERED; + IoSize = UseSendBuffer ? PERF_DEFAULT_IO_SIZE_BUFFERED : PERF_DEFAULT_IO_SIZE_NONBUFFERED; TryGetValue(argc, argv, "iosize", &IoSize); - IoCount = UseSendBuffer ? THROGHTPUT_DEFAULT_SEND_COUNT_BUFFERED : THROUGHPUT_DEFAULT_SEND_COUNT_NONBUFFERED; + IoCount = UseSendBuffer ? PERF_DEFAULT_SEND_COUNT_BUFFERED : PERF_DEFAULT_SEND_COUNT_NONBUFFERED; TryGetValue(argc, argv, "iocount", &IoCount); size_t Len = strlen(Target); @@ -274,6 +276,9 @@ ThroughputClient::Start( while (StrmData->BytesSent < Length && SendRequestCount < IoCount) { SendRequest* SendReq = SendRequestAllocator.Alloc(&BufferAllocator, IoSize, true); SendReq->SetLength(Length - StrmData->BytesSent); + if (StrmData->BytesSent == 0) { + QuicZeroMemory(SendReq->QuicBuffer.Buffer, sizeof(uint64_t)); + } StrmData->BytesSent += SendReq->QuicBuffer.Length; ++SendRequestCount; Status = @@ -300,7 +305,7 @@ ThroughputClient::Start( WriteOutput("Failed ConnectionStart 0x%x\n", Status); return Status; } - WriteOutput("Started!\n"); + Shutdown.ConnHandle = nullptr; return Status; } diff --git a/src/perf/lib/ThroughputClient.h b/src/perf/lib/ThroughputClient.h index 4664d97a2..2f99819d5 100644 --- a/src/perf/lib/ThroughputClient.h +++ b/src/perf/lib/ThroughputClient.h @@ -82,13 +82,13 @@ private: ); MsQuicRegistration Registration; - MsQuicSession Session{Registration, THROUGHPUT_ALPN}; + MsQuicSession Session{Registration, PERF_ALPN}; QuicPoolAllocator StreamDataAllocator; QuicPoolAllocator ConnectionDataAllocator; QuicPoolAllocator SendRequestAllocator; QuicPoolBufferAllocator BufferAllocator; UniquePtr TargetData; - uint16_t Port {THROUGHPUT_DEFAULT_PORT}; + uint16_t Port {PERF_DEFAULT_PORT}; QUIC_EVENT* StopEvent {nullptr}; uint64_t Length {0}; // FIXME: unused: bool ConstructionSuccess {false}; diff --git a/src/perf/lib/ThroughputServer.cpp b/src/perf/lib/ThroughputServer.cpp deleted file mode 100644 index 99e17c851..000000000 --- a/src/perf/lib/ThroughputServer.cpp +++ /dev/null @@ -1,202 +0,0 @@ -/*++ - - Copyright (c) Microsoft Corporation. - Licensed under the MIT License. - -Abstract: - - QUIC Perf Throughput Server Implementation. - ---*/ - -#include "ThroughputServer.h" - -#ifdef QUIC_CLOG -#include "ThroughputServer.cpp.clog.h" -#endif - -static -void -PrintHelp( - ) { - WriteOutput( - "\n" - "Throughput Server options:\n" - "\n" - " -thumbprint: The hash or thumbprint of the certificate to use.\n" - " -cert_store: The certificate store to search for the thumbprint in.\n" - " -machine_cert:<0/1> Use the machine, or current user's, certificate store. (def:0)\n" - " -connections:<####> The number of connections to create. (def:0)\n" - " -port:<####> The UDP port of the server. (def:%u)\n" - "\n", - THROUGHPUT_DEFAULT_PORT - ); -} - -ThroughputServer::ThroughputServer( - _In_ PerfSelfSignedConfiguration* SelfSignedConfig - ) : SelfSignedConfig{SelfSignedConfig} { - if (Session.IsValid()) { - Session.SetAutoCleanup(); - Session.SetPeerUnidiStreamCount(THROUGHPUT_SERVER_PEER_UNI); - Session.SetDisconnectTimeout(THROUGHPUT_DEFAULT_DISCONNECT_TIMEOUT); - Session.SetIdleTimeout(THROUGHPUT_DEFAULT_IDLE_TIMEOUT); - } -} - -QUIC_STATUS -ThroughputServer::Init( - _In_ int argc, - _In_reads_(argc) _Null_terminated_ char* argv[] - ) { - if (argc > 0 && (IsArg(argv[0], "?") || IsArg(argv[0], "help"))) { - PrintHelp(); - return QUIC_STATUS_INVALID_PARAMETER; - } - - if (!Listener.IsValid()) { - return Listener.GetInitStatus(); - } - - TryGetValue(argc, argv, "port", &Port); - TryGetValue(argc, argv, "connections", &NumberOfConnections); - - QUIC_STATUS Status = SecurityConfig.Initialize(argc, argv, Registration, SelfSignedConfig); - if (QUIC_FAILED(Status)) { - PrintHelp(); - return Status; - } - - return QUIC_STATUS_SUCCESS; -} - -QUIC_STATUS -ThroughputServer::Start( - _In_ QUIC_EVENT* StopEvent - ) { - QUIC_ADDR Address; - QuicAddrSetFamily(&Address, AF_UNSPEC); - QuicAddrSetPort(&Address, Port); - - QUIC_STATUS Status = - Listener.Start( - &Address, - [](HQUIC Handle, void* Context, QUIC_LISTENER_EVENT* Event) -> QUIC_STATUS { - return ((ThroughputServer*)Context)->ListenerCallback(Handle, Event); - }, - this); - if (QUIC_FAILED(Status)) { - return Status; - } - RefCount = CountHelper{StopEvent}; - if (NumberOfConnections > 0) { - for (uint32_t i = 0; i < NumberOfConnections; i++) { - RefCount.AddItem(); - } - } else { - // - // Add a single item so we can wait on the Count Helper - // - RefCount.AddItem(); - } - return QUIC_STATUS_SUCCESS; -} - -QUIC_STATUS -ThroughputServer::Wait( - _In_ int Timeout - ) { - if (Timeout > 0) { - RefCount.Wait(Timeout); - } else { - RefCount.WaitForever(); - } - return QUIC_STATUS_SUCCESS; -} - -QUIC_STATUS -ThroughputServer::ListenerCallback( - _In_ HQUIC /*ListenerHandle*/, - _Inout_ QUIC_LISTENER_EVENT* Event - ) { - switch (Event->Type) { - case QUIC_LISTENER_EVENT_NEW_CONNECTION: { - Event->NEW_CONNECTION.SecurityConfig = SecurityConfig; - QUIC_CONNECTION_CALLBACK_HANDLER Handler = - [](HQUIC Conn, void* Context, QUIC_CONNECTION_EVENT* Event) -> QUIC_STATUS { - return ((ThroughputServer*)Context)-> - ConnectionCallback( - Conn, - Event); - }; - MsQuic->SetCallbackHandler( - Event->NEW_CONNECTION.Connection, - (void*)Handler, - this); - BOOLEAN value = TRUE; - if (QUIC_FAILED( - MsQuic->SetParam( - Event->NEW_CONNECTION.Connection, - QUIC_PARAM_LEVEL_CONNECTION, - QUIC_PARAM_CONN_DISABLE_1RTT_ENCRYPTION, - sizeof(value), - &value))) { - WriteOutput("MsQuic->SetParam (CONN_DISABLE_1RTT_ENCRYPTION) failed!\n"); - } - break; - } - } - return QUIC_STATUS_SUCCESS; -} - -QUIC_STATUS -ThroughputServer::ConnectionCallback( - _In_ HQUIC ConnectionHandle, - _Inout_ QUIC_CONNECTION_EVENT* Event - ) { - switch (Event->Type) { - case QUIC_CONNECTION_EVENT_SHUTDOWN_COMPLETE: - MsQuic->ConnectionClose(ConnectionHandle); - if (NumberOfConnections > 0) { - RefCount.CompleteItem(); - } - break; - case QUIC_CONNECTION_EVENT_PEER_STREAM_STARTED: { - QUIC_STREAM_CALLBACK_HANDLER Handler = - [](HQUIC Stream, void* Context, QUIC_STREAM_EVENT* Event) -> QUIC_STATUS { - return ((ThroughputServer*)Context)-> - StreamCallback( - Stream, - Event); - }; - MsQuic->SetCallbackHandler(Event->PEER_STREAM_STARTED.Stream, (void*)Handler, this); - break; - } - default: - break; - } - return QUIC_STATUS_SUCCESS; -} - -QUIC_STATUS -ThroughputServer::StreamCallback( - _In_ HQUIC StreamHandle, - _Inout_ QUIC_STREAM_EVENT* Event - ) { - switch (Event->Type) { - case QUIC_STREAM_EVENT_PEER_SEND_ABORTED: - case QUIC_STREAM_EVENT_PEER_RECEIVE_ABORTED: - MsQuic->StreamShutdown( - StreamHandle, - QUIC_STREAM_SHUTDOWN_FLAG_ABORT_SEND | QUIC_STREAM_SHUTDOWN_FLAG_ABORT_RECEIVE, - 0); - break; - case QUIC_STREAM_EVENT_SHUTDOWN_COMPLETE: { - MsQuic->StreamClose(StreamHandle); - break; - default: - break; - } - } - return QUIC_STATUS_SUCCESS; -} diff --git a/src/perf/lib/ThroughputServer.h b/src/perf/lib/ThroughputServer.h deleted file mode 100644 index ac790aecb..000000000 --- a/src/perf/lib/ThroughputServer.h +++ /dev/null @@ -1,69 +0,0 @@ -/*++ - - Copyright (c) Microsoft Corporation. - Licensed under the MIT License. - -Abstract: - - QUIC Perf Throughput Server declaration. Defines the functions and - variables used in the ThroughputServer class. - ---*/ - -#pragma once - -#include "PerfHelpers.h" -#include "PerfBase.h" -#include "PerfCommon.h" - -class ThroughputServer : public PerfBase { -public: - ThroughputServer( - _In_ PerfSelfSignedConfiguration* SelfSignedConfig - ); - - QUIC_STATUS - Init( - _In_ int argc, - _In_reads_(argc) _Null_terminated_ char* argv[] - ) override; - - QUIC_STATUS - Start( - _In_ QUIC_EVENT* StopEvent - ) override; - - QUIC_STATUS - Wait( - int Timeout - ) override; - -private: - - QUIC_STATUS - ListenerCallback( - _In_ HQUIC ListenerHandle, - _Inout_ QUIC_LISTENER_EVENT* Event - ); - - QUIC_STATUS - ConnectionCallback( - _In_ HQUIC ConnectionHandle, - _Inout_ QUIC_CONNECTION_EVENT* Event - ); - - QUIC_STATUS - StreamCallback( - _In_ HQUIC StreamHandle, - _Inout_ QUIC_STREAM_EVENT* Event - ); - - MsQuicRegistration Registration; - MsQuicSession Session {Registration, THROUGHPUT_ALPN}; - MsQuicListener Listener {Session}; - PerfSelfSignedConfiguration* SelfSignedConfig; - PerfSecurityConfig SecurityConfig; - uint16_t Port {THROUGHPUT_DEFAULT_PORT}; - uint32_t NumberOfConnections {0}; - CountHelper RefCount; -}; diff --git a/src/perf/lib/perflib.kernel.vcxproj b/src/perf/lib/perflib.kernel.vcxproj index 8515bf317..b6106d10b 100644 --- a/src/perf/lib/perflib.kernel.vcxproj +++ b/src/perf/lib/perflib.kernel.vcxproj @@ -35,11 +35,10 @@ + - - - + diff --git a/src/perf/lib/quicmain.cpp b/src/perf/lib/quicmain.cpp index e4136a94c..7a94b3601 100644 --- a/src/perf/lib/quicmain.cpp +++ b/src/perf/lib/quicmain.cpp @@ -10,9 +10,8 @@ Abstract: --*/ #include "PerfHelpers.h" -#include "ThroughputServer.h" +#include "PerfServer.h" #include "ThroughputClient.h" -#include "RpsServer.h" #include "RpsClient.h" #ifdef QUIC_CLOG @@ -39,7 +38,7 @@ PrintHelp( ) { WriteOutput( "\n" - "Usage: quicperf -TestName: [-ServerMode:<1:0>] [options]\n" + "Usage: quicperf -ServerMode:<1:0> [-TestName:] [options]\n" "\n" ); } @@ -58,21 +57,16 @@ QuicMainStart( return QUIC_STATUS_INVALID_PARAMETER; } - if (!IsArg(argv[0], "TestName")) { - WriteOutput("Must specify -TestName argument\n"); + ServerMode = 0; + if (!IsArg(argv[0], "ServerMode")) { + WriteOutput("Must specify -ServerMode argument\n"); PrintHelp(); return QUIC_STATUS_INVALID_PARAMETER; } - const char* TestName = GetValue(argc, argv, "TestName"); + TryGetValue(argc, argv, "ServerMode", &ServerMode); argc--; argv++; - ServerMode = 0; - if (argc != 0 && IsArg(argv[0], "ServerMode")) { - TryGetValue(argc, argv, "ServerMode", &ServerMode); - argc--; argv++; - } - QUIC_STATUS Status; if (ServerMode) { @@ -91,7 +85,6 @@ QuicMainStart( } } - MsQuic = new(std::nothrow) QuicApiTable; if (MsQuic == nullptr) { return QUIC_STATUS_OUT_OF_MEMORY; @@ -102,21 +95,29 @@ QuicMainStart( return Status; } - if (IsValue(TestName, "Throughput")) { - if (ServerMode) { - TestToRun = new(std::nothrow) ThroughputServer(SelfSignedConfig); - } else { - TestToRun = new(std::nothrow) ThroughputClient; - } - } else if (IsValue(TestName, "RPS")) { - if (ServerMode) { - TestToRun = new(std::nothrow) RpsServer(SelfSignedConfig); - } else { - TestToRun = new(std::nothrow) RpsClient; - } + if (ServerMode) { + TestToRun = new(std::nothrow) PerfServer(SelfSignedConfig); + } else { - delete MsQuic; - return QUIC_STATUS_INVALID_PARAMETER; + if (!IsArg(argv[0], "TestName")) { + WriteOutput("Must specify -TestName argument\n"); + PrintHelp(); + delete MsQuic; + MsQuic = nullptr; + return QUIC_STATUS_INVALID_PARAMETER; + } + + const char* TestName = GetValue(argc, argv, "TestName"); + argc--; argv++; + + if (IsValue(TestName, "Throughput")) { + TestToRun = new(std::nothrow) ThroughputClient; + } else if (IsValue(TestName, "RPS")) { + TestToRun = new(std::nothrow) RpsClient; + } else { + delete MsQuic; + return QUIC_STATUS_INVALID_PARAMETER; + } } if (TestToRun != nullptr) {