Skip to content

Commit 27fad5d

Browse files
committed
Add shadowsocks reducedIvHeadEntropy option v2fly#1552
1 parent e1168f4 commit 27fad5d

File tree

9 files changed

+182
-122
lines changed

9 files changed

+182
-122
lines changed

infra/conf/v4/shadowsocks.go

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,15 @@ func (v *ShadowsocksServerConfig) Build() (proto.Message, error) {
5555
}
5656

5757
type ShadowsocksServerTarget struct {
58-
Address *cfgcommon.Address `json:"address"`
59-
Port uint16 `json:"port"`
60-
Cipher string `json:"method"`
61-
Password string `json:"password"`
62-
Email string `json:"email"`
63-
Ota bool `json:"ota"`
64-
Level byte `json:"level"`
65-
IVCheck bool `json:"ivCheck"`
58+
Address *cfgcommon.Address `json:"address"`
59+
Port uint16 `json:"port"`
60+
Cipher string `json:"method"`
61+
Password string `json:"password"`
62+
Email string `json:"email"`
63+
Ota bool `json:"ota"`
64+
Level byte `json:"level"`
65+
IVCheck bool `json:"ivCheck"`
66+
ExperimentReducedIvHeadEntropy bool `json:"experimentReducedIvHeadEntropy"`
6667
}
6768

6869
type ShadowsocksClientConfig struct {
@@ -91,7 +92,8 @@ func (v *ShadowsocksClientConfig) Build() (proto.Message, error) {
9192
return nil, newError("Shadowsocks password is not specified.")
9293
}
9394
account := &shadowsocks.Account{
94-
Password: server.Password,
95+
Password: server.Password,
96+
ExperimentReducedIvHeadEntropy: server.ExperimentReducedIvHeadEntropy,
9597
}
9698
account.CipherType = shadowsocks.CipherFromString(server.Cipher)
9799
if account.CipherType == shadowsocks.CipherType_UNKNOWN {

proxy/shadowsocks/client.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,9 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
176176
if account.Cipher.IVSize() > 0 {
177177
iv = make([]byte, account.Cipher.IVSize())
178178
common.Must2(rand.Read(iv))
179+
if account.ReducedIVEntropy && len(iv) > 6 {
180+
remapToPrintable(iv[:6])
181+
}
179182
if ivError := account.CheckIV(iv); ivError != nil {
180183
return newError("failed to mark outgoing iv").Base(ivError)
181184
}

proxy/shadowsocks/config.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ type MemoryAccount struct {
3636
Key []byte
3737

3838
replayFilter antireplay.GeneralizedReplayFilter
39+
40+
ReducedIVEntropy bool
3941
}
4042

4143
// Equals implements protocol.Account.Equals().
@@ -367,6 +369,7 @@ func (a *Account) AsAccount() (protocol.Account, error) {
367369
}
368370
return nil
369371
}(),
372+
ReducedIVEntropy: a.ExperimentReducedIvHeadEntropy,
370373
}, nil
371374
}
372375

proxy/shadowsocks/config.pb.go

Lines changed: 116 additions & 90 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

proxy/shadowsocks/config.proto

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ message Account {
1616
CipherType cipher_type = 2;
1717

1818
bool iv_check = 3;
19+
bool experiment_reduced_iv_head_entropy = 90001;
1920
}
2021

2122
enum CipherType {
@@ -80,4 +81,5 @@ message ClientConfig {
8081
string plugin = 2;
8182
string plugin_opts = 3;
8283
repeated string plugin_args = 4;
84+
bool experiment_reduced_iv_head_entropy = 90001;
8385
}

proxy/shadowsocks/protocol.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"crypto/sha256"
77
"hash/crc32"
88
"io"
9+
mrand "math/rand"
910
gonet "net"
1011

1112
"github.com/v2fly/v2ray-core/v5/common"
@@ -365,3 +366,11 @@ func (w *UDPWriter) WriteTo(payload []byte, addr gonet.Addr) (n int, err error)
365366
packet.Release()
366367
return len(payload), err
367368
}
369+
370+
func remapToPrintable(input []byte) {
371+
const charSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!#$%&()*+,./:;<=>?@[]^_`{|}~\\\""
372+
seed := mrand.New(mrand.NewSource(int64(crc32.ChecksumIEEE(input))))
373+
for i := range input {
374+
input[i] = charSet[seed.Intn(len(charSet))]
375+
}
376+
}

proxy/shadowsocks/simplified/config.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,9 @@ func init() {
4040
User: []*protocol.User{
4141
{
4242
Account: serial.ToTypedMessage(&shadowsocks.Account{
43-
Password: simplifiedClient.Password,
44-
CipherType: shadowsocks.CipherFromString(simplifiedClient.Method),
43+
Password: simplifiedClient.Password,
44+
CipherType: shadowsocks.CipherFromString(simplifiedClient.Method),
45+
ExperimentReducedIvHeadEntropy: simplifiedClient.ExperimentReducedIvHeadEntropy,
4546
}),
4647
},
4748
},

proxy/shadowsocks/simplified/config.pb.go

Lines changed: 34 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

proxy/shadowsocks/simplified/config.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,5 @@ message ClientConfig {
3434
string plugin = 5;
3535
string plugin_opts = 6;
3636
repeated string plugin_args = 7;
37+
bool experiment_reduced_iv_head_entropy = 90001;
3738
}

0 commit comments

Comments
 (0)