From 5e6fd2867eb6229d05f9a995a1348ba40c7bc1a4 Mon Sep 17 00:00:00 2001 From: Erik Dubbelboer Date: Mon, 30 Mar 2026 04:57:31 +0200 Subject: [PATCH] Fix context race condition `ctx` was being overwritten while it was being used in a different goroutine. --- internal/signaling/handler.go | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/internal/signaling/handler.go b/internal/signaling/handler.go index a2edd91..9ffad3a 100644 --- a/internal/signaling/handler.go +++ b/internal/signaling/handler.go @@ -161,8 +161,11 @@ func Handler(ctx context.Context, store stores.Store, cloudflare *cloudflare.Cre util.ErrorAndDisconnect(ctx, conn, err) } + // Use a local variable for the request-scoped context to avoid + // a data race with the ping goroutine that also reads ctx. + reqCtx := ctx if base.RequestID != "" { - ctx = util.WithRequestID(ctx, base.RequestID) + reqCtx = util.WithRequestID(reqCtx, base.RequestID) } if peer.closedPacketReceived { @@ -174,24 +177,24 @@ func Handler(ctx context.Context, store stores.Store, cloudflare *cloudflare.Cre switch base.Type { case "credentials": - credentials, err := cloudflare.GetCredentials(ctx) + credentials, err := cloudflare.GetCredentials(reqCtx) if err != nil { - util.ReplyError(ctx, conn, err) + util.ReplyError(reqCtx, conn, err) } else { packet := CredentialsPacket{ Type: "credentials", Credentials: *credentials, RequestID: base.RequestID, } - if err := peer.Send(ctx, packet); err != nil { - util.ErrorAndDisconnect(ctx, conn, err) + if err := peer.Send(reqCtx, packet); err != nil { + util.ErrorAndDisconnect(reqCtx, conn, err) } } case "event": params := metrics.EventParams{} if err := json.Unmarshal(raw, ¶ms); err != nil { - util.ErrorAndDisconnect(ctx, conn, err) + util.ErrorAndDisconnect(reqCtx, conn, err) } // Add country and region to event data of the avg-latency-at-10s event. @@ -207,17 +210,17 @@ func Handler(ctx context.Context, store stores.Store, cloudflare *cloudflare.Cre } } - go metrics.RecordEvent(ctx, params) + go metrics.RecordEvent(reqCtx, params) case "ping", "pong": // ignore, ping/pong is just for the tcp keepalive. default: - if err := peer.HandlePacket(ctx, base.Type, raw); err != nil { + if err := peer.HandlePacket(reqCtx, base.Type, raw); err != nil { if err == ErrUnknownPacketType { logger.Warn("unknown packet type received", zap.String("type", base.Type), zap.String("peer", peer.ID), zap.String("game", peer.Game), zap.String("origin", r.Header.Get("Origin"))) } else { - util.ErrorAndDisconnect(ctx, conn, err) + util.ErrorAndDisconnect(reqCtx, conn, err) } } }