1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-12-22 01:57:12 -05:00

added drain for ss and improved vmess drain

This commit is contained in:
Shelikhoo 2020-08-26 13:51:23 +08:00
parent f5642b4075
commit a40727a3dc
No known key found for this signature in database
GPG Key ID: C4D5E79D22B25316
2 changed files with 47 additions and 1 deletions

View File

@ -4,8 +4,14 @@ package shadowsocks
import ( import (
"bytes" "bytes"
"crypto/hmac"
"crypto/rand" "crypto/rand"
"crypto/sha256"
"hash"
"hash/crc32"
"io" "io"
"io/ioutil"
"v2ray.com/core/common/dice"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/bitmask" "v2ray.com/core/common/bitmask"
@ -32,6 +38,19 @@ var addrParser = protocol.NewAddressParser(
func ReadTCPSession(user *protocol.MemoryUser, reader io.Reader) (*protocol.RequestHeader, buf.Reader, error) { func ReadTCPSession(user *protocol.MemoryUser, reader io.Reader) (*protocol.RequestHeader, buf.Reader, error) {
account := user.Account.(*MemoryAccount) account := user.Account.(*MemoryAccount)
hashkdf := hmac.New(func()hash.Hash{return sha256.New()}, []byte("SSBSKDF"))
hashkdf.Write(account.Key)
behaviorSeed := crc32.ChecksumIEEE(hashkdf.Sum(nil))
behaviorRand := dice.NewDeterministicDice(int64(behaviorSeed))
BaseDrainSize := behaviorRand.Roll(3266)
RandDrainMax := behaviorRand.Roll(64) + 1
RandDrainRolled := dice.Roll(RandDrainMax)
DrainSize := BaseDrainSize + 16 + 38 + RandDrainRolled
readSizeRemain := DrainSize
buffer := buf.New() buffer := buf.New()
defer buffer.Release() defer buffer.Release()
@ -39,6 +58,8 @@ func ReadTCPSession(user *protocol.MemoryUser, reader io.Reader) (*protocol.Requ
var iv []byte var iv []byte
if ivLen > 0 { if ivLen > 0 {
if _, err := buffer.ReadFullFrom(reader, ivLen); err != nil { if _, err := buffer.ReadFullFrom(reader, ivLen); err != nil {
readSizeRemain -= int(buffer.Len())
DrainConnN(reader,readSizeRemain)
return nil, nil, newError("failed to read IV").Base(err) return nil, nil, newError("failed to read IV").Base(err)
} }
@ -47,6 +68,8 @@ func ReadTCPSession(user *protocol.MemoryUser, reader io.Reader) (*protocol.Requ
r, err := account.Cipher.NewDecryptionReader(account.Key, iv, reader) r, err := account.Cipher.NewDecryptionReader(account.Key, iv, reader)
if err != nil { if err != nil {
readSizeRemain -= int(buffer.Len())
DrainConnN(reader,readSizeRemain)
return nil, nil, newError("failed to initialize decoding stream").Base(err).AtError() return nil, nil, newError("failed to initialize decoding stream").Base(err).AtError()
} }
br := &buf.BufferedReader{Reader: r} br := &buf.BufferedReader{Reader: r}
@ -58,10 +81,13 @@ func ReadTCPSession(user *protocol.MemoryUser, reader io.Reader) (*protocol.Requ
Command: protocol.RequestCommandTCP, Command: protocol.RequestCommandTCP,
} }
readSizeRemain -= int(buffer.Len())
buffer.Clear() buffer.Clear()
addr, port, err := addrParser.ReadAddressPort(buffer, br) addr, port, err := addrParser.ReadAddressPort(buffer, br)
if err != nil { if err != nil {
readSizeRemain -= int(buffer.Len())
DrainConnN(reader,readSizeRemain)
return nil, nil, newError("failed to read address").Base(err) return nil, nil, newError("failed to read address").Base(err)
} }
@ -74,10 +100,14 @@ func ReadTCPSession(user *protocol.MemoryUser, reader io.Reader) (*protocol.Requ
} }
if request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Disabled { if request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Disabled {
readSizeRemain -= int(buffer.Len())
DrainConnN(reader,readSizeRemain)
return nil, nil, newError("rejecting connection with OTA enabled, while server disables OTA") return nil, nil, newError("rejecting connection with OTA enabled, while server disables OTA")
} }
if !request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Enabled { if !request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Enabled {
readSizeRemain -= int(buffer.Len())
DrainConnN(reader,readSizeRemain)
return nil, nil, newError("rejecting connection with OTA disabled, while server enables OTA") return nil, nil, newError("rejecting connection with OTA disabled, while server enables OTA")
} }
} }
@ -88,15 +118,21 @@ func ReadTCPSession(user *protocol.MemoryUser, reader io.Reader) (*protocol.Requ
_, err := buffer.ReadFullFrom(br, AuthSize) _, err := buffer.ReadFullFrom(br, AuthSize)
if err != nil { if err != nil {
readSizeRemain -= int(buffer.Len())
DrainConnN(reader,readSizeRemain)
return nil, nil, newError("Failed to read OTA").Base(err) return nil, nil, newError("Failed to read OTA").Base(err)
} }
if !bytes.Equal(actualAuth, buffer.BytesFrom(-AuthSize)) { if !bytes.Equal(actualAuth, buffer.BytesFrom(-AuthSize)) {
readSizeRemain -= int(buffer.Len())
DrainConnN(reader,readSizeRemain)
return nil, nil, newError("invalid OTA") return nil, nil, newError("invalid OTA")
} }
} }
if request.Address == nil { if request.Address == nil {
readSizeRemain -= int(buffer.Len())
DrainConnN(reader,readSizeRemain)
return nil, nil, newError("invalid remote address.") return nil, nil, newError("invalid remote address.")
} }
@ -110,6 +146,11 @@ func ReadTCPSession(user *protocol.MemoryUser, reader io.Reader) (*protocol.Requ
return request, chunkReader, nil return request, chunkReader, nil
} }
func DrainConnN(reader io.Reader, n int) error {
_, err := io.CopyN(ioutil.Discard, reader, int64(n))
return err
}
// WriteTCPRequest writes Shadowsocks request into the given writer, and returns a writer for body. // WriteTCPRequest writes Shadowsocks request into the given writer, and returns a writer for body.
func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Writer, error) { func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Writer, error) {
user := request.User user := request.User

View File

@ -3,6 +3,9 @@
package vmess package vmess
import ( import (
"crypto/hmac"
"crypto/sha256"
"hash"
"hash/crc64" "hash/crc64"
"strings" "strings"
"sync" "sync"
@ -139,7 +142,9 @@ func (v *TimedUserValidator) Add(u *protocol.MemoryUser) error {
account := uu.user.Account.(*MemoryAccount) account := uu.user.Account.(*MemoryAccount)
if v.behaviorFused == false { if v.behaviorFused == false {
v.behaviorSeed = crc64.Update(v.behaviorSeed, crc64.MakeTable(crc64.ECMA), account.ID.Bytes()) hashkdf := hmac.New(func()hash.Hash{return sha256.New()}, []byte("VMESSBSKDF"))
hashkdf.Write(account.ID.Bytes())
v.behaviorSeed = crc64.Update(v.behaviorSeed, crc64.MakeTable(crc64.ECMA), hashkdf.Sum(nil))
} }
var cmdkeyfl [16]byte var cmdkeyfl [16]byte