Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions common/antireplay/antireplay.go

This file was deleted.

33 changes: 33 additions & 0 deletions common/antireplay/antireplay_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package antireplay

import (
"bufio"
"crypto/rand"
"testing"
)

func BenchmarkMapFilter(b *testing.B) {
filter := NewMapFilter[[16]byte](120)
var sample [16]byte
reader := bufio.NewReader(rand.Reader)
reader.Read(sample[:])
b.ResetTimer()
for range b.N {
reader.Read(sample[:])
filter.Check(sample)
}
}

func TestMapFilter(t *testing.T) {
filter := NewMapFilter[[16]byte](120)
var sample [16]byte
rand.Read(sample[:])
filter.Check(sample)
if filter.Check(sample) {
t.Error("Unexpected true negative")
}
sample[0]++
if !filter.Check(sample) {
t.Error("Unexpected false positive")
}
}
36 changes: 0 additions & 36 deletions common/antireplay/bloomring.go

This file was deleted.

46 changes: 46 additions & 0 deletions common/antireplay/mapfilter.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package antireplay

import (
"sync"
"time"
)

// ReplayFilter checks for replay attacks.
type ReplayFilter[T comparable] struct {
lock sync.Mutex
poolA map[T]struct{}
poolB map[T]struct{}
interval time.Duration
lastClean time.Time
}

// NewMapFilter create a new filter with specifying the expiration time interval in seconds.
func NewMapFilter[T comparable](interval int64) *ReplayFilter[T] {
filter := &ReplayFilter[T]{
poolA: make(map[T]struct{}),
poolB: make(map[T]struct{}),
interval: time.Duration(interval) * time.Second,
lastClean: time.Now(),
}
return filter
}

// Check determines if there are duplicate records.
func (filter *ReplayFilter[T]) Check(sum T) bool {
filter.lock.Lock()
defer filter.lock.Unlock()

now := time.Now()
if now.Sub(filter.lastClean) >= filter.interval {
filter.poolB = filter.poolA
filter.poolA = make(map[T]struct{})
filter.lastClean = now
}

_, existsA := filter.poolA[sum]
_, existsB := filter.poolB[sum]
if !existsA && !existsB {
filter.poolA[sum] = struct{}{}
}
return !(existsA || existsB)
}
58 changes: 0 additions & 58 deletions common/antireplay/replayfilter.go

This file was deleted.

4 changes: 0 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,7 @@ require (
github.com/refraction-networking/utls v1.8.2
github.com/sagernet/sing v0.5.1
github.com/sagernet/sing-shadowsocks v0.2.7
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771
github.com/stretchr/testify v1.11.1
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e
github.com/vishvananda/netlink v1.3.1
github.com/xtls/reality v0.0.0-20251014195629-e4eec4520535
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
Expand All @@ -38,15 +36,13 @@ require (
require (
github.com/andybalholm/brotli v1.0.6 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165 // indirect
github.com/google/btree v1.1.2 // indirect
github.com/juju/ratelimit v1.0.2 // indirect
github.com/klauspost/compress v1.17.4 // indirect
github.com/klauspost/cpuid/v2 v2.0.12 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/quic-go/qpack v0.6.0 // indirect
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
github.com/vishvananda/netns v0.0.5 // indirect
golang.org/x/mod v0.31.0 // indirect
golang.org/x/text v0.33.0 // indirect
Expand Down
13 changes: 0 additions & 13 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,8 @@ github.com/apernet/quic-go v0.57.2-0.20260111184307-eec823306178/go.mod h1:N1WIj
github.com/cloudflare/circl v1.6.2 h1:hL7VBpHHKzrV5WTfHCaBsgx/HGbBYlgrwvNXEVDYYsQ=
github.com/cloudflare/circl v1.6.2/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165 h1:BS21ZUJ/B5X2UVUbczfmdWH7GapPWAhxcMsDnjJTU1E=
github.com/dgryski/go-metro v0.0.0-20200812162917-85c65e2d0165/go.mod h1:c9O8+fpSOX1DM8cPNSkX/qsBWdkD4yd2dpciOWQjpBw=
github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344 h1:Arcl6UOIS/kgO2nW3A65HN+7CMjSDP/gofXL4CZt1V4=
github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
Expand Down Expand Up @@ -54,22 +51,14 @@ github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
github.com/refraction-networking/utls v1.8.2 h1:j4Q1gJj0xngdeH+Ox/qND11aEfhpgoEvV+S9iJ2IdQo=
github.com/refraction-networking/utls v1.8.2/go.mod h1:jkSOEkLqn+S/jtpEHPOsVv/4V4EVnelwbMQl4vCWXAM=
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ=
github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog=
github.com/sagernet/sing v0.5.1 h1:mhL/MZVq0TjuvHcpYcFtmSD1BFOxZ/+8ofbNZcg1k1Y=
github.com/sagernet/sing v0.5.1/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8=
github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE=
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 h1:emzAzMZ1L9iaKCTxdy3Em8Wv4ChIAGnfiz18Cda70g4=
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771/go.mod h1:bR6DqgcAl1zTcOX8/pE2Qkj9XO00eCNqmKb7lXP8EAg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e h1:5QefA066A1tF8gHIiADmOVOV5LS43gt3ONnlEl3xkwI=
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e/go.mod h1:5t19P9LBIrNamL6AcMQOncg/r10y3Pc01AbHeMhwlpU=
github.com/vishvananda/netlink v1.3.1 h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0=
github.com/vishvananda/netlink v1.3.1/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4=
github.com/vishvananda/netns v0.0.5 h1:DfiHV+j8bA32MFM7bfEunvT8IAqQ/NzSJHtcmW5zdEY=
Expand Down Expand Up @@ -154,8 +143,6 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gvisor.dev/gvisor v0.0.0-20260109181451-4be7c433dae2 h1:fr6L00yGG2RP5NMea6njWpdC+bm+cMdFClrSpaicp1c=
Expand Down
8 changes: 0 additions & 8 deletions infra/conf/shadowsocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ type ShadowsocksServerConfig struct {
Email string `json:"email"`
Users []*ShadowsocksUserConfig `json:"clients"`
NetworkList *NetworkList `json:"network"`
IVCheck bool `json:"ivCheck"`
}

func (v *ShadowsocksServerConfig) Build() (proto.Message, error) {
Expand All @@ -64,7 +63,6 @@ func (v *ShadowsocksServerConfig) Build() (proto.Message, error) {
account := &shadowsocks.Account{
Password: user.Password,
CipherType: cipherFromString(user.Cipher),
IvCheck: v.IVCheck,
}
if account.Password == "" {
return nil, errors.New("Shadowsocks password is not specified.")
Expand All @@ -83,7 +81,6 @@ func (v *ShadowsocksServerConfig) Build() (proto.Message, error) {
account := &shadowsocks.Account{
Password: v.Password,
CipherType: cipherFromString(v.Cipher),
IvCheck: v.IVCheck,
}
if account.Password == "" {
return nil, errors.New("Shadowsocks password is not specified.")
Expand Down Expand Up @@ -168,7 +165,6 @@ type ShadowsocksServerTarget struct {
Email string `json:"email"`
Cipher string `json:"method"`
Password string `json:"password"`
IVCheck bool `json:"ivCheck"`
UoT bool `json:"uot"`
UoTVersion int `json:"uotVersion"`
}
Expand All @@ -180,7 +176,6 @@ type ShadowsocksClientConfig struct {
Email string `json:"email"`
Cipher string `json:"method"`
Password string `json:"password"`
IVCheck bool `json:"ivCheck"`
UoT bool `json:"uot"`
UoTVersion int `json:"uotVersion"`
Servers []*ShadowsocksServerTarget `json:"servers"`
Expand All @@ -198,7 +193,6 @@ func (v *ShadowsocksClientConfig) Build() (proto.Message, error) {
Email: v.Email,
Cipher: v.Cipher,
Password: v.Password,
IVCheck: v.IVCheck,
UoT: v.UoT,
UoTVersion: v.UoTVersion,
},
Expand Down Expand Up @@ -254,8 +248,6 @@ func (v *ShadowsocksClientConfig) Build() (proto.Message, error) {
return nil, errors.New("unknown cipher method: ", server.Cipher)
}

account.IvCheck = server.IVCheck

ss := &protocol.ServerEndpoint{
Address: server.Address.Build(),
Port: uint32(server.Port),
Expand Down
23 changes: 2 additions & 21 deletions proxy/shadowsocks/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import (
"crypto/cipher"
"crypto/md5"
"crypto/sha1"
"google.golang.org/protobuf/proto"
"io"

"google.golang.org/protobuf/proto"

"github.com/xtls/xray-core/common"
"github.com/xtls/xray-core/common/antireplay"
"github.com/xtls/xray-core/common/buf"
"github.com/xtls/xray-core/common/crypto"
"github.com/xtls/xray-core/common/errors"
Expand All @@ -24,8 +24,6 @@ type MemoryAccount struct {
CipherType CipherType
Key []byte
Password string

replayFilter antireplay.GeneralizedReplayFilter
}

var ErrIVNotUnique = errors.New("IV is not unique")
Expand All @@ -42,18 +40,7 @@ func (a *MemoryAccount) ToProto() proto.Message {
return &Account{
CipherType: a.CipherType,
Password: a.Password,
IvCheck: a.replayFilter != nil,
}
}

func (a *MemoryAccount) CheckIV(iv []byte) error {
if a.replayFilter == nil {
return nil
}
if a.replayFilter.Check(iv) {
return nil
}
return ErrIVNotUnique
}

func createAesGcm(key []byte) cipher.AEAD {
Expand Down Expand Up @@ -116,12 +103,6 @@ func (a *Account) AsAccount() (protocol.Account, error) {
CipherType: a.CipherType,
Key: passwordToCipherKey([]byte(a.Password), Cipher.KeySize()),
Password: a.Password,
replayFilter: func() antireplay.GeneralizedReplayFilter {
if a.IvCheck {
return antireplay.NewBloomRing()
}
return nil
}(),
}, nil
}

Expand Down
10 changes: 0 additions & 10 deletions proxy/shadowsocks/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -139,9 +139,6 @@ func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Wri
if account.Cipher.IVSize() > 0 {
iv = make([]byte, account.Cipher.IVSize())
common.Must2(rand.Read(iv))
if ivError := account.CheckIV(iv); ivError != nil {
return nil, errors.New("failed to mark outgoing iv").Base(ivError)
}
if err := buf.WriteAllBytes(writer, iv, nil); err != nil {
return nil, errors.New("failed to write IV")
}
Expand Down Expand Up @@ -188,10 +185,6 @@ func ReadTCPResponse(user *protocol.MemoryUser, reader io.Reader) (buf.Reader, e
}
}

if ivError := account.CheckIV(iv); ivError != nil {
return nil, drain.WithError(drainer, reader, errors.New("failed iv check").Base(ivError))
}

return account.Cipher.NewDecryptionReader(account.Key, iv, reader)
}

Expand All @@ -203,9 +196,6 @@ func WriteTCPResponse(request *protocol.RequestHeader, writer io.Writer) (buf.Wr
if account.Cipher.IVSize() > 0 {
iv = make([]byte, account.Cipher.IVSize())
common.Must2(rand.Read(iv))
if ivError := account.CheckIV(iv); ivError != nil {
return nil, errors.New("failed to mark outgoing iv").Base(ivError)
}
if err := buf.WriteAllBytes(writer, iv, nil); err != nil {
return nil, errors.New("failed to write IV.").Base(err)
}
Expand Down
Loading
Loading