Repository navigation
refactor: one resync path in send and the SNMPv3 negotiation in its steps - #45
Merged
Merged
Conversation
ilyam8
added this pull request to stack #38
October 9, 2026 21:08
ilyam8
force-pushed
the
engine-send
branch
2 times, most recently
from
October 11, 2026 09:46
053f493 to
924c431
Compare
Mutation probes on send's restructuring found its resynchronization path unpinned in four places: - resync/panic-in-retransmission: a panic during the retransmission is returned as the recover error together with the Report, the result the request had when it panicked (send's named results). - resync/security-model-changed-by-hook: a hook that changes the client's security model before the retransmission makes the packet update fail, and the request returns its error. - resync/retransmission-answered-by-report: a Report answering the retransmission is returned with ErrNotInTimeWindow (known bug). - resync/retransmission-answer-time: the engine time of the answer to the retransmission is not stored (known bug). All four pass on the current code.
…teps send handled the two Reports that resynchronize the client, notInTimeWindow and unknownEngineID, in two copies of the same branch, and recognized them with its own switch beside the table answers used. - reportKinds replaces reportErrors: each Report counter gives the request's error, whether it resynchronizes the client and its name in log lines; reportKindOf serves answers and send. - send keeps the boundary (recover with its named results, the Conn and Retries checks, the negotiation) and hands a resync Report to resync, which updates the packet, sends it again and returns the Report's error if that fails. - negotiateInitialSecurityParameters discovers the engine (discoverEngine) or derives the keys; engineFoundDespiteUnknownUser names the tolerance for devices that answer discovery with usmStatsUnknownUserNames. Its two guards are gone: mkSnmpPacket copies the client's version and security model, send negotiates only for an SNMPv3 packet, and no hook runs in between. Each known bug of these functions keeps one site with a known-bug comment, setSecurityParameters' included; the stale RFC 2574 comment is replaced. No behavior change: goldens and logger output unchanged.
BenchmarkSendOneRequest stops below send, so the negotiation, the store and the resync dispatch had no benchmark. BenchmarkGet runs an SNMPv2c Get on the in-memory transport; BenchmarkGetV3 an authNoPriv Get after discovery against the fake agent.
…hanges the client
Review of send's restructuring found two paths no scenario observed; both
pins pass on the code before it.
- discovery/report-without-engine-id/{md5,sha-aes}: a discovery Report
without an engine ID is accepted and the request goes out with an empty
engine ID; at authPriv it fails in the encoder for want of a privacy key
(known bug).
- hooks/logger-changes-{security-model,version}: the client's Logger is user
code that runs inside send before the negotiation; when it changes the
client's security model or version, the negotiation's guards end the
request with an empty packet.
…wn bugs Review of send's restructuring: - The two guards of negotiateInitialSecurityParameters come back: the client's Logger runs inside send between mkSnmpPacket and the negotiation, so a Logger that changes the client reaches them. - The retransmission failure's log line passes the same format and argument to the Logger as before (the text was the same, the call was not). - Known-bug comments: setSecurityParameters adopts boots and time from any accepted message and keeps the time without the moment it arrived (the 150 s notInTimeWindow round trip, moved here from resync); storeSecurityParameters takes the context engine ID only while it is empty; discovery accepts an answer without an engine ID; the discovery exception of testAuthentication skips the digest for any message with an empty user name and engine ID; resync returns a nil error for a resync Report only. - reportKind.resync and reportKindOf say what they decide more precisely. No behavior change: goldens and logger output (method, format, arguments) unchanged.
All pass on the code before send's restructuring: - hooks/logger-panics-after-failed-retransmission: a Logger that panics on the retransmission's failure line ends the request with the Report that answered the retransmission, not the first one. - hooks/onfinish-changes-version: a hook that changes the client's version during the request makes the store fail, and the request returns its error with the reply. - resync/report-for-other-request-id: a notInTimeWindow Report for another request ID still resynchronizes the request (known bug). - resync/retransmission-answered-by-authenticated-report: the engine time of an authenticated Report answering the retransmission is not stored (known bug). - discovery/report-without-engine-id/sha256-des: with DES, a discovery answer without an engine ID makes the encoder panic (known bug). onLogging replaces the Logger helper of the previous pins and records the line it acts on.
send's recover returns the result held by its named results when a panic, user code's included, ends the request. With the retransmission in a helper, a Logger panicking on the retransmission's failure line returned the first Report instead of the retransmission's answer. The resynchronization is one paragraph of send again, with its known-bug comments; resync is gone. No behavior change: goldens and logger output unchanged.
vkalintiris
approved these changes
Oct 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Restructures
send, the request boundary, and the SNMPv3 negotiation. No behavior or exported API change.sendhandled the two Reports that resynchronize the client (notInTimeWindow, unknownEngineID) in two copies of the same branch, and recognized them with its ownswitchbeside the tableanswersused.reportKinds(replacingreportErrors): each Report counter gives the request's error, whether it resynchronizes the client, and its name in log lines;reportKindOfserves bothanswersandsend.sendkeeps the boundary (recover, theConnandRetrieschecks, the negotiation) and resynchronizes in one paragraph: update the packet, send it again, return the Report's error if that fails. The retransmission stays insendon purpose: every result passes through its named results, which therecoverreturns when a panic (user code's included, such as a Logger) ends the request.negotiateInitialSecurityParameterseither discovers the engine (discoverEngine, RFC 3414 section 4) or derives the keys;engineFoundDespiteUnknownUsernames the tolerance for devices that answer discovery with usmStatsUnknownUserNames. Its guards stay: the client's Logger runs insidesendbefore the negotiation and can change the client.Each known bug of these functions keeps one site with a known-bug comment (
setSecurityParameters,storeSecurityParametersand the discovery exception oftestAuthenticationincluded); the stale RFC 2574 comment is replaced.The test commits pin what mutation probes and two reviews found unobserved, each passing on the previous code: a panic during the retransmission (from a hook or the Logger), hooks and a Logger that change the client, Reports answering the retransmission, a resync Report for another request ID, a discovery answer without an engine ID (AES, DES, MD5), and the engine time of the retransmission's answer (several of these are known bugs).
BenchmarkGetandBenchmarkGetV3run throughsend(BenchmarkSendOneRequeststops below it).Testing
go test ./...on darwin/arm64 andGOARCH=386;-race; the FIPS 140-only tests; golangci-lint v2.14.0 (incl.end2end): 0 issues;GOOS=windows go vet.BenchmarkSendOneRequest,BenchmarkGetandBenchmarkGetV3within noise, B/op and allocs/op identical.