Skip to content

feat: S12.17 tunable + runtime-overridable TCP connect and TLS handshake timeouts#447

Merged
DavidCozens merged 7 commits into
mainfrom
feat/s12-17-tunable-tcp-tls-timeouts
May 25, 2026
Merged

feat: S12.17 tunable + runtime-overridable TCP connect and TLS handshake timeouts#447
DavidCozens merged 7 commits into
mainfrom
feat/s12-17-tunable-tcp-tls-timeouts

Conversation

@DavidCozens

@DavidCozens DavidCozens commented May 25, 2026

Copy link
Copy Markdown
Owner

Closes #282.

Summary

  • Two new compile-time tunables (SOLIDSYSLOG_TCP_CONNECT_TIMEOUT_MS = 200, SOLIDSYSLOG_TLS_HANDSHAKE_TIMEOUT_MS = 5000) overridable via SOLIDSYSLOG_USER_TUNABLES_FILE.
  • Per-stream config getter + context (SolidSyslogTcpConnectTimeoutFunction, SolidSyslogTlsHandshakeTimeoutFunction) read at use-time on every connect / handshake attempt — supports commissioning-from-NVRAM, live-tuning, and per-instance variation without rebuilding or recreating the stream.
  • NULL getter → TU-private Null Object returning the tunable, so the bounded-wait path is a single code path regardless of whether the integrator wired runtime tuning.
  • Applied uniformly across all five backends: SolidSyslogPosixTcpStream, SolidSyslogWinsockTcpStream, SolidSyslogFreeRtosTcpStream, SolidSyslogTlsStream (OpenSSL), SolidSyslogMbedTlsStream.

API change: TCP stream _Create(void)_Create(const struct ...Config*) accepting NULL for all-defaults. Existing callers pass NULL or zeroed config (existing zero-init {} / {0} calls keep their default behavior automatically).

Test plan

  • gcc debug — 1330 tests green
  • clang debug — 1330 tests green
  • sanitize — 1330 tests green
  • coverage — 96.2% overall; 100% on every touched .c
  • analyze-tidy — green
  • analyze-cppcheck (plain + MISRA) — green
  • analyze-format — CI
  • analyze-iwyu — CI
  • Windows (Winsock + MSVC) — CI
  • FreeRTOS host-TDD — CI
  • MbedTLS unit + integration — CI
  • BDD suites — CI

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • TCP connection timeout is now configurable per stream via callback functions, with a tunable default of 200ms.
    • TLS handshake timeout is now configurable per stream via callback functions, with a tunable default of 5000ms.
    • New timeout configuration defaults available for integrators without custom callback implementations.

Review Change Stack

DavidCozens and others added 6 commits May 25, 2026 12:17
Adds SOLIDSYSLOG_TCP_CONNECT_TIMEOUT_MS / _TLS_HANDSHAKE_TIMEOUT_MS
tunables and the SolidSyslogTcpConnectTimeoutFunction callback typedef.
PosixTcpStream gains a config struct carrying GetConnectTimeoutMs +
context; the getter is invoked per Open so commissioning-time or live
tuning takes effect without rebuilding or recreating the stream.

NULL config (or NULL getter field) falls back to a TU-private Null
Object returning the tunable — single code path through the bounded
select() wait.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirrors the POSIX shape: SolidSyslogWinsockTcpStreamConfig carries
GetConnectTimeoutMs + context; default DefaultWinsockTcpStream static
holds the Null Object getter so a NULL config flows through the same
bounded select() path as a configured one.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirrors POSIX/Winsock: SolidSyslogFreeRtosTcpStreamConfig with
GetConnectTimeoutMs + context, DefaultFreeRtosTcpStream static, Null
Object substitution. The bounded SO_RCVTIMEO/SO_SNDTIMEO ticks now
come from pdMS_TO_TICKS(ResolveConnectTimeoutMs(self)) so commissioning
or live-tuning takes effect on the next connect.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds SolidSyslogTlsHandshakeTimeoutFunction typedef header, extends
SolidSyslogTlsStreamConfig with GetHandshakeTimeoutMs + context, and
substitutes a Null Object in Initialise when the integrator does not
install a getter. The bounded handshake retry budget now resolves
from the getter at the start of each handshake attempt so commissioning
or live-tuning takes effect on the next reconnect.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mirrors the OpenSSL TlsStream pattern: SolidSyslogMbedTlsStreamConfig
gains GetHandshakeTimeoutMs + context, Null Object substituted in
Initialise when not supplied. The bounded handshake retry budget now
resolves from the getter at the start of each handshake attempt so
commissioning or live-tuning takes effect on the next reconnect.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- C++ tests use nullptr in Create() calls (modernize-use-nullptr)
- NOLINT bugprone-easily-swappable-parameters on PosixTcpStream's
  WaitForConnectCompletion(int fd, long timeoutMicros)
- NOLINT cppcoreguidelines-pro-type-reinterpret-cast on the test
  fakes' sentinel-pointer Reset
- Include <stddef.h> in BddTargetTlsSender_OpenSsl_PosixTcp.c for NULL

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 25, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@DavidCozens, we couldn't start this review because you've used your available PR reviews for now.

Your plan includes 1 review of capacity. Refill in 31 minutes and 59 seconds.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more review capacity refills, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than trial, open-source, and free plans. In all cases, review capacity refills continuously over time.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 3ead7b49-d7e2-4033-9e36-798000a43571

📥 Commits

Reviewing files that changed from the base of the PR and between 951da4f and 11db069.

📒 Files selected for processing (6)
  • Platform/FreeRtos/Source/SolidSyslogFreeRtosTcpStream.c
  • Platform/Posix/Source/SolidSyslogPosixTcpStream.c
  • Platform/Windows/Source/SolidSyslogWinsockTcpStream.c
  • Tests/SolidSyslogPosixTcpStreamTest.cpp
  • Tests/SolidSyslogTlsStreamTest.cpp
  • misra_suppressions.txt
📝 Walkthrough

Walkthrough

This PR implements tunable and runtime-overridable TCP connect and TLS handshake timeouts across five backend implementations (POSIX, Windows, FreeRtos, OpenSSL, MbedTLS), replacing hardcoded timeout constants with config-driven getter callbacks that support per-instance and live-tuning configuration.

Changes

Core contract types and tunables

Layer / File(s) Summary
Callback types and tunable defaults
Core/Interface/SolidSyslogTcpConnectTimeoutFunction.h, Core/Interface/SolidSyslogTlsHandshakeTimeoutFunction.h, Core/Interface/SolidSyslogTunablesDefaults.h
Introduces SolidSyslogTcpConnectTimeoutFunction and SolidSyslogTlsHandshakeTimeoutFunction callback typedefs for timeout getters accepting a void* context and returning uint32_t milliseconds. Adds SOLIDSYSLOG_TCP_CONNECT_TIMEOUT_MS (200ms) and SOLIDSYSLOG_TLS_HANDSHAKE_TIMEOUT_MS (5000ms) tunable defaults that serve as compile-time fallbacks when integrators do not provide custom getters.

TCP stream backends

Layer / File(s) Summary
POSIX TCP config and runtime resolution
Platform/Posix/Interface/SolidSyslogPosixTcpStream.h, Platform/Posix/Source/SolidSyslogPosixTcpStream.*, Tests/SolidSyslogPosixTcpStreamTest.cpp
Introduces SolidSyslogPosixTcpStreamConfig struct with GetConnectTimeoutMs callback and context pointer; factory signature changed from _Create(void) to _Create(const config*). Implementation adds per-instance config storage, null-object default getter, and resolves timeout at connect-attempt time via PosixTcpStream_ResolveConnectTimeoutMicros() instead of using compile-time CONNECT_TIMEOUT_MICROSECONDS constant. Test suite adds fake getter, verifies callback invocation and timeout usage, and updates pool tests to pass explicit nullptr config.
Windows Winsock TCP config and runtime resolution
Platform/Windows/Interface/SolidSyslogWinsockTcpStream.h, Platform/Windows/Source/SolidSyslogWinsockTcpStream.*, Tests/SolidSyslogWinsockTcpStreamTest.cpp
Introduces SolidSyslogWinsockTcpStreamConfig struct with GetConnectTimeoutMs callback and context pointer; factory signature changed from _Create(void) to _Create(const config*). Implementation adds per-instance config storage, null-object default getter, and resolves timeout per reconnect attempt via WinsockTcpStream_ResolveConnectTimeoutMs(), replacing fixed CONNECT_TIMEOUT_MILLISECONDS enum constant. Test suite adds fake getter, validates callback invocation and select timeout conversion, and updates pool tests to pass explicit nullptr config.
FreeRtos TCP config and runtime resolution
Platform/FreeRtos/Interface/SolidSyslogFreeRtosTcpStream.h, Platform/FreeRtos/Source/SolidSyslogFreeRtosTcpStream.*, Tests/FreeRtos/SolidSyslogFreeRtosTcpStreamTest.cpp
Introduces SolidSyslogFreeRtosTcpStreamConfig struct with GetConnectTimeoutMs callback and context pointer; factory signature changed from _Create(void) to _Create(const config*). Implementation adds per-instance config storage, null-object default getter, and resolves timeout per connect attempt via FreeRtosTcpStream_ResolveConnectTimeoutMs() instead of compile-time 200ms constant. Test suite adds fake getter, verifies callback invocation and socket receive-timeout conversion, and updates pool tests to pass explicit nullptr config.

TLS stream backends

Layer / File(s) Summary
OpenSSL TLS config and runtime resolution
Platform/OpenSsl/Interface/SolidSyslogTlsStream.h, Platform/OpenSsl/Source/SolidSyslogTlsStream.c, Tests/SolidSyslogTlsStreamTest.cpp
Extends SolidSyslogTlsStreamConfig with GetHandshakeTimeoutMs callback and HandshakeTimeoutContext fields. Implementation adds null-object handshake-timeout getter (returning tunable when integrator provides no getter), resolves per-handshake budget at attempt time, tracks elapsed sleep as uint32_t, and exhaustion-checks against resolved budgetMs instead of fixed constant. Test suite adds fake getter, validates callback invocation and handshake budget behavior, and confirms nullptr context passing.
MbedTLS TLS config and runtime resolution
Platform/MbedTls/Interface/SolidSyslogMbedTlsStream.h, Platform/MbedTls/Source/SolidSyslogMbedTlsStream.c, Tests/MbedTls/SolidSyslogMbedTlsStreamTest.cpp
Extends SolidSyslogMbedTlsStreamConfig with GetHandshakeTimeoutMs callback and HandshakeTimeoutContext fields. Implementation adds null-object handshake-timeout getter (returning tunable when integrator provides no getter), resolves per-handshake budget at attempt time, tracks elapsed sleep as uint32_t, and exhaustion-checks against resolved budgetMs instead of fixed constant. Test suite adds fake getter, validates callback invocation and handshake budget behavior, and confirms nullptr context passing.

Caller updates

Layer / File(s) Summary
BDD target stream creation
Bdd/Targets/Common/BddTargetTlsSender_*.c, Bdd/Targets/*/main.c, Bdd/Targets/Windows/BddTargetWindows.c
All BDD target call sites updated to pass explicit NULL config to stream Create functions: SolidSyslogPosixTcpStream_Create(NULL), SolidSyslogWinsockTcpStream_Create(NULL), SolidSyslogFreeRtosTcpStream_Create(NULL). One target adds #include <stddef.h> to provide NULL macro. Test harnesses across five TEST_GROUP contexts updated to call SolidSyslogPosixTcpStream_Create(nullptr) instead of parameterless constructor.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • DavidCozens/solid-syslog#407: Earlier POSIX adapter pool migration that changed SolidSyslogPosixTcpStream constructor, upon which this PR's config-driven factory builds.
  • DavidCozens/solid-syslog#411: FreeRtos TCP stream adapter construction changes that this PR refactors to support config-driven connect-timeout wiring.
  • DavidCozens/solid-syslog#419: MbedTLS stream adapter introduction, upon which this PR's handshake timeout getter plumbing builds.

🐰 Timeouts once burned in stone,
Now flow from configs, live and grown—
Each stream may tune its patience pace,
No firmware rebuild, just data grace!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 24.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: introducing tunable and runtime-overridable TCP connect and TLS handshake timeouts (S12.17), which aligns with all file changes across five backends.
Description check ✅ Passed The description covers purpose (Closes #282), changes (tunables, per-stream getters, Null Object pattern, five backends, API changes), and test plan status, meeting template expectations.
Linked Issues check ✅ Passed The PR fully implements #282 objectives: adds two compile-time tunables, introduces function-pointer getters with context for both TCP and TLS streams, applies Null Object pattern across five backends, changes TCP stream Create APIs to accept config pointers, and updates all callers consistently.
Out of Scope Changes check ✅ Passed All changes are directly scoped to #282: tunable definitions, timeout function callbacks, stream config extensions, per-backend implementations, and aligned test/caller updates. No unrelated refactoring, dependency upgrades, or out-of-scope features detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/s12-17-tunable-tcp-tls-timeouts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

Copy link
Copy Markdown
Contributor

☀️   Quality Summary

   🚦   build-linux-gcc: 100% successful (✔️ 1336 passed)
   🚦   build-freertos-host-tdd: 100% successful (✔️ 1570 passed)
   🚦   build-linux-clang: 100% successful (✔️ 1288 passed)
   🚦   sanitize-linux-gcc: 100% successful (✔️ 1288 passed)
   🚦   integration-linux-openssl: 100% successful (✔️ 9 passed)
   🚦   integration-linux-mbedtls: 100% successful (✔️ 7 passed)
   🚦   integration-windows-openssl: 100% successful (✔️ 9 passed)
   🚦   bdd-linux-syslog-ng: 94% successful (✔️ 46 passed, 🙈 3 skipped)
   🚦   bdd-windows-otel: 90% successful (✔️ 44 passed, 🙈 5 skipped)
   🚦   bdd-freertos-qemu: 86% successful (✔️ 42 passed, 🙈 7 skipped)
   🚦   build-windows-msvc: 100% successful (✔️ 1147 passed)
   🚦   build-linux-tunable-override: 100% successful (✔️ 1288 passed)
   ⚠️   Clang-Tidy: No warnings
   ⚠️   CPPCheck: 1 warning (low: 1)


Created by Quality Monitor v1.14.0 (#f3859fd). More details are shown in the GitHub Checks Result.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Tests/SolidSyslogWinsockTcpStreamTest.cpp (1)

270-276: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Derive the expected timeout from the tunable macro.

Line 274 hard-codes the default 200 ms, so this test will false-fail in any build that overrides SOLIDSYSLOG_TCP_CONNECT_TIMEOUT_MS via the user tunables hook. Assert against the macro instead of the default literal.

💡 Proposed fix
 TEST(SolidSyslogWinsockTcpStream, OpenPassesBoundedConnectTimeoutToSelect)
 {
     WinsockFake_SetConnectFailsWithLastError(WSAEWOULDBLOCK);
     SolidSyslogStream_Open(stream, addr);
-    /* Default tunable SOLIDSYSLOG_TCP_CONNECT_TIMEOUT_MS = 200 → 0 s + 200 000 µs. */
-    LONGS_EQUAL(0, WinsockFake_LastSelectTimeoutSec());
-    LONGS_EQUAL(200000, WinsockFake_LastSelectTimeoutUsec());
+    LONGS_EQUAL(
+        (long) (SOLIDSYSLOG_TCP_CONNECT_TIMEOUT_MS / 1000U),
+        WinsockFake_LastSelectTimeoutSec()
+    );
+    LONGS_EQUAL(
+        (long) ((SOLIDSYSLOG_TCP_CONNECT_TIMEOUT_MS % 1000U) * 1000U),
+        WinsockFake_LastSelectTimeoutUsec()
+    );
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Tests/SolidSyslogWinsockTcpStreamTest.cpp` around lines 270 - 276, The test
TEST(SolidSyslogWinsockTcpStream, OpenPassesBoundedConnectTimeoutToSelect)
currently asserts a hard-coded 200 ms value; change it to derive the expected
timeout from the tunable macro SOLIDSYSLOG_TCP_CONNECT_TIMEOUT_MS instead:
compute expected usec as (SOLIDSYSLOG_TCP_CONNECT_TIMEOUT_MS * 1000) and assert
that WinsockFake_LastSelectTimeoutSec() is 0 and
WinsockFake_LastSelectTimeoutUsec() equals that computed value after calling
WinsockFake_SetConnectFailsWithLastError(WSAEWOULDBLOCK) and
SolidSyslogStream_Open(stream, addr).
🧹 Nitpick comments (6)
Tests/SolidSyslogWinsockTcpStreamTest.cpp (1)

109-122: ⚡ Quick win

Add one non-null ConnectTimeoutContext test path.

Line 116 only builds a getter-only config, so the new context field never gets exercised. A dropped copy/forward of ConnectTimeoutContext would still pass this file today.

💡 Suggested extension
-    void OpenStreamWithFakeGetter()
+    void OpenStreamWithFakeGetter(void* context = nullptr)
     {
         SolidSyslogWinsockTcpStream_Destroy(stream);
         struct SolidSyslogWinsockTcpStreamConfig config = {};
         config.GetConnectTimeoutMs                      = FakeGetConnectTimeoutMs;
+        config.ConnectTimeoutContext                    = context;
         stream                                          = SolidSyslogWinsockTcpStream_Create(&config);
 
         WinsockFake_SetConnectFailsWithLastError(WSAEWOULDBLOCK);
         SolidSyslogStream_Open(stream, addr);
     }
+TEST(SolidSyslogWinsockTcpStream, GetterReceivesConfiguredContext)
+{
+    void* testContext = reinterpret_cast<void*>(0x1234U);
+
+    OpenStreamWithFakeGetter(testContext);
+
+    POINTERS_EQUAL(testContext, FakeGetConnectTimeoutMs_LastContext);
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Tests/SolidSyslogWinsockTcpStreamTest.cpp` around lines 109 - 122, The test
OpenStreamWithFakeGetter builds a config with GetConnectTimeoutMs but never sets
ConnectTimeoutContext, so add a non-null ConnectTimeoutContext to exercise the
context path: in OpenStreamWithFakeGetter, after setting
config.GetConnectTimeoutMs = FakeGetConnectTimeoutMs, set
config.ConnectTimeoutContext to a pointer to a test-local context object (e.g.
&fakeConnectTimeoutContext) that the FakeGetConnectTimeoutMs recognizes,
ensuring the fake getter and SolidSyslogWinsockTcpStream_Create are invoked with
a non-null ConnectTimeoutContext.
Platform/MbedTls/Source/SolidSyslogMbedTlsStream.c (1)

87-90: ⚡ Quick win

Move MbedTlsStream_ResolveHandshakeTimeoutMs directly below its first caller.

Please place this helper definition immediately beneath MbedTlsStream_PerformHandshake (keep the forward declaration at file top) to preserve the project’s required top-down reading order.

As per coding guidelines: **/*.c: “Helper functions must be forward-declared at file top and defined immediately beneath their first caller for top-down reading”.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Platform/MbedTls/Source/SolidSyslogMbedTlsStream.c` around lines 87 - 90, The
helper function MbedTlsStream_ResolveHandshakeTimeoutMs is defined too early;
keep its forward declaration at the top but move the full definition so it
appears immediately after its first caller MbedTlsStream_PerformHandshake;
locate the MbedTlsStream_PerformHandshake implementation and cut the
MbedTlsStream_ResolveHandshakeTimeoutMs definition from its current location and
paste it directly beneath that function to satisfy the top-down reading order
while leaving the forward declaration at the file header unchanged.
Tests/SolidSyslogPosixTcpStreamTest.cpp (1)

463-468: ⚡ Quick win

Add a non-null context pass-through test for the getter.

You verify the null-context path, but not that a configured context pointer is forwarded unchanged. A small test here would lock the contract.

Suggested test shape
+TEST(SolidSyslogPosixTcpStream, GetterReceivesConfiguredContext)
+{
+    int marker = 42;
+    SolidSyslogPosixTcpStream_Destroy(stream);
+    struct SolidSyslogPosixTcpStreamConfig config = {};
+    config.GetConnectTimeoutMs = FakeGetConnectTimeoutMs;
+    config.ConnectTimeoutContext = &marker;
+    stream = SolidSyslogPosixTcpStream_Create(&config);
+
+    SocketFake_SetConnectFailsWithErrno(EINPROGRESS);
+    SolidSyslogStream_Open(stream, addr);
+
+    POINTERS_EQUAL(&marker, FakeGetConnectTimeoutMs_LastContext);
+}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Tests/SolidSyslogPosixTcpStreamTest.cpp` around lines 463 - 468, Add a new
test mirroring GetterReceivesNullContextWhenContextNotConfigured that verifies a
non-null context is forwarded: create a sentinel object, register/configure the
fake getter with that sentinel as its context, call OpenStreamWithFakeGetter
(using the same helper used in the existing test but passing/setting the
configured context), then assert POINTERS_EQUAL(sentinel,
FakeGetConnectTimeoutMs_LastContext); name the test e.g.
GetterForwardsNonNullContextWhenContextConfigured and perform any necessary
cleanup.
Platform/OpenSsl/Source/SolidSyslogTlsStream.c (1)

410-422: ⚡ Quick win

Move these Initialise-only helpers under TlsStream_Initialise.

TlsStream_NullHandshakeTimeoutGetter and TlsStream_ConfigProvidesHandshakeGetter are first used on Line 67, but their definitions live ~340 lines later. Please place them immediately beneath their first caller to keep this TU top-down per the repo C layout rule.

As per coding guidelines, "Helper functions must be forward-declared at file top and defined immediately beneath their first caller for top-down reading".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Platform/OpenSsl/Source/SolidSyslogTlsStream.c` around lines 410 - 422,
Forward-declare TlsStream_NullHandshakeTimeoutGetter and
TlsStream_ConfigProvidesHandshakeGetter at the top of the TU, then move their
full definitions so they appear immediately beneath the TlsStream_Initialise
function (their first caller). Keep the signatures and static/static inline
qualifiers unchanged and ensure any uses by TlsStream_Initialise still compile
after relocation.
Tests/SolidSyslogTlsStreamTest.cpp (1)

1107-1134: ⚡ Quick win

Add one reopen/context case for the new timeout contract.

These tests only cover a single Open and the default-null context path. A cached handshake budget, or a dropped non-null config.HandshakeTimeoutContext, would still pass. Please add one case that sets a non-null context, opens once, changes the backing timeout value, re-opens, and asserts both the updated budget and forwarded context.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Tests/SolidSyslogTlsStreamTest.cpp` around lines 1107 - 1134, Add a new test
similar to the others that verifies the non-null HandshakeTimeoutContext is
forwarded on each Open and that the handshake budget is refreshed on reopen:
call RecreateStreamWithFakeHandshakeGetter(), set
stream->config.HandshakeTimeoutContext to a non-null pointer, set
FakeGetHandshakeTimeoutMs_ReturnValue to an initial value and call
SolidSyslogStream_Open(stream, addr) to consume that budget, then change
FakeGetHandshakeTimeoutMs_ReturnValue to a different value and call
SolidSyslogStream_Open(stream, addr) again (arrange persistent handshake error
with ArrangePersistentHandshakeError(SSL_ERROR_WANT_READ) to force polling) and
assert that NoOpSleepCallCount equals the new budget and that
FakeGetHandshakeTimeoutMs_LastContext equals the non-null context pointer; use
the existing FakeGetHandshakeTimeoutMs_* helpers and
SolidSyslogStream_Open/RecreateStreamWithFakeHandshakeGetter to locate the
relevant code paths.
Tests/FreeRtos/SolidSyslogFreeRtosTcpStreamTest.cpp (1)

114-121: ⚡ Quick win

Add one test for configured non-null context passthrough.

The suite verifies the unconfigured (nullptr) context path, but not that a configured ConnectTimeoutContext is forwarded to the getter.

✅ Suggested patch
-    void openStreamWithFakeGetter()
+    void openStreamWithFakeGetter(void* context = nullptr)
     {
         SolidSyslogFreeRtosTcpStream_Destroy(stream);
         struct SolidSyslogFreeRtosTcpStreamConfig config = {};
         config.GetConnectTimeoutMs                       = FakeGetConnectTimeoutMs;
+        config.ConnectTimeoutContext                     = context;
         stream                                           = SolidSyslogFreeRtosTcpStream_Create(&config);
         SolidSyslogStream_Open(stream, addr);
     }
 TEST(SolidSyslogFreeRtosTcpStream, GetterReceivesNullContextWhenContextNotConfigured)
 {
     openStreamWithFakeGetter();

     POINTERS_EQUAL(nullptr, FakeGetConnectTimeoutMs_LastContext);
 }
+
+TEST(SolidSyslogFreeRtosTcpStream, GetterReceivesConfiguredContext)
+{
+    int contextToken = 42;
+    openStreamWithFakeGetter(&contextToken);
+
+    POINTERS_EQUAL(&contextToken, FakeGetConnectTimeoutMs_LastContext);
+}

Also applies to: 217-222

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Tests/FreeRtos/SolidSyslogFreeRtosTcpStreamTest.cpp` around lines 114 - 121,
Add a test that configures a non-null ConnectTimeoutContext on the
SolidSyslogFreeRtosTcpStreamConfig and asserts that the pointer passed into the
GetConnectTimeoutMs callback (FakeGetConnectTimeoutMs) equals that configured
context; update the openStreamWithFakeGetter helper (and the analogous helper at
lines 217-222) to set config.ConnectTimeoutContext to a distinct non-null value
before creating the stream with SolidSyslogFreeRtosTcpStream_Create and calling
SolidSyslogStream_Open so the FakeGetConnectTimeoutMs can verify the
passthrough.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@Platform/Posix/Source/SolidSyslogPosixTcpStream.c`:
- Around line 210-214: PosixTcpStream_ResolveConnectTimeoutMicros currently
multiplies a 32-bit ms by 1000 using (long) which can overflow on 32-bit long
targets; change the computation to use a wider integer (e.g. int64_t or long
long) for the multiply, then clamp the result to the target long range and
return (long) safely. Locate the function
PosixTcpStream_ResolveConnectTimeoutMicros and replace the direct (long) ms *
1000L expression with a promotion to int64_t (or uint64_t), perform the
multiplication, cap to LONG_MAX if it exceeds the representable range, and cast
the clamped value back to long for the return so select() deadlines are not
given invalid values.

---

Outside diff comments:
In `@Tests/SolidSyslogWinsockTcpStreamTest.cpp`:
- Around line 270-276: The test TEST(SolidSyslogWinsockTcpStream,
OpenPassesBoundedConnectTimeoutToSelect) currently asserts a hard-coded 200 ms
value; change it to derive the expected timeout from the tunable macro
SOLIDSYSLOG_TCP_CONNECT_TIMEOUT_MS instead: compute expected usec as
(SOLIDSYSLOG_TCP_CONNECT_TIMEOUT_MS * 1000) and assert that
WinsockFake_LastSelectTimeoutSec() is 0 and WinsockFake_LastSelectTimeoutUsec()
equals that computed value after calling
WinsockFake_SetConnectFailsWithLastError(WSAEWOULDBLOCK) and
SolidSyslogStream_Open(stream, addr).

---

Nitpick comments:
In `@Platform/MbedTls/Source/SolidSyslogMbedTlsStream.c`:
- Around line 87-90: The helper function MbedTlsStream_ResolveHandshakeTimeoutMs
is defined too early; keep its forward declaration at the top but move the full
definition so it appears immediately after its first caller
MbedTlsStream_PerformHandshake; locate the MbedTlsStream_PerformHandshake
implementation and cut the MbedTlsStream_ResolveHandshakeTimeoutMs definition
from its current location and paste it directly beneath that function to satisfy
the top-down reading order while leaving the forward declaration at the file
header unchanged.

In `@Platform/OpenSsl/Source/SolidSyslogTlsStream.c`:
- Around line 410-422: Forward-declare TlsStream_NullHandshakeTimeoutGetter and
TlsStream_ConfigProvidesHandshakeGetter at the top of the TU, then move their
full definitions so they appear immediately beneath the TlsStream_Initialise
function (their first caller). Keep the signatures and static/static inline
qualifiers unchanged and ensure any uses by TlsStream_Initialise still compile
after relocation.

In `@Tests/FreeRtos/SolidSyslogFreeRtosTcpStreamTest.cpp`:
- Around line 114-121: Add a test that configures a non-null
ConnectTimeoutContext on the SolidSyslogFreeRtosTcpStreamConfig and asserts that
the pointer passed into the GetConnectTimeoutMs callback
(FakeGetConnectTimeoutMs) equals that configured context; update the
openStreamWithFakeGetter helper (and the analogous helper at lines 217-222) to
set config.ConnectTimeoutContext to a distinct non-null value before creating
the stream with SolidSyslogFreeRtosTcpStream_Create and calling
SolidSyslogStream_Open so the FakeGetConnectTimeoutMs can verify the
passthrough.

In `@Tests/SolidSyslogPosixTcpStreamTest.cpp`:
- Around line 463-468: Add a new test mirroring
GetterReceivesNullContextWhenContextNotConfigured that verifies a non-null
context is forwarded: create a sentinel object, register/configure the fake
getter with that sentinel as its context, call OpenStreamWithFakeGetter (using
the same helper used in the existing test but passing/setting the configured
context), then assert POINTERS_EQUAL(sentinel,
FakeGetConnectTimeoutMs_LastContext); name the test e.g.
GetterForwardsNonNullContextWhenContextConfigured and perform any necessary
cleanup.

In `@Tests/SolidSyslogTlsStreamTest.cpp`:
- Around line 1107-1134: Add a new test similar to the others that verifies the
non-null HandshakeTimeoutContext is forwarded on each Open and that the
handshake budget is refreshed on reopen: call
RecreateStreamWithFakeHandshakeGetter(), set
stream->config.HandshakeTimeoutContext to a non-null pointer, set
FakeGetHandshakeTimeoutMs_ReturnValue to an initial value and call
SolidSyslogStream_Open(stream, addr) to consume that budget, then change
FakeGetHandshakeTimeoutMs_ReturnValue to a different value and call
SolidSyslogStream_Open(stream, addr) again (arrange persistent handshake error
with ArrangePersistentHandshakeError(SSL_ERROR_WANT_READ) to force polling) and
assert that NoOpSleepCallCount equals the new budget and that
FakeGetHandshakeTimeoutMs_LastContext equals the non-null context pointer; use
the existing FakeGetHandshakeTimeoutMs_* helpers and
SolidSyslogStream_Open/RecreateStreamWithFakeHandshakeGetter to locate the
relevant code paths.

In `@Tests/SolidSyslogWinsockTcpStreamTest.cpp`:
- Around line 109-122: The test OpenStreamWithFakeGetter builds a config with
GetConnectTimeoutMs but never sets ConnectTimeoutContext, so add a non-null
ConnectTimeoutContext to exercise the context path: in OpenStreamWithFakeGetter,
after setting config.GetConnectTimeoutMs = FakeGetConnectTimeoutMs, set
config.ConnectTimeoutContext to a pointer to a test-local context object (e.g.
&fakeConnectTimeoutContext) that the FakeGetConnectTimeoutMs recognizes,
ensuring the fake getter and SolidSyslogWinsockTcpStream_Create are invoked with
a non-null ConnectTimeoutContext.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 9290aea8-6d5b-455e-a60f-8094e60bcd77

📥 Commits

Reviewing files that changed from the base of the PR and between b1b556b and 951da4f.

📒 Files selected for processing (31)
  • Bdd/Targets/Common/BddTargetTlsSender_MbedTls_FreeRtosTcp.c
  • Bdd/Targets/Common/BddTargetTlsSender_OpenSsl_PosixTcp.c
  • Bdd/Targets/Common/BddTargetTlsSender_OpenSsl_WinsockTcp.c
  • Bdd/Targets/FreeRtos/main.c
  • Bdd/Targets/Linux/main.c
  • Bdd/Targets/Windows/BddTargetWindows.c
  • Core/Interface/SolidSyslogTcpConnectTimeoutFunction.h
  • Core/Interface/SolidSyslogTlsHandshakeTimeoutFunction.h
  • Core/Interface/SolidSyslogTunablesDefaults.h
  • Platform/FreeRtos/Interface/SolidSyslogFreeRtosTcpStream.h
  • Platform/FreeRtos/Source/SolidSyslogFreeRtosTcpStream.c
  • Platform/FreeRtos/Source/SolidSyslogFreeRtosTcpStreamPrivate.h
  • Platform/FreeRtos/Source/SolidSyslogFreeRtosTcpStreamStatic.c
  • Platform/MbedTls/Interface/SolidSyslogMbedTlsStream.h
  • Platform/MbedTls/Source/SolidSyslogMbedTlsStream.c
  • Platform/OpenSsl/Interface/SolidSyslogTlsStream.h
  • Platform/OpenSsl/Source/SolidSyslogTlsStream.c
  • Platform/Posix/Interface/SolidSyslogPosixTcpStream.h
  • Platform/Posix/Source/SolidSyslogPosixTcpStream.c
  • Platform/Posix/Source/SolidSyslogPosixTcpStreamPrivate.h
  • Platform/Posix/Source/SolidSyslogPosixTcpStreamStatic.c
  • Platform/Windows/Interface/SolidSyslogWinsockTcpStream.h
  • Platform/Windows/Source/SolidSyslogWinsockTcpStream.c
  • Platform/Windows/Source/SolidSyslogWinsockTcpStreamPrivate.h
  • Platform/Windows/Source/SolidSyslogWinsockTcpStreamStatic.c
  • Tests/FreeRtos/SolidSyslogFreeRtosTcpStreamTest.cpp
  • Tests/MbedTls/SolidSyslogMbedTlsStreamTest.cpp
  • Tests/SolidSyslogPosixTcpStreamTest.cpp
  • Tests/SolidSyslogStreamSenderTest.cpp
  • Tests/SolidSyslogTlsStreamTest.cpp
  • Tests/SolidSyslogWinsockTcpStreamTest.cpp

Comment thread Platform/Posix/Source/SolidSyslogPosixTcpStream.c
- IWYU: drop unused SolidSyslogStreamDefinition.h include from
  PosixTcpStream.c (private header pulls it in); add stdint.h to
  PosixTcpStreamTest.cpp + TlsStreamTest.cpp for uint32_t
- MISRA: line-number bumps in misra_suppressions.txt for the moved
  cast/enum sites in PosixTcpStream/WinsockTcpStream/FreeRtosTcpStream/
  TlsStream/MbedTlsStream
- MISRA 8.9: move Default*TcpStream statics inside their respective
  Initialise functions (function-local static const) so the rule no
  longer trips on file-scope objects used in a single function

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

☀️   Quality Summary

   🚦   build-linux-gcc: 100% successful (✔️ 1336 passed)
   🚦   build-freertos-host-tdd: 100% successful (✔️ 1570 passed)
   🚦   build-linux-clang: 100% successful (✔️ 1288 passed)
   🚦   sanitize-linux-gcc: 100% successful (✔️ 1288 passed)
   🚦   integration-linux-openssl: 100% successful (✔️ 9 passed)
   🚦   integration-linux-mbedtls: 100% successful (✔️ 7 passed)
   🚦   integration-windows-openssl: 100% successful (✔️ 9 passed)
   🚦   bdd-linux-syslog-ng: 94% successful (✔️ 46 passed, 🙈 3 skipped)
   🚦   bdd-windows-otel: 90% successful (✔️ 44 passed, 🙈 5 skipped)
   🚦   bdd-freertos-qemu: 86% successful (✔️ 42 passed, 🙈 7 skipped)
   🚦   build-windows-msvc: 100% successful (✔️ 1147 passed)
   🚦   build-linux-tunable-override: 100% successful (✔️ 1288 passed)
   ⚠️   Clang-Tidy: No warnings
   ⚠️   CPPCheck: 1 warning (low: 1)


Created by Quality Monitor v1.14.0 (#f3859fd). More details are shown in the GitHub Checks Result.

@DavidCozens DavidCozens merged commit e4ce4d0 into main May 25, 2026
21 checks passed
@DavidCozens DavidCozens deleted the feat/s12-17-tunable-tcp-tls-timeouts branch May 25, 2026 13:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

S12.17: Tunable + runtime-overridable TCP connect and TLS handshake timeouts

1 participant