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:
parent
f5642b4075
commit
a40727a3dc
@ -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
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user