in ctsTraffic/ctsTraffic.cpp [46:211]
int __cdecl wmain(int argc, _In_reads_z_(argc) const wchar_t** argv)
{
WSADATA wsadata{};
auto err = WSAStartup(WINSOCK_VERSION, &wsadata);
if (err != 0)
{
wprintf(L"ctsTraffic failed at WSAStartup [%d]\n", err);
return err;
}
try
{
if (!ctsConfig::Startup(argc, argv))
{
ctsConfig::Shutdown();
err = ERROR_INVALID_DATA;
}
}
catch (const invalid_argument& e)
{
ctsConfig::PrintErrorInfoOverride(wil::str_printf<std::wstring>(L"Invalid argument specified: %hs", e.what()).c_str());
ctsConfig::Shutdown();
err = ERROR_INVALID_DATA;
}
catch (const exception& e)
{
ctsConfig::PrintExceptionOverride(e.what());
ctsConfig::Shutdown();
err = ERROR_INVALID_DATA;
}
if (err == ERROR_INVALID_DATA)
{
wprintf(
L"\n\n"
L"For more information on command line options, specify -Help\n"
L"ctsTraffic.exe -Help:[tcp] [udp] [logging] [advanced]\n"
L"\t- <default> == prints this usage statement\n"
L"\t- tcp : prints usage for TCP-specific options\n"
L"\t- udp : prints usage for UDP-specific options\n"
L"\t- logging : prints usage for logging options\n"
L"\t- advanced : prints the usage for advanced and experimental options\n"
L"\n\n");
return err;
}
try
{
if (!SetConsoleCtrlHandler(CtrlBreakHandlerRoutine, TRUE))
{
THROW_WIN32_MSG(GetLastError(), "SetConsoleCtrlHandler");
}
ctsConfig::PrintSettings();
ctsConfig::PrintLegend();
// set the start timer as close as possible to the start of the engine
ctsConfig::g_configSettings->StartTimeMilliseconds = ctTimer::SnapQpcInMillis();
const auto broker(std::make_shared<ctsSocketBroker>());
g_socketBroker = broker.get();
broker->Start();
ctThreadpoolTimer statusTimer;
statusTimer.schedule_reoccuring(ctsConfig::PrintStatusUpdate, 0LL, ctsConfig::g_configSettings->StatusUpdateFrequencyMilliseconds);
// define this is testing the shutdown path to force a clean shutdown while running
// #define DEBUGGING_CTSTRAFFIC
#ifdef DEBUGGING_CTSTRAFFIC
getchar();
#else
if (!broker->Wait(ctsConfig::g_configSettings->TimeLimit > 0 ? ctsConfig::g_configSettings->TimeLimit : INFINITE))
{
ctsConfig::PrintSummary(L"\n ** Time-limit of %lu reached **\n", ctsConfig::g_configSettings->TimeLimit);
}
#endif
}
catch (const wil::ResultException& e)
{
ctsConfig::PrintExceptionOverride(e.what());
ctsConfig::Shutdown();
return e.GetErrorCode();
}
catch (const bad_alloc&)
{
ctsConfig::PrintErrorInfoOverride(L"ctsTraffic failed: Out of Memory");
ctsConfig::Shutdown();
return ERROR_OUTOFMEMORY;
}
catch (const exception& e)
{
ctsConfig::PrintErrorInfoOverride(wil::str_printf<std::wstring>(L"ctsTraffic failed: %hs", e.what()).c_str());
ctsConfig::Shutdown();
return ERROR_CANCELLED;
}
const auto totalTimeRun = ctTimer::SnapQpcInMillis() - ctsConfig::g_configSettings->StartTimeMilliseconds;
// write out the final status update
ctsConfig::PrintStatusUpdate();
ctsConfig::Shutdown();
ctsConfig::PrintSummary(
L"\n\n"
L" Historic Connection Statistics (all connections over the complete lifetime) \n"
L"-------------------------------------------------------------------------------\n"
L" SuccessfulConnections [%lld] NetworkErrors [%lld] ProtocolErrors [%lld]\n",
ctsConfig::g_configSettings->ConnectionStatusDetails.m_successfulCompletionCount.GetValue(),
ctsConfig::g_configSettings->ConnectionStatusDetails.m_connectionErrorCount.GetValue(),
ctsConfig::g_configSettings->ConnectionStatusDetails.m_protocolErrorCount.GetValue());
if (ctsConfig::g_configSettings->Protocol == ctsConfig::ProtocolType::TCP)
{
ctsConfig::PrintSummary(
L"\n"
L" Total Bytes Recv : %lld\n"
L" Total Bytes Sent : %lld\n",
ctsConfig::g_configSettings->TcpStatusDetails.m_bytesRecv.GetValue(),
ctsConfig::g_configSettings->TcpStatusDetails.m_bytesSent.GetValue());
}
else
{
// currently don't track UDP server stats
if (!ctsConfig::IsListening())
{
const auto successfulFrames = ctsConfig::g_configSettings->UdpStatusDetails.m_successfulFrames.GetValue();
const auto droppedFrames = ctsConfig::g_configSettings->UdpStatusDetails.m_droppedFrames.GetValue();
const auto duplicateFrames = ctsConfig::g_configSettings->UdpStatusDetails.m_duplicateFrames.GetValue();
const auto errorFrames = ctsConfig::g_configSettings->UdpStatusDetails.m_errorFrames.GetValue();
const auto totalFrames =
successfulFrames +
droppedFrames +
duplicateFrames +
errorFrames;
ctsConfig::PrintSummary(
L"\n"
L" Total Bytes Recv : %lld\n"
L" Total Successful Frames : %lld (%f)\n"
L" Total Dropped Frames : %lld (%f)\n"
L" Total Duplicate Frames : %lld (%f)\n"
L" Total Error Frames : %lld (%f)\n",
ctsConfig::g_configSettings->UdpStatusDetails.m_bitsReceived.GetValue() / 8LL,
successfulFrames,
totalFrames > 0 ? static_cast<double>(successfulFrames) / static_cast<double>(totalFrames) * 100.0 : 0.0,
droppedFrames,
totalFrames > 0 ? static_cast<double>(droppedFrames) / static_cast<double>(totalFrames) * 100.0 : 0.0,
duplicateFrames,
totalFrames > 0 ? static_cast<double>(duplicateFrames) / static_cast<double>(totalFrames) * 100.0 : 0.0,
errorFrames,
totalFrames > 0 ? static_cast<double>(errorFrames) / static_cast<double>(totalFrames) * 100.0 : 0.0);
}
}
ctsConfig::PrintSummary(
L" Total Time : %lld ms.\n", totalTimeRun);
int64_t errorCount =
ctsConfig::g_configSettings->ConnectionStatusDetails.m_connectionErrorCount.GetValue() +
ctsConfig::g_configSettings->ConnectionStatusDetails.m_protocolErrorCount.GetValue();
if (errorCount > MAXINT)
{
errorCount = MAXINT;
}
return static_cast<int>(errorCount);
}