mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-04-29 16:58:34 +00:00
Refactor: Shadowsocks AEAD Single-port Multi-user (Needs Optimizations)
https://t.me/projectXray/170851
This commit is contained in:
parent
99863aa2ac
commit
33755d6e90
7 changed files with 259 additions and 129 deletions
|
@ -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)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue