diff --git a/go.mod b/go.mod index d6bf151..adeac40 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/sagernet/sing-shadowsocks go 1.18 require ( - github.com/sagernet/sing v0.2.11 + github.com/sagernet/sing v0.2.12 golang.org/x/crypto v0.13.0 lukechampine.com/blake3 v1.2.1 ) diff --git a/go.sum b/go.sum index 0e0abdf..a9399f2 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ github.com/klauspost/cpuid/v2 v2.0.12 h1:p9dKCg8i4gmOxtv35DvrYoWqYzQrvEVdjQ762Y0OqZE= github.com/klauspost/cpuid/v2 v2.0.12/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c= -github.com/sagernet/sing v0.2.11 h1:mu0S6d8y/xSVxilOqRd32Fmire5SZz9nT3t9NEHwUMY= -github.com/sagernet/sing v0.2.11/go.mod h1:GQ673iPfUnkbK/dIPkfd1Xh1MjOGo36gkl/mkiHY7Jg= +github.com/sagernet/sing v0.2.12 h1:wwdLm3c4qvU4hW8tNtadh60V5z2FGlDZSYYGRzHhD74= +github.com/sagernet/sing v0.2.12/go.mod h1:GQ673iPfUnkbK/dIPkfd1Xh1MjOGo36gkl/mkiHY7Jg= golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= diff --git a/shadowaead_2022/service.go b/shadowaead_2022/service.go index d751c9c..4dfdf97 100644 --- a/shadowaead_2022/service.go +++ b/shadowaead_2022/service.go @@ -31,8 +31,9 @@ import ( ) var ( - ErrNoPadding = E.New("bad request: missing payload or padding") - ErrBadPadding = E.New("bad request: damaged padding") + ErrInvalidRequest = E.New("invalid request") + ErrNoPadding = E.New("bad request: missing payload or padding") + ErrBadPadding = E.New("bad request: damaged padding") ) var _ shadowsocks.Service = (*Service)(nil) diff --git a/shadowaead_2022/service_multi.go b/shadowaead_2022/service_multi.go index 49351e3..bb635ce 100644 --- a/shadowaead_2022/service_multi.go +++ b/shadowaead_2022/service_multi.go @@ -7,6 +7,7 @@ import ( "crypto/rand" "encoding/base64" "encoding/binary" + "io" "math" "net" "os" @@ -115,16 +116,24 @@ func (s *MultiService[U]) UpdateUsersWithPasswords(userList []U, passwordList [] } func (s *MultiService[U]) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error { - err := s.newConnection(ctx, conn, metadata) + err := s.NewConnection0(ctx, conn, metadata, conn, nil) if err != nil { err = &shadowsocks.ServerConnError{Conn: conn, Source: metadata.Source, Cause: err} } return err } -func (s *MultiService[U]) newConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error { +func (s *MultiService[U]) NewConnection0(ctx context.Context, conn net.Conn, metadata M.Metadata, handshakeReader io.Reader, handshakeSuccess func()) error { requestHeader := make([]byte, s.keySaltLength+aes.BlockSize+shadowaead.Overhead+RequestHeaderFixedChunkLength) - n, err := conn.Read(requestHeader) + var ( + n int + err error + ) + if handshakeSuccess != nil { + n, err = io.ReadFull(handshakeReader, requestHeader) + } else { + n, err = handshakeReader.Read(requestHeader) + } if err != nil { return err } else if n < len(requestHeader) { @@ -158,7 +167,11 @@ func (s *MultiService[U]) newConnection(ctx context.Context, conn net.Conn, meta user = u uPSK = s.uPSK[u] } else { - return E.New("invalid request") + return ErrInvalidRequest + } + + if handshakeSuccess != nil { + handshakeSuccess() } requestKey := SessionKey(uPSK, requestSalt, s.keySaltLength)