void PrintSettings()

in ctsTraffic/ctsConfig.cpp [4236:4588]


void PrintSettings()
{
    ctsConfigInitOnce();

    wstring settingString(
        L"  Configured Settings  \n"
        L"-----------------------\n");

    settingString.append(L"\tProtocol: ");
    switch (g_configSettings->Protocol)
    {
        case ProtocolType::TCP:
            settingString.append(L"TCP");
            break;
        case ProtocolType::UDP:
            settingString.append(L"UDP");
            break;

        case ProtocolType::NoProtocolSet:
            [[fallthrough]];
        default:
            FAIL_FAST_MSG("Unexpected Settings Protocol");
    }
    settingString.append(L"\n");

    settingString.append(L"\tOptions:");
    if (NoOptionSet == g_configSettings->Options)
    {
        settingString.append(L" None");
    }
    else
    {
        if (g_configSettings->Options & LoopbackFastPath)
        {
            settingString.append(L" TCPFastPath");
        }
        if (g_configSettings->KeepAliveValue > 0)
        {
            settingString.append(L" KeepAlive (");
            settingString.append(std::to_wstring(g_configSettings->KeepAliveValue));
            settingString.append(L")");
        }
        else if (g_configSettings->Options & Keepalive)
        {
            settingString.append(L" KeepAlive");
        }
        if (g_configSettings->Options & NonBlockingIo)
        {
            settingString.append(L" NonBlockingIO");
        }
        if (g_configSettings->Options & HandleInlineIocp)
        {
            settingString.append(L" InlineIOCP");
        }
        if (g_configSettings->Options & ReuseUnicastPort)
        {
            settingString.append(L" ReuseUnicastPort");
        }
        if (g_configSettings->Options & SetRecvBuf)
        {
            settingString.append(wil::str_printf<std::wstring>(L" SO_RCVBUF(%lu)", g_configSettings->RecvBufValue));
        }
        if (g_configSettings->Options & SetSendBuf)
        {
            settingString.append(wil::str_printf<std::wstring>(L" SO_SNDBUF(%lu)", g_configSettings->SendBufValue));
        }
        if (g_configSettings->Options & MsgWaitAll)
        {
            settingString.append(L" MsgWaitAll");
        }
    }
    settingString.append(L"\n");

    settingString.append(wil::str_printf<std::wstring>(L"\tIO function: %ws\n", g_ioFunctionName));

    settingString.append(L"\tIoPattern: ");
    switch (g_configSettings->IoPattern)
    {
        case IoPatternType::Pull:
            settingString.append(L"Pull <TCP client recv/server send>\n");
            break;
        case IoPatternType::Push:
            settingString.append(L"Push <TCP client send/server recv>\n");
            break;
        case IoPatternType::PushPull:
            settingString.append(L"PushPull <TCP client/server alternate send/recv>\n");
            settingString.append(wil::str_printf<std::wstring>(L"\t\tPushBytes: %lu\n", g_configSettings->PushBytes));
            settingString.append(wil::str_printf<std::wstring>(L"\t\tPullBytes: %lu\n", g_configSettings->PullBytes));
            break;
        case IoPatternType::Duplex:
            settingString.append(L"Duplex <TCP client/server both sending and receiving>\n");
            break;
        case IoPatternType::MediaStream:
            settingString.append(L"MediaStream <UDP controlled stream from server to client>\n");
            break;

        case IoPatternType::NoIoSet:
            [[fallthrough]];
        default:
            FAIL_FAST_MSG("Unexpected Settings IoPattern");
    }

    settingString.append(wil::str_printf<std::wstring>(L"\tPrePostRecvs: %u\n", g_configSettings->PrePostRecvs));

    if (g_configSettings->PrePostSends > 0)
    {
        settingString.append(wil::str_printf<std::wstring>(L"\tPrePostSends: %u\n", g_configSettings->PrePostSends));
    }
    else
    {
        settingString.append(wil::str_printf<std::wstring>(L"\tPrePostSends: Following Ideal Send Backlog\n"));
    }

    settingString.append(
        wil::str_printf<std::wstring>(
            L"\tLevel of verification: %ws\n",
            g_configSettings->ShouldVerifyBuffers ? L"Connections & Data" : L"Connections"));

    settingString.append(wil::str_printf<std::wstring>(L"\tPort: %u\n", g_configSettings->Port));

    if (0 == g_bufferSizeHigh)
    {
        settingString.append(
            wil::str_printf<std::wstring>(
                L"\tBuffer used for each IO request: %u [0x%x] bytes\n",
                g_bufferSizeLow, g_bufferSizeLow));
    }
    else
    {
        settingString.append(
            wil::str_printf<std::wstring>(
                L"\tBuffer used for each IO request: [%u, %u] bytes\n",
                g_bufferSizeLow, g_bufferSizeHigh));
    }

    if (0 == g_transferSizeHigh)
    {
        settingString.append(
            wil::str_printf<std::wstring>(
                L"\tTotal transfer per connection: %llu bytes\n",
                g_transferSizeLow));
    }
    else
    {
        settingString.append(
            wil::str_printf<std::wstring>(
                L"\tTotal transfer per connection: [%llu, %llu] bytes\n",
                g_transferSizeLow, g_transferSizeHigh));
    }

    if (ProtocolType::UDP == g_configSettings->Protocol)
    {
        settingString.append(
            wil::str_printf<std::wstring>(
                L"\t\tUDP Stream BitsPerSecond: %lld bits per second\n",
                g_mediaStreamSettings.BitsPerSecond));
        settingString.append(
            wil::str_printf<std::wstring>(
                L"\t\tUDP Stream FrameRate: %lu frames per second\n",
                g_mediaStreamSettings.FramesPerSecond));

        if (g_mediaStreamSettings.BufferDepthSeconds > 0)
        {
            settingString.append(
                wil::str_printf<std::wstring>(
                    L"\t\tUDP Stream BufferDepth: %lu seconds\n",
                    g_mediaStreamSettings.BufferDepthSeconds));
        }

        settingString.append(
            wil::str_printf<std::wstring>(
                L"\t\tUDP Stream StreamLength: %lu seconds (%lu frames)\n",
                g_mediaStreamSettings.StreamLengthSeconds,
                g_mediaStreamSettings.StreamLengthFrames));
        settingString.append(
            wil::str_printf<std::wstring>(
                L"\t\tUDP Stream FrameSize: %lu bytes\n",
                g_mediaStreamSettings.FrameSizeBytes));
    }

    if (ProtocolType::TCP == g_configSettings->Protocol && g_rateLimitLow > 0)
    {
        if (0 == g_rateLimitHigh)
        {
            settingString.append(
                wil::str_printf<std::wstring>(
                    L"\tSending throughput rate limited down to %lld bytes/second\n",
                    g_rateLimitLow));
        }
        else
        {
            settingString.append(
                wil::str_printf<std::wstring>(
                    L"\tSending throughput rate limited down to a range of [%lld, %lld] bytes/second\n",
                    g_rateLimitLow, g_rateLimitHigh));
        }
    }

    if (g_netAdapterAddresses != nullptr)
    {
        settingString.append(
            wil::str_printf<std::wstring>(
                L"\tIP Compartment: %u\n", g_compartmentId));
    }

    if (!g_configSettings->ListenAddresses.empty())
    {
        settingString.append(L"\tAccepting connections on addresses:\n");
        WCHAR wsaddress[SockAddrMaxStringLength]{};
        for (const auto& addr : g_configSettings->ListenAddresses)
        {
            if (addr.WriteCompleteAddress(wsaddress))
            {
                settingString.append(L"\t\t");
                settingString.append(wsaddress);
                settingString.append(L"\n");
            }
        }
    }
    else
    {
        if (g_configSettings->OutgoingIfIndex > 0)
        {
            settingString.append(
                wil::str_printf<std::wstring>(
                    L"\tInterfaceIndex: %u\n", g_configSettings->OutgoingIfIndex));
        }

        settingString.append(L"\tConnecting out to addresses:\n");
        WCHAR wsaddress[SockAddrMaxStringLength]{};
        for (const auto& addr : g_configSettings->TargetAddresses)
        {
            if (addr.WriteCompleteAddress(wsaddress))
            {
                settingString.append(L"\t\t");
                settingString.append(wsaddress);
                settingString.append(L"\n");
            }
        }

        settingString.append(L"\tBinding to local addresses for outgoing connections:\n");
        for (const auto& addr : g_configSettings->BindAddresses)
        {
            if (addr.WriteCompleteAddress(wsaddress))
            {
                settingString.append(L"\t\t");
                settingString.append(wsaddress);
                settingString.append(L"\n");
            }
        }

        if (g_configSettings->LocalPortLow != 0)
        {
            if (0 == g_configSettings->LocalPortHigh)
            {
                settingString.append(
                    wil::str_printf<std::wstring>(
                        L"\tUsing local port for outgoing connections: %u\n",
                        g_configSettings->LocalPortLow));
            }
            else
            {
                settingString.append(
                    wil::str_printf<std::wstring>(
                        L"\tUsing local port for outgoing connections: [%u, %u]\n",
                        g_configSettings->LocalPortLow, g_configSettings->LocalPortHigh));
            }
        }

        settingString.append(
            wil::str_printf<std::wstring>(
                L"\tConnection limit (maximum established connections): %u [0x%x]\n",
                g_configSettings->ConnectionLimit,
                g_configSettings->ConnectionLimit));
        settingString.append(
            wil::str_printf<std::wstring>(
                L"\tConnection throttling rate (maximum pended connection attempts): %u [0x%x]\n",
                g_configSettings->ConnectionThrottleLimit,
                g_configSettings->ConnectionThrottleLimit));
    }
    // calculate total connections
    if (g_configSettings->AcceptFunction)
    {
        if (g_configSettings->ServerExitLimit > MAXLONG)
        {
            settingString.append(
                wil::str_printf<std::wstring>(
                    L"\tServer-accepted connections before exit : 0x%llx\n",
                    g_configSettings->ServerExitLimit));
        }
        else
        {
            settingString.append(
                wil::str_printf<std::wstring>(
                    L"\tServer-accepted connections before exit : %llu [0x%llx]\n",
                    g_configSettings->ServerExitLimit,
                    g_configSettings->ServerExitLimit));
        }
    }
    else
    {
        uint64_t totalConnections{};
        if (g_configSettings->Iterations == MAXULONGLONG)
        {
            totalConnections = MAXULONGLONG;
        }
        else
        {
            totalConnections = g_configSettings->Iterations * g_configSettings->ConnectionLimit;
        }
        if (totalConnections > MAXLONG)
        {
            settingString.append(
                wil::str_printf<std::wstring>(
                    L"\tTotal outgoing connections before exit (iterations * concurrent connections) : 0x%llx\n",
                    totalConnections));
        }
        else
        {
            settingString.append(
                wil::str_printf<std::wstring>(
                    L"\tTotal outgoing connections before exit (iterations * concurrent connections) : %llu [0x%llx]\n",
                    totalConnections,
                    totalConnections));
        }
    }

    settingString.append(L"\n");

    // immediately print the legend once we know the status info object
    switch (g_consoleVerbosity)
    {
        // case 0: // nothing
        case 1: // status updates
        case 2: // error info
        case 3: // error info + status updates
        case 4: // connection info + error info
        case 5: // connection info + error info + status updates
        case 6: // above + debug info
        default:
        {
            fwprintf(stdout, L"%ws", settingString.c_str());
        }
    }

    // must manually convert all carriage returns to file-friendly carriage return/line feed
    if (g_connectionLogger && !g_connectionLogger->IsCsvFormat())
    {
        g_connectionLogger->LogMessage(
            ctString::ctReplaceAllCopy(
                settingString, L"\n", L"\r\n").c_str());
    }
}