From f2270835391879ccd3fd465934a33ceae84a1302 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Fri, 31 May 2024 08:06:14 -0700 Subject: [PATCH] derp: add some guardrails for derpReason metrics getting out of sync The derp metrics got out of sync in 74eb99aed17539 (2023-03). They were fixed in 0380cbc90d6 (2024-05). This adds some further guardrails (atop the previous fix) to make sure they don't get out of sync again. Updates #12288 Change-Id: I809061a81f8ff92f45054d0253bc13871fc71634 Signed-off-by: Brad Fitzpatrick --- derp/derp_server.go | 33 ++++++++++++++++++++++++--------- derp/dropreason_string.go | 5 +++-- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/derp/derp_server.go b/derp/derp_server.go index 3f08a6487..11ba82661 100644 --- a/derp/derp_server.go +++ b/derp/derp_server.go @@ -330,21 +330,35 @@ func NewServer(privateKey key.NodePrivate, logf logger.Logf) *Server { s.packetsRecvDisco = s.packetsRecvByKind.Get("disco") s.packetsRecvOther = s.packetsRecvByKind.Get("other") - s.packetsDroppedReasonCounters = []*expvar.Int{ - dropReasonUnknownDest: s.packetsDroppedReason.Get("unknown_dest"), - dropReasonUnknownDestOnFwd: s.packetsDroppedReason.Get("unknown_dest_on_fwd"), - dropReasonGoneDisconnected: s.packetsDroppedReason.Get("gone_disconnected"), - dropReasonQueueHead: s.packetsDroppedReason.Get("queue_head"), - dropReasonQueueTail: s.packetsDroppedReason.Get("queue_tail"), - dropReasonWriteError: s.packetsDroppedReason.Get("write_error"), - dropReasonDupClient: s.packetsDroppedReason.Get("dup_client"), - } + s.packetsDroppedReasonCounters = s.genPacketsDroppedReasonCounters() s.packetsDroppedTypeDisco = s.packetsDroppedType.Get("disco") s.packetsDroppedTypeOther = s.packetsDroppedType.Get("other") return s } +func (s *Server) genPacketsDroppedReasonCounters() []*expvar.Int { + getMetric := s.packetsDroppedReason.Get + ret := []*expvar.Int{ + dropReasonUnknownDest: getMetric("unknown_dest"), + dropReasonUnknownDestOnFwd: getMetric("unknown_dest_on_fwd"), + dropReasonGoneDisconnected: getMetric("gone_disconnected"), + dropReasonQueueHead: getMetric("queue_head"), + dropReasonQueueTail: getMetric("queue_tail"), + dropReasonWriteError: getMetric("write_error"), + dropReasonDupClient: getMetric("dup_client"), + } + if len(ret) != int(numDropReasons) { + panic("dropReason metrics out of sync") + } + for i := range numDropReasons { + if ret[i] == nil { + panic("dropReason metrics out of sync") + } + } + return ret +} + // SetMesh sets the pre-shared key that regional DERP servers used to mesh // amongst themselves. // @@ -1049,6 +1063,7 @@ const ( dropReasonQueueTail // destination queue is full, dropped packet at queue tail dropReasonWriteError // OS write() failed dropReasonDupClient // the public key is connected 2+ times (active/active, fighting) + numDropReasons // unused; keep last ) func (s *Server) recordDrop(packetBytes []byte, srcKey, dstKey key.NodePublic, reason dropReason) { diff --git a/derp/dropreason_string.go b/derp/dropreason_string.go index 5ba500ab2..3ad072819 100644 --- a/derp/dropreason_string.go +++ b/derp/dropreason_string.go @@ -18,11 +18,12 @@ func _() { _ = x[dropReasonQueueTail-4] _ = x[dropReasonWriteError-5] _ = x[dropReasonDupClient-6] + _ = x[numDropReasons-7] } -const _dropReason_name = "UnknownDestUnknownDestOnFwdGoneDisconnectedQueueHeadQueueTailWriteErrorDupClient" +const _dropReason_name = "UnknownDestUnknownDestOnFwdGoneDisconnectedQueueHeadQueueTailWriteErrorDupClientnumDropReasons" -var _dropReason_index = [...]uint8{0, 11, 27, 43, 52, 61, 71, 80} +var _dropReason_index = [...]uint8{0, 11, 27, 43, 52, 61, 71, 80, 94} func (i dropReason) String() string { if i < 0 || i >= dropReason(len(_dropReason_index)-1) {