Refactor: Shadowsocks AEAD Single-port Multi-user (Needs Optimizations)

https://t.me/projectXray/170851
This commit is contained in:
RPRX 2021-01-18 22:52:35 +00:00 committed by GitHub
parent 99863aa2ac
commit 33755d6e90
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 259 additions and 129 deletions

View file

@ -22,30 +22,32 @@ import (
type Server struct {
config *ServerConfig
user *protocol.MemoryUser
users []*protocol.MemoryUser
policyManager policy.Manager
cone bool
}
// NewServer create a new Shadowsocks server.
func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
if config.GetUser() == nil {
return nil, newError("user is not specified")
}
mUser, err := config.User.ToMemoryUser()
if err != nil {
return nil, newError("failed to parse user account").Base(err)
if config.Users == nil {
return nil, newError("empty users")
}
v := core.MustFromContext(ctx)
s := &Server{
config: config,
user: mUser,
policyManager: v.GetFeature(policy.ManagerType()).(policy.Manager),
cone: ctx.Value("cone").(bool),
}
for _, user := range config.Users {
u, err := user.ToMemoryUser()
if err != nil {
return nil, newError("failed to parse user account").Base(err)
}
s.users = append(s.users, u)
}
return s, nil
}
@ -54,9 +56,6 @@ func (s *Server) Network() []net.Network {
if len(list) == 0 {
list = append(list, net.Network_TCP)
}
if s.config.UdpEnabled {
list = append(list, net.Network_UDP)
}
return list
}
@ -103,7 +102,9 @@ func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
if inbound == nil {
panic("no inbound metadata")
}
inbound.User = s.user
if len(s.users) == 1 {
inbound.User = s.users[0]
}
var dest *net.Destination
@ -115,9 +116,21 @@ func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
}
for _, payload := range mpayload {
request, data, err := DecodeUDPPacket(s.user, payload)
var request *protocol.RequestHeader
var data *buf.Buffer
var err error
if inbound.User != nil {
request, data, err = DecodeUDPPacket([]*protocol.MemoryUser{inbound.User}, payload)
} else {
request, data, err = DecodeUDPPacket(s.users, payload)
if err == nil {
inbound.User = request.User
}
}
if err != nil {
if inbound := session.InboundFromContext(ctx); inbound != nil && inbound.Source.IsValid() {
if inbound.Source.IsValid() {
newError("dropping invalid UDP packet from: ", inbound.Source).Base(err).WriteToLog(session.ExportIDToError(ctx))
log.Record(&log.AccessMessage{
From: inbound.Source,
@ -159,11 +172,13 @@ func (s *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
}
func (s *Server) handleConnection(ctx context.Context, conn internet.Connection, dispatcher routing.Dispatcher) error {
sessionPolicy := s.policyManager.ForLevel(s.user.Level)
conn.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake))
sessionPolicy := s.policyManager.ForLevel(0)
if err := conn.SetReadDeadline(time.Now().Add(sessionPolicy.Timeouts.Handshake)); err != nil {
return newError("unable to set read deadline").Base(err).AtWarning()
}
bufferedReader := buf.BufferedReader{Reader: buf.NewReader(conn)}
request, bodyReader, err := ReadTCPSession(s.user, &bufferedReader)
request, bodyReader, err := ReadTCPSession(s.users, &bufferedReader)
if err != nil {
log.Record(&log.AccessMessage{
From: conn.RemoteAddr(),
@ -179,7 +194,7 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
if inbound == nil {
panic("no inbound metadata")
}
inbound.User = s.user
inbound.User = request.User
dest := request.Destination()
ctx = log.ContextWithAccessMessage(ctx, &log.AccessMessage{
@ -191,6 +206,7 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
})
newError("tunnelling request to ", dest).WriteToLog(session.ExportIDToError(ctx))
sessionPolicy = s.policyManager.ForLevel(request.User.Level)
ctx, cancel := context.WithCancel(ctx)
timer := signal.CancelAfterInactivity(ctx, cancel, sessionPolicy.Timeouts.ConnectionIdle)