mirror of
https://github.com/v2fly/v2ray-core.git
synced 2026-06-10 13:09:11 -04:00
refactor shadowsocks
This commit is contained in:
@@ -3,8 +3,12 @@ package shadowsocks
|
||||
import (
|
||||
"crypto/hmac"
|
||||
"crypto/sha1"
|
||||
"io"
|
||||
|
||||
"github.com/v2ray/v2ray-core/common/alloc"
|
||||
"github.com/v2ray/v2ray-core/common/log"
|
||||
"github.com/v2ray/v2ray-core/common/serial"
|
||||
"github.com/v2ray/v2ray-core/transport"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -23,10 +27,6 @@ func NewAuthenticator(keygen KeyGenerator) *Authenticator {
|
||||
}
|
||||
}
|
||||
|
||||
func (this *Authenticator) AuthSize() int {
|
||||
return AuthSize
|
||||
}
|
||||
|
||||
func (this *Authenticator) Authenticate(auth []byte, data []byte) []byte {
|
||||
hasher := hmac.New(sha1.New, this.key())
|
||||
hasher.Write(data)
|
||||
@@ -53,3 +53,44 @@ func ChunkKeyGenerator(iv []byte) func() []byte {
|
||||
return newKey
|
||||
}
|
||||
}
|
||||
|
||||
type ChunkReader struct {
|
||||
reader io.Reader
|
||||
auth *Authenticator
|
||||
}
|
||||
|
||||
func NewChunkReader(reader io.Reader, auth *Authenticator) *ChunkReader {
|
||||
return &ChunkReader{
|
||||
reader: reader,
|
||||
auth: auth,
|
||||
}
|
||||
}
|
||||
|
||||
func (this *ChunkReader) Read() (*alloc.Buffer, error) {
|
||||
buffer := alloc.NewLargeBuffer()
|
||||
if _, err := io.ReadFull(this.reader, buffer.Value[:2]); err != nil {
|
||||
alloc.Release(buffer)
|
||||
return nil, err
|
||||
}
|
||||
// There is a potential buffer overflow here. Large buffer is 64K bytes,
|
||||
// while uin16 + 10 will be more than that
|
||||
length := serial.BytesLiteral(buffer.Value[:2]).Uint16Value() + AuthSize
|
||||
if _, err := io.ReadFull(this.reader, buffer.Value[:length]); err != nil {
|
||||
alloc.Release(buffer)
|
||||
return nil, err
|
||||
}
|
||||
buffer.Slice(0, int(length))
|
||||
|
||||
authBytes := buffer.Value[:AuthSize]
|
||||
payload := buffer.Value[AuthSize:]
|
||||
|
||||
actualAuthBytes := this.auth.Authenticate(nil, payload)
|
||||
if !serial.BytesLiteral(authBytes).Equals(serial.BytesLiteral(actualAuthBytes)) {
|
||||
alloc.Release(buffer)
|
||||
log.Debug("AuthenticationReader: Unexpected auth: ", authBytes)
|
||||
return nil, transport.CorruptedPacket
|
||||
}
|
||||
buffer.Value = payload
|
||||
|
||||
return buffer, nil
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ func ReadRequest(reader io.Reader, auth *Authenticator) (*Request, error) {
|
||||
lenBuffer += 2
|
||||
|
||||
if request.OTA {
|
||||
authBytes := buffer.Value[lenBuffer : lenBuffer+auth.AuthSize()]
|
||||
authBytes := buffer.Value[lenBuffer : lenBuffer+AuthSize]
|
||||
_, err = io.ReadFull(reader, authBytes)
|
||||
if err != nil {
|
||||
log.Error("Shadowsocks: Failed to read OTA: ", err)
|
||||
|
||||
@@ -155,7 +155,7 @@ func (this *Shadowsocks) handleConnection(conn *hub.TCPConn) {
|
||||
return
|
||||
}
|
||||
|
||||
request, err := ReadRequest(reader, NewAuthenticator(HeaderKeyGenerator(key, iv)))
|
||||
request, err := ReadRequest(reader, NewAuthenticator(HeaderKeyGenerator(iv, key)))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -188,7 +188,7 @@ func (this *Shadowsocks) handleConnection(conn *hub.TCPConn) {
|
||||
var payloadReader v2io.Reader
|
||||
if request.OTA {
|
||||
payloadAuth := NewAuthenticator(ChunkKeyGenerator(iv))
|
||||
payloadReader = v2io.NewAuthenticationReader(v2io.NewChunkReader(reader), payloadAuth, true)
|
||||
payloadReader = NewChunkReader(reader, payloadAuth)
|
||||
} else {
|
||||
payloadReader = v2io.NewAdaptiveReader(reader)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user