Skip to content

fix: accept an acknowledgement carrying a VarBindList - #13

Merged
marcinpsk merged 1 commit into
mainfrom
fix/accept-varbind-list-acknowledgement
Sep 14, 2026
Merged

marcinpsk merged 1 commit into
mainfrom
fix/accept-varbind-list-acknowledgement

Conversation

@marcinpsk

@marcinpsk marcinpsk commented Sep 14, 2026

Copy link
Copy Markdown
Owner

The problem

The subagent never registers against net-snmp. It connects, sends Open, rejects the reply, and loops:

[INFO] Connecting to AgentX master at /var/agentx/master
[WARN] AgentX session ended: unexpected AgentX acknowledgement
[INFO] Reconnecting in 1 seconds
... 2, 4, 8, 16, 30 ...

Walking 1.3.6.1.2.1.31.1.2 returns nothing, because the session is torn down before it serves anything.

Cause

acknowledge() required the Response payload to be exactly 8 bytes. A Response PDU is sysUpTime, error and index followed by a VarBindList (RFC 2741 §6.2.11), and the master is free to populate it. net-snmp does.

Probing a live master directly over its Unix socket with a hand-rolled Open and Register:

OPEN     -> type=18 (Response)  payload_length=40  error=0  session=21
REGISTER -> type=18 (Response)  payload_length=32  error=0  session=21

Type, transactionID and packetID all match and the error is noAgentXError, so both operations actually succeeded and the session was granted. Only the length check refused them, which means the region was registered on the master while the subagent tore the connection down.

The fix

Compare against 8 instead of requiring equality. The function only reads the fixed 8-byte block at bytes[24..28], so a longer payload needs no other handling.

Why existing tests missed it

tests/support/agentx.rs answers with Response::from_header(...), whose VarBindList is empty and whose payload is therefore exactly 8 — a length no real master sends. The suite has never exercised a response shaped like net-snmp's.

The added unit test drives acknowledge() over a socket pair with a net-snmp-shaped reply for both Open and Register. Restoring the old comparison makes it fail with the production message:

a master response carrying a VarBindList is a valid acknowledgement:
  Custom { kind: InvalidData, error: "unexpected AgentX acknowledgement" }

Reproduced on

Two unrelated hosts, so this is not load or version specific:

host OS net-snmp load interfaces
A Ubuntu 22.04.5 5.9.1 98 1062
B Debian 13 packaged 0.60 20

Both installed from the v0.2.0 release .deb and run in the foreground.

Checks

cargo fmt --check, cargo clippy --all-targets -- -D warnings, cargo test (47 + 6 + 1, 7 root-only ignored) and scripts/opengrep-scan.sh all pass.

One unrelated observation

acknowledge() collapses type, payload length, packet id, transaction id and session id into a single message, so every cause reads the same. Naming the mismatched field and its value would turn a multi-run investigation into one. Happy to follow up separately if useful.

Summary by CodeRabbit

  • Bug Fixes
    • Improved compatibility with net-snmp masters by accepting acknowledgement responses that include additional VarBindList data.
    • Open and Register acknowledgements with extended payloads are now handled successfully.

The subagent never registers against net-snmp. It connects, sends Open, and
rejects the reply, logging "AgentX session ended: unexpected AgentX
acknowledgement" before backing off 1, 2, 4, 8, 16 and 30 seconds forever.

acknowledge() required the Response payload to be exactly 8 bytes. A Response
PDU is sysUpTime, error and index followed by a VarBindList (RFC 2741 6.2.11),
and the master may populate it. net-snmp does. Probing a live master directly
over its Unix socket:

  OPEN     -> type=18 payload_length=40 error=0 session=21
  REGISTER -> type=18 payload_length=32 error=0 session=21

Type, transactionID and packetID all matched and the error was
noAgentXError, so both operations had in fact succeeded and the session was
granted. Only the length check refused them, so the region was registered on
the master while the subagent tore the connection down.

Comparing against 8 rather than requiring equality fixes it. The function only
reads the fixed 8 byte block at bytes[24..28], so a longer payload needs no
other handling.

Reproduced on two unrelated hosts: Ubuntu 22.04 with net-snmp 5.9.1 and
Debian 13 with a healthy, idle snmpd. The existing coverage misses it because
the test master answers with Response::from_header, whose VarBindList is empty
and whose payload is therefore exactly 8, which no real master sends.

The added test drives acknowledge() over a socket pair with a net-snmp shaped
reply for both Open and Register, and fails with the production error message
when the comparison is restored.
@coderabbitai

coderabbitai Bot commented Sep 14, 2026

Copy link
Copy Markdown

Review Change StackReview Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 89bf249b-6a06-48e9-a96e-6dff504c3b81

📥 Commits

Reviewing files that changed from the base of the PR and between c8a8703 and f82c03e.

📒 Files selected for processing (1)
  • src/session.rs

Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review.


Walkthrough

The acknowledgement parser now accepts AgentX Response PDUs with payloads of at least 8 bytes. A test verifies Open and Register acknowledgements that include VarBindList data.

Changes

Acknowledgement payload handling

Layer / File(s) Summary
Payload validation and coverage
src/session.rs
acknowledge accepts payloads of at least 8 bytes and reads the fixed response fields. The test verifies Open and Register responses with VarBindList data.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to f82c0

The acknowledgement parser now accepts valid longer responses without weakening validation of the required fixed fields. No actionable merge-blocking risk remains.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 3 functions across 1 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: accepting acknowledgements that include a VarBindList.
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.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/accept-varbind-list-acknowledgement
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch fix/accept-varbind-list-acknowledgement

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

A rabbit checks the response byte,
Eight fields pass, and all is right.
Open and Register cross the stream,
VarBind tails now join the team.
The session ID returns with cheer.

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

@marcinpsk
marcinpsk merged commit f931fcf into main Sep 14, 2026
15 checks passed
@marcinpsk
marcinpsk deleted the fix/accept-varbind-list-acknowledgement branch September 15, 2026 08:42
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