[client] pqkem: address review findings on convergence, strict parsing and status

Bot review (CodeRabbit, cubic) on PR #7098 surfaced several real defects:

- Strict() parsed the raw env value instead of the normalized one, so a
  mixed-case NB_PQ_MLKEM_STRICT such as "tRuE" silently disabled fail-closed
  mode. Parse the lower-cased value, matching Enabled().
- OnDataPathMessage labeled a data-path answer as "signal" in logs, mislabeling
  every rotation answer. Use the data-path label.
- A failed sendAnswer aborted the whole connection setup, skipping the relay/ICE
  listeners; a transient signalling failure now still brings the local transport
  up (the peer retries the answer).
- processOffer left the reserved exchange slot in place when Respond failed, so
  every retransmission of that offer was dropped forever. Clear the reservation
  on a pre-commit error so a retry can derive again.
- Dropped a no-op time.Since that implied a convergence-latency metric that was
  never recorded, and the now-unused startedAt field.
- The strict-mode status line asserted active blocking even for a peer that is
  simply offline; reword it to state that no PSK is established yet.
- conn_test used t.Fatalf for conditions under test; use assert.
This commit is contained in:
riccardom
2026-10-05 16:02:33 +02:00
parent dd07b12f63
commit 89ec00eb20
6 changed files with 20 additions and 17 deletions
+2 -6
View File
@@ -296,16 +296,12 @@ func TestConn_presharedKey_RosenpassManaged(t *testing.T) {
// When Rosenpass has already initialized the PSK for this peer,
// presharedKey must return nil to avoid UpdatePeer overwriting it.
conn.rosenpassInitializedPresharedKeyValidator = func(peerKey string) bool { return true }
if k := conn.presharedKey([]byte("remote"), nil); k != nil {
t.Fatalf("expected nil presharedKey when Rosenpass manages PSK, got %v", k)
}
assert.Nil(t, conn.presharedKey([]byte("remote"), nil), "expected nil presharedKey when Rosenpass manages PSK")
// When Rosenpass hasn't taken over yet, presharedKey should provide
// a non-nil initial key (deterministic or from NetBird PSK).
conn.rosenpassInitializedPresharedKeyValidator = func(peerKey string) bool { return false }
if k := conn.presharedKey([]byte("remote"), nil); k == nil {
t.Fatalf("expected non-nil presharedKey before Rosenpass manages PSK")
}
assert.NotNil(t, conn.presharedKey([]byte("remote"), nil), "expected non-nil presharedKey before Rosenpass manages PSK")
}
func newWGTimeoutTestConn(rosenpassEnabled bool, disconnected *[]string) *Conn {
+3 -2
View File
@@ -171,10 +171,11 @@ func (h *Handshaker) handleRemoteOffer(remoteOfferAnswer OfferAnswer) {
// Derive+store the KEM PSK (inside sendAnswer's AnswerPayload) BEFORE bringing up the
// connection: the relay/ICE workers configure the WG endpoint, which pulls the PSK
// for the first handshake. Notifying them first would race the KEM exchange and hand
// the first handshake a not-yet-derived key.
// the first handshake a not-yet-derived key. A failure to signal the answer is
// transient (the peer retries), so still bring the local transport up over relay/ICE
// instead of aborting the whole setup.
if err := h.sendAnswer(&remoteOfferAnswer); err != nil {
h.log.Errorf("failed to send remote offer confirmation: %s", err)
return
}
h.notifyListeners(&remoteOfferAnswer)
}