Skip to content

feat: send over TCP instead of UDP - #36

Merged
DavidCozens merged 1 commit into
mainfrom
stage/tcp
Jul 29, 2026
Merged

feat: send over TCP instead of UDP#36
DavidCozens merged 1 commit into
mainfrom
stage/tcp

Conversation

@DavidCozens

@DavidCozens DavidCozens commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Pull request

What this stage adds

A StreamSender over an lwIP TCP stream replaces the UDP sender, and the collector
moves to 5601. Records are framed by octet count (RFC 6587), which is what a
receiver expects on a stream transport.

Flash +7,320 B (+532 on the previous stage)
RAM +5,856 B (+180)
Log stack +448 B (unchanged)
Service +672 B (-56)

TCP before TLS is deliberate. It is the smaller step — a stream, a connect and a
framing rule, with no certificates in the picture — and it gives store-and-forward
somewhere to spool before crypto arrives. It also completes what the sequenceId
started: the transport now detects loss where it happens, while the sequence only
reveals it afterwards.

The flash is small because the baseline already holds a real mTLS session, so
lwIP's TCP code was in the image before this stage asked for it. What is charged
here is the stream and the sender in front of it, and the 180 bytes of RAM are
those two objects in SolidSyslog's static pool.

The log stack does not move at all: a task that calls Log is unaffected by the
transport underneath it. The service seam's high-water actually fell 56 bytes —
this stream's send path measures shallower than the datagram's — but the seam
stays 2 KiB, so nothing is given back. The stream takes a Sleep callback because
a connect is not instantaneous and the library will not pick a blocking primitive
on your behalf; one vTaskDelay is the whole of it.

Files

 README.md               | 16 ++++++++--------
 app/syslog/Syslog.c     | 32 +++++++++++++++++++++-----------
 measurements/stages.tsv |  1 +
 measurements/tcp.csv    | 13 +++++++++++++
 run-report.md           | 30 +++++++++++++++---------------
 5 files changed, 58 insertions(+), 34 deletions(-)

Checklist

  • The diff is application-only — no change to board bring-up, config headers, or build infra.
  • measurements/tcp.csv committed.
  • Row added to measurements/stages.tsv.
  • README regenerated: python3 scripts/gen-cost-table.py.
  • ./run.sh green (build + QEMU + baseline self-check) — run-report.md committed.

Context for review: 9 of 21 sequential single-commit PRs replaying the integration on top of the Baseline root. Each lands green and reviewed before the next is built on it, because a change to an early commit would force every commit above it to be re-run and re-measured.

Summary by CodeRabbit

  • New Features

    • Syslog transmission now uses a TCP connection with octet-count framing (switching from UDP).
    • Log sending now retries when the connection drops.
    • Report sending fails when the collector endpoint is unavailable.
    • TCP collector endpoint is updated to port 5601.
  • Documentation

    • Updated stage documentation to describe the TCP “This stage — TCP” behavior and refreshed TCP cost/resource figures and verification results.
    • Updated the recorded TCP run example and self-check measurements accordingly.

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d5575c2b-332a-400e-8d1e-2e70a948f05c

📥 Commits

Reviewing files that changed from the base of the PR and between 3731c7a and 4d5a067.

⛔ Files ignored due to path filters (2)
  • measurements/stages.tsv is excluded by !**/*.tsv
  • measurements/tcp.csv is excluded by !**/*.csv
📒 Files selected for processing (3)
  • README.md
  • app/syslog/Syslog.c
  • run-report.md
🚧 Files skipped from review as they are similar to previous changes (2)
  • README.md
  • app/syslog/Syslog.c

📝 Walkthrough

Walkthrough

Syslog delivery changes from UDP to lwIP TCP with collector port 5601 and bounded connection yielding. README and run-report documentation now describe TCP framing and record refreshed TCP resource measurements.

Changes

TCP syslog transport

Layer / File(s) Summary
Configure lwIP TCP syslog delivery
app/syslog/Syslog.c
Replaces the UDP sender configuration with a TCP stream sender, adds SyslogSleep() for connection yielding, and changes the collector port to 5601.
Document TCP behavior and measurements
README.md, run-report.md
Updates TCP framing descriptions, stage cost values, run metadata, binary size checks, and TCP self-check measurements.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly states the main change: switching syslog transport from UDP to TCP.
Description check ✅ Passed It follows the template and includes the required stage summary plus all checklist items.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch stage/tcp

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
README.md (1)

15-17: 🔒 Security & Privacy | 🔵 Trivial

Document that this stage uses plaintext TCP.

TCP improves stream delivery but does not provide confidentiality or authentication. Add a note that sensitive logs still require TLS/mTLS or another authenticated transport; the upstream library describes RFC 6587 plain TCP as a legacy/interoperability option. (github.com)

🤖 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 `@README.md` around lines 15 - 17, Update the README section describing the TCP
sender to explicitly state that it uses plaintext RFC 6587 TCP without
confidentiality or authentication. Add guidance that sensitive logs require
TLS/mTLS or another authenticated transport, while retaining the existing
delivery and framing description.
🤖 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 `@README.md`:
- Around line 15-20: Update the README section describing TCP delivery to remove
claims that failed records are retained or retried, and avoid equating TCP
retransmission with collector-level acceptance. Keep only guarantees supported
by the current SolidSyslogNullStore-based sender configuration, unless the
implementation is changed to provide actual store-and-forward behavior.

---

Nitpick comments:
In `@README.md`:
- Around line 15-17: Update the README section describing the TCP sender to
explicitly state that it uses plaintext RFC 6587 TCP without confidentiality or
authentication. Add guidance that sensitive logs require TLS/mTLS or another
authenticated transport, while retaining the existing delivery and framing
description.
🪄 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: a38459c2-70e1-452f-b8fa-3e903a1d81fc

📥 Commits

Reviewing files that changed from the base of the PR and between 56a66eb and 3731c7a.

⛔ Files ignored due to path filters (2)
  • measurements/stages.tsv is excluded by !**/*.tsv
  • measurements/tcp.csv is excluded by !**/*.csv
📒 Files selected for processing (3)
  • README.md
  • app/syslog/Syslog.c
  • run-report.md

Comment thread README.md Outdated
A StreamSender over an lwIP TCP stream replaces the UDP sender, and the collector
moves to 5601. Records are framed by octet count (RFC 6587), which is what a
receiver expects on a stream transport.

  Flash       +7,320 B    (+532 on the previous stage)
  RAM         +5,856 B      (+180)
  Log stack     +448 B  (unchanged)
  Service       +672 B       (-56)

TCP before TLS is deliberate. It is the smaller step — a stream, a connect and a
framing rule, with no certificates in the picture — and it gives store-and-forward
somewhere to spool before crypto arrives. It also completes what the sequenceId
started: the transport now detects loss where it happens, while the sequence only
reveals it afterwards.

The flash is small because the baseline already holds a real mTLS session, so
lwIP's TCP code was in the image before this stage asked for it. What is charged
here is the stream and the sender in front of it, and the 180 bytes of RAM are
those two objects in SolidSyslog's static pool.

The log stack does not move at all: a task that calls Log is unaffected by the
transport underneath it. The service seam's high-water actually fell 56 bytes —
this stream's send path measures shallower than the datagram's — but the seam
stays 2 KiB, so nothing is given back. The stream takes a Sleep callback because
a connect is not instantaneous and the library will not pick a blocking primitive
on your behalf; one vTaskDelay is the whole of it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@DavidCozens
DavidCozens merged commit 3f1847f into main Jul 29, 2026
2 checks passed
@DavidCozens
DavidCozens deleted the stage/tcp branch July 29, 2026 19:24
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.

1 participant