From 4fb13a18685099d1dea2fc337ab35aa006d3aca2 Mon Sep 17 00:00:00 2001
From: Matt Joiner <anacrolix@gmail.com>
Date: Sun, 27 Jun 2021 11:57:11 +1000
Subject: [PATCH] Fix race in concurrent connects in UDP tracker

---
 tracker/udp/client.go | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/tracker/udp/client.go b/tracker/udp/client.go
index 59714c09..aea3ec91 100644
--- a/tracker/udp/client.go
+++ b/tracker/udp/client.go
@@ -7,10 +7,12 @@ import (
 	"errors"
 	"fmt"
 	"io"
+	"sync"
 	"time"
 )
 
 type Client struct {
+	mu           sync.Mutex
 	connId       ConnectionId
 	connIdIssued time.Time
 	Dispatcher   *Dispatcher
@@ -66,6 +68,10 @@ func (cl *Client) Scrape(
 }
 
 func (cl *Client) connect(ctx context.Context) (err error) {
+	// We could get fancier here and use RWMutex, and even fire off the connection asynchronously
+	// and provide a grace period while it resolves.
+	cl.mu.Lock()
+	defer cl.mu.Unlock()
 	if !cl.connIdIssued.IsZero() && time.Since(cl.connIdIssued) < time.Minute {
 		return nil
 	}
-- 
2.51.0