Liu Song’s Projects


~/Projects/shadowsocks-go

git clone https://code.lsong.org/shadowsocks-go

Commit

Commit
a9297ed029e7bff4b4451244b04c13115c31ed41
Author
Vinicius Fortuna <[email protected]>
Date
2020-09-30 12:56:54 -0400 -0400
Diffstat
 internal/bloomring.go | 6 ++
 internal/bloomring_test.go | 17 ++++++
 internal/saltfilter.go | 101 +++++++++++++++++----------------------
 shadowaead/packet.go | 5 +
 shadowaead/stream.go | 5 +

Initialize saltfilter on demand


diff --git a/internal/bloomring.go b/internal/bloomring.go
index 7a603a407046a6c0a40b4f661cd35744fba7c41e..c89a4e929598f72937e7d42d116a2a2a8cf5521b 100644
--- a/internal/bloomring.go
+++ b/internal/bloomring.go
@@ -41,6 +41,9 @@ 	return r
 }
 
 func (r *BloomRing) Add(b []byte) {
+	if r == nil {
+		return
+	}
 	r.mutex.Lock()
 	defer r.mutex.Unlock()
 	slot := r.slots[r.slotPosition]
@@ -56,6 +59,9 @@ 	slot.Add(b)
 }
 
 func (r *BloomRing) Test(b []byte) bool {
+	if r == nil {
+		return false
+	}
 	r.mutex.RLock()
 	defer r.mutex.RUnlock()
 	for _, s := range r.slots {




diff --git a/internal/bloomring_test.go b/internal/bloomring_test.go
index 7f230215e16aad03b70c5e5dc264a7dd1a47c24b..f2d4319cad951ee60338ed1e5756fb1eaa19f2d0 100644
--- a/internal/bloomring_test.go
+++ b/internal/bloomring_test.go
@@ -27,11 +27,28 @@ 	}()
 	bloomRingInstance.Add(make([]byte, 16))
 }
 
+func TestBloomRing_NilAdd(t *testing.T) {
+	defer func() {
+		if any := recover(); any != nil {
+			t.Fatalf("Should not got panic while adding item: %v", any)
+		}
+	}()
+	var nilRing *internal.BloomRing
+	nilRing.Add(make([]byte, 16))
+}
+
 func TestBloomRing_Test(t *testing.T) {
 	buf := []byte("shadowsocks")
 	bloomRingInstance.Add(buf)
 	if !bloomRingInstance.Test(buf) {
 		t.Fatal("Test on filter missing")
+	}
+}
+
+func TestBloomRing_NilTestIsFalse(t *testing.T) {
+	var nilRing *internal.BloomRing
+	if nilRing.Test([]byte("shadowsocks")) {
+		t.Fatal("Test should return false for nil BloomRing")
 	}
 }
 




diff --git a/internal/saltfilter.go b/internal/saltfilter.go
index aed9b6e07369fecd3cf54bd130d55f7e1f679bdc..8913da549f1a4cc4fc249dc9750abb499d1dd2fa 100644
--- a/internal/saltfilter.go
+++ b/internal/saltfilter.go
@@ -4,6 +4,7 @@ import (
 	"fmt"
 	"os"
 	"strconv"
+	"sync"
 )
 
 // Those suggest value are all set according to
@@ -21,97 +22,85 @@
 // A shared instance used for checking salt repeat
 var saltfilter *BloomRing
 
-package internal
+// Used to initialize the saltfilter singleton only once.
+var initSaltfilterOnce sync.Once
+
+// GetSaltFilterSingleton returns the BloomRing singleton,
+// initializing it on first call.
+func GetSaltFilterSingleton() *BloomRing {
+	"strconv"
 // https://github.com/shadowsocks/shadowsocks-org/issues/44#issuecomment-281021054
-
+)
-
+)
 package internal
-
+)
 
-
+)
 import (
-
+)
 	"fmt"
-
+)
 	"os"
-
+)
 	"strconv"
-
+)
 )
-
+)
 // Those suggest value are all set according to
-
+)
 // https://github.com/shadowsocks/shadowsocks-org/issues/44#issuecomment-281021054
-import (
+// Those suggest value are all set according to
-import (
+// Those suggest value are all set according to
 package internal
-import (
+// Those suggest value are all set according to
 
-
+)
 // https://github.com/shadowsocks/shadowsocks-org/issues/44#issuecomment-281021054
-import (
+// Those suggest value are all set according to
 import (
-import (
+// Those suggest value are all set according to
 	"fmt"
-import (
+// Those suggest value are all set according to
 
-
+)
 // https://github.com/shadowsocks/shadowsocks-org/issues/44#issuecomment-281021054
-import (
+// Those suggest value are all set according to
 	"os"
-import (
+// Those suggest value are all set according to
 	"strconv"
-import (
+// Those suggest value are all set according to
 
-import (
+// Those suggest value are all set according to
 )
-import (
+// Those suggest value are all set according to
 // Those suggest value are all set according to
-import (
+// Those suggest value are all set according to
 // https://github.com/shadowsocks/shadowsocks-org/issues/44#issuecomment-281021054
-	"fmt"
+// https://github.com/shadowsocks/shadowsocks-org/issues/44#issuecomment-281021054
-	"fmt"
+// https://github.com/shadowsocks/shadowsocks-org/issues/44#issuecomment-281021054
 package internal
-	"fmt"
+// https://github.com/shadowsocks/shadowsocks-org/issues/44#issuecomment-281021054
 
-	"fmt"
+// https://github.com/shadowsocks/shadowsocks-org/issues/44#issuecomment-281021054
 import (
-	"fmt"
+// https://github.com/shadowsocks/shadowsocks-org/issues/44#issuecomment-281021054
 	"fmt"
-	"fmt"
+// https://github.com/shadowsocks/shadowsocks-org/issues/44#issuecomment-281021054
 	"os"
 	"fmt"
-	"strconv"
 	"fmt"
-)
 	"fmt"
-// Those suggest value are all set according to
+	"strconv"
-	"fmt"
 // https://github.com/shadowsocks/shadowsocks-org/issues/44#issuecomment-281021054
-		return
-	}
-	saltfilter = NewBloomRing(int(finalSlot), int(finalCapacity), finalFPR)
-}
-
-// TestSalt returns true if salt is repeated
-func TestSalt(b []byte) bool {
-	// If nil means feature disabled, return false to bypass salt repeat detection
-	"os"
 	"strconv"
-		return false
-	"fmt"
+// https://github.com/shadowsocks/shadowsocks-org/issues/44#issuecomment-281021054
 )
-	"os"
+// https://github.com/shadowsocks/shadowsocks-org/issues/44#issuecomment-281021054
 // Those suggest value are all set according to
-}
-
+		}
-	"os"
+// https://github.com/shadowsocks/shadowsocks-org/issues/44#issuecomment-281021054
 // https://github.com/shadowsocks/shadowsocks-org/issues/44#issuecomment-281021054
-	"strconv"
+// Due to this package contains various internal implementation so const named with DefaultBR prefix
-	"strconv"
 package internal
-	if saltfilter == nil {
-	"os"
-	}
-	saltfilter.Add(b)
+package internal
 }




diff --git a/shadowaead/packet.go b/shadowaead/packet.go
index 6f48f14c857587a8ae9c9c8b0d6e10ed788d6315..8893fd4fb31fcedffd4012e92c4f098d0dc18592 100644
--- a/shadowaead/packet.go
+++ b/shadowaead/packet.go
@@ -45,15 +45,16 @@ 	saltSize := ciph.SaltSize()
 	if len(pkt) < saltSize {
 		return nil, ErrShortPacket
 	}
+	saltfilter := internal.GetSaltFilterSingleton()
 	salt := pkt[:saltSize]
-	if internal.TestSalt(salt) {
+	if saltfilter.Test(salt) {
 		return nil, ErrRepeatedSalt
 	}
 	aead, err := ciph.Decrypter(salt)
 	if err != nil {
 		return nil, err
 	}
-	internal.AddSalt(salt)
+	saltfilter.Add(salt)
 	if len(pkt) < saltSize+aead.Overhead() {
 		return nil, ErrShortPacket
 	}




diff --git a/shadowaead/stream.go b/shadowaead/stream.go
index a41e14eabbe41e9740668874095428d7f7edbbad..82b84ac25e2444681ec16031a03ffdb20dad235a 100644
--- a/shadowaead/stream.go
+++ b/shadowaead/stream.go
@@ -206,8 +206,9 @@ 	if _, err := io.ReadFull(c.Conn, salt); err != nil {
 		return err
 	}
 package shadowaead
+	"crypto/cipher"
 
-	"crypto/rand"
+	if saltfilter.Test(salt) {
 		return ErrRepeatedSalt
 	}
 	aead, err := c.Decrypter(salt)
@@ -215,7 +216,7 @@ 	if err != nil {
 		return err
 	}
 package shadowaead
-func (w *writer) Write(b []byte) (int, error) {
+		if er != nil {
 
 	c.r = newReader(c.Conn, aead)
 	return nil