Skip to content

Commit

Permalink
added drain for ss and improved vmess drain
Browse files Browse the repository at this point in the history
  • Loading branch information
xiaokangwang committed Aug 26, 2020
1 parent f5642b4 commit a40727a
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 1 deletion.
41 changes: 41 additions & 0 deletions proxy/shadowsocks/protocol.go
Expand Up @@ -4,8 +4,14 @@ package shadowsocks

import (
"bytes"
"crypto/hmac"
"crypto/rand"
"crypto/sha256"
"hash"
"hash/crc32"
"io"
"io/ioutil"
"v2ray.com/core/common/dice"

"v2ray.com/core/common"
"v2ray.com/core/common/bitmask"
Expand All @@ -32,13 +38,28 @@ var addrParser = protocol.NewAddressParser(
func ReadTCPSession(user *protocol.MemoryUser, reader io.Reader) (*protocol.RequestHeader, buf.Reader, error) {
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()
defer buffer.Release()

ivLen := account.Cipher.IVSize()
var iv []byte
if ivLen > 0 {
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)
}

Expand All @@ -47,6 +68,8 @@ func ReadTCPSession(user *protocol.MemoryUser, reader io.Reader) (*protocol.Requ

r, err := account.Cipher.NewDecryptionReader(account.Key, iv, reader)
if err != nil {
readSizeRemain -= int(buffer.Len())
DrainConnN(reader,readSizeRemain)
return nil, nil, newError("failed to initialize decoding stream").Base(err).AtError()
}
br := &buf.BufferedReader{Reader: r}
Expand All @@ -58,10 +81,13 @@ func ReadTCPSession(user *protocol.MemoryUser, reader io.Reader) (*protocol.Requ
Command: protocol.RequestCommandTCP,
}

readSizeRemain -= int(buffer.Len())
buffer.Clear()

addr, port, err := addrParser.ReadAddressPort(buffer, br)
if err != nil {
readSizeRemain -= int(buffer.Len())
DrainConnN(reader,readSizeRemain)
return nil, nil, newError("failed to read address").Base(err)
}

Expand All @@ -74,10 +100,14 @@ func ReadTCPSession(user *protocol.MemoryUser, reader io.Reader) (*protocol.Requ
}

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")
}

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")
}
}
Expand All @@ -88,15 +118,21 @@ func ReadTCPSession(user *protocol.MemoryUser, reader io.Reader) (*protocol.Requ

_, err := buffer.ReadFullFrom(br, AuthSize)
if err != nil {
readSizeRemain -= int(buffer.Len())
DrainConnN(reader,readSizeRemain)
return nil, nil, newError("Failed to read OTA").Base(err)
}

if !bytes.Equal(actualAuth, buffer.BytesFrom(-AuthSize)) {
readSizeRemain -= int(buffer.Len())
DrainConnN(reader,readSizeRemain)
return nil, nil, newError("invalid OTA")
}
}

if request.Address == nil {
readSizeRemain -= int(buffer.Len())
DrainConnN(reader,readSizeRemain)
return nil, nil, newError("invalid remote address.")
}

Expand All @@ -110,6 +146,11 @@ func ReadTCPSession(user *protocol.MemoryUser, reader io.Reader) (*protocol.Requ
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.
func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Writer, error) {
user := request.User
Expand Down
7 changes: 6 additions & 1 deletion proxy/vmess/validator.go
Expand Up @@ -3,6 +3,9 @@
package vmess

import (
"crypto/hmac"
"crypto/sha256"
"hash"
"hash/crc64"
"strings"
"sync"
Expand Down Expand Up @@ -139,7 +142,9 @@ func (v *TimedUserValidator) Add(u *protocol.MemoryUser) error {

account := uu.user.Account.(*MemoryAccount)
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
Expand Down

0 comments on commit a40727a

Please sign in to comment.