int __cdecl wmain()

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);
}