[tor-commits] [pluggable-transports/snowflake] branch main updated: Fix broker race condition

gitolite role git at cupani.torproject.org
Tue Jul 26 21:57:25 UTC 2022


This is an automated email from the git hooks/post-receive script.

itchyonion pushed a commit to branch main
in repository pluggable-transports/snowflake.

The following commit(s) were added to refs/heads/main by this push:
     new 03b2b56  Fix broker race condition
03b2b56 is described below

commit 03b2b56f879879bb379cff8d7352ace1102d8811
Author: itchyonion <itchyonion at torproject.com>
AuthorDate: Thu May 26 23:26:38 2022 -0700

    Fix broker race condition
---
 broker/broker.go |  2 +-
 broker/ipc.go    | 41 ++++++++++++++++++++++-------------------
 2 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/broker/broker.go b/broker/broker.go
index 2bf4614..c356de9 100644
--- a/broker/broker.go
+++ b/broker/broker.go
@@ -154,8 +154,8 @@ func (ctx *BrokerContext) AddSnowflake(id string, proxyType string, natType stri
 		heap.Push(ctx.restrictedSnowflakes, snowflake)
 	}
 	ctx.metrics.promMetrics.AvailableProxies.With(prometheus.Labels{"nat": natType, "type": proxyType}).Inc()
-	ctx.snowflakeLock.Unlock()
 	ctx.idToSnowflake[id] = snowflake
+	ctx.snowflakeLock.Unlock()
 	return snowflake
 }
 
diff --git a/broker/ipc.go b/broker/ipc.go
index 30de180..6b8971f 100644
--- a/broker/ipc.go
+++ b/broker/ipc.go
@@ -190,19 +190,10 @@ func (i *IPC) ClientOffers(arg messages.Arg, response *[]byte) error {
 
 	offer.fingerprint = BridgeFingerprint.ToBytes()
 
-	// Only hand out known restricted snowflakes to unrestricted clients
-	var snowflakeHeap *SnowflakeHeap
-	if offer.natType == NATUnrestricted {
-		snowflakeHeap = i.ctx.restrictedSnowflakes
+	snowflake := i.matchSnowflake(offer.natType)
+	if snowflake != nil {
+		snowflake.offerChannel <- offer
 	} else {
-		snowflakeHeap = i.ctx.snowflakes
-	}
-
-	// Immediately fail if there are no snowflakes available.
-	i.ctx.snowflakeLock.Lock()
-	numSnowflakes := snowflakeHeap.Len()
-	i.ctx.snowflakeLock.Unlock()
-	if numSnowflakes <= 0 {
 		i.ctx.metrics.lock.Lock()
 		i.ctx.metrics.clientDeniedCount++
 		i.ctx.metrics.promMetrics.ClientPollTotal.With(prometheus.Labels{"nat": offer.natType, "status": "denied"}).Inc()
@@ -216,13 +207,6 @@ func (i *IPC) ClientOffers(arg messages.Arg, response *[]byte) error {
 		return sendClientResponse(resp, response)
 	}
 
-	// Otherwise, find the most available snowflake proxy, and pass the offer to it.
-	// Delete must be deferred in order to correctly process answer request later.
-	i.ctx.snowflakeLock.Lock()
-	snowflake := heap.Pop(snowflakeHeap).(*Snowflake)
-	i.ctx.snowflakeLock.Unlock()
-	snowflake.offerChannel <- offer
-
 	// Wait for the answer to be returned on the channel or timeout.
 	select {
 	case answer := <-snowflake.answerChannel:
@@ -248,6 +232,25 @@ func (i *IPC) ClientOffers(arg messages.Arg, response *[]byte) error {
 	return err
 }
 
+func (i *IPC) matchSnowflake(natType string) *Snowflake {
+	// Only hand out known restricted snowflakes to unrestricted clients
+	var snowflakeHeap *SnowflakeHeap
+	if natType == NATUnrestricted {
+		snowflakeHeap = i.ctx.restrictedSnowflakes
+	} else {
+		snowflakeHeap = i.ctx.snowflakes
+	}
+
+	i.ctx.snowflakeLock.Lock()
+	defer i.ctx.snowflakeLock.Unlock()
+
+	if snowflakeHeap.Len() > 0 {
+		return heap.Pop(snowflakeHeap).(*Snowflake)
+	} else {
+		return nil
+	}
+}
+
 func (i *IPC) ProxyAnswers(arg messages.Arg, response *[]byte) error {
 	answer, id, err := messages.DecodeAnswerRequest(arg.Body)
 	if err != nil || answer == "" {

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the tor-commits mailing list