mirror of
https://github.com/XTLS/Xray-core.git
synced 2025-04-30 09:18:34 +00:00
Refactor log (#3446)
* Refactor log * Add new log methods * Fix logger test * Change all logging code * Clean up pathObj * Rebase to latest main * Remove invoking method name after the dot
This commit is contained in:
parent
8320732743
commit
079d0bd8a9
291 changed files with 1837 additions and 2368 deletions
|
@ -32,12 +32,12 @@ func NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {
|
|||
for _, rec := range config.Server {
|
||||
s, err := protocol.NewServerSpecFromPB(rec)
|
||||
if err != nil {
|
||||
return nil, newError("failed to parse server spec").Base(err)
|
||||
return nil, errors.New("failed to parse server spec").Base(err)
|
||||
}
|
||||
serverList.AddServer(s)
|
||||
}
|
||||
if serverList.Size() == 0 {
|
||||
return nil, newError("0 server")
|
||||
return nil, errors.New("0 server")
|
||||
}
|
||||
|
||||
v := core.MustFromContext(ctx)
|
||||
|
@ -51,9 +51,9 @@ func NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {
|
|||
// Process implements OutboundHandler.Process().
|
||||
func (c *Client) Process(ctx context.Context, link *transport.Link, dialer internet.Dialer) error {
|
||||
outbounds := session.OutboundsFromContext(ctx)
|
||||
ob := outbounds[len(outbounds) - 1]
|
||||
ob := outbounds[len(outbounds)-1]
|
||||
if !ob.Target.IsValid() {
|
||||
return newError("target not specified")
|
||||
return errors.New("target not specified")
|
||||
}
|
||||
ob.Name = "trojan"
|
||||
ob.CanSpliceCopy = 3
|
||||
|
@ -74,16 +74,16 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
|
|||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return newError("failed to find an available destination").AtWarning().Base(err)
|
||||
return errors.New("failed to find an available destination").AtWarning().Base(err)
|
||||
}
|
||||
newError("tunneling request to ", destination, " via ", server.Destination().NetAddr()).WriteToLog(session.ExportIDToError(ctx))
|
||||
errors.LogInfo(ctx, "tunneling request to ", destination, " via ", server.Destination().NetAddr())
|
||||
|
||||
defer conn.Close()
|
||||
|
||||
user := server.PickUser()
|
||||
account, ok := user.Account.(*MemoryAccount)
|
||||
if !ok {
|
||||
return newError("user account is not valid")
|
||||
return errors.New("user account is not valid")
|
||||
}
|
||||
|
||||
var newCtx context.Context
|
||||
|
@ -121,12 +121,12 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
|
|||
|
||||
// write some request payload to buffer
|
||||
if err = buf.CopyOnceTimeout(link.Reader, bodyWriter, time.Millisecond*100); err != nil && err != buf.ErrNotTimeoutReader && err != buf.ErrReadTimeout {
|
||||
return newError("failed to write A request payload").Base(err).AtWarning()
|
||||
return errors.New("failed to write A request payload").Base(err).AtWarning()
|
||||
}
|
||||
|
||||
// Flush; bufferWriter.WriteMultiBufer now is bufferWriter.writer.WriteMultiBuffer
|
||||
if err = bufferWriter.SetBuffered(false); err != nil {
|
||||
return newError("failed to flush payload").Base(err).AtWarning()
|
||||
return errors.New("failed to flush payload").Base(err).AtWarning()
|
||||
}
|
||||
|
||||
// Send header if not sent yet
|
||||
|
@ -135,7 +135,7 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
|
|||
}
|
||||
|
||||
if err = buf.Copy(link.Reader, bodyWriter, buf.UpdateActivity(timer)); err != nil {
|
||||
return newError("failed to transfer request payload").Base(err).AtInfo()
|
||||
return errors.New("failed to transfer request payload").Base(err).AtInfo()
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -161,7 +161,7 @@ func (c *Client) Process(ctx context.Context, link *transport.Link, dialer inter
|
|||
|
||||
responseDoneAndCloseWriter := task.OnSuccess(getResponse, task.Close(link.Writer))
|
||||
if err := task.Run(ctx, postRequest, responseDoneAndCloseWriter); err != nil {
|
||||
return newError("connection ends").Base(err)
|
||||
return errors.New("connection ends").Base(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
package trojan
|
||||
|
||||
import "github.com/xtls/xray-core/common/errors"
|
||||
|
||||
type errPathObjHolder struct{}
|
||||
|
||||
func newError(values ...interface{}) *errors.Error {
|
||||
return errors.New(values...).WithPathObj(errPathObjHolder{})
|
||||
}
|
|
@ -5,6 +5,7 @@ import (
|
|||
"io"
|
||||
|
||||
"github.com/xtls/xray-core/common/buf"
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
"github.com/xtls/xray-core/common/net"
|
||||
"github.com/xtls/xray-core/common/protocol"
|
||||
)
|
||||
|
@ -38,7 +39,7 @@ type ConnWriter struct {
|
|||
func (c *ConnWriter) Write(p []byte) (n int, err error) {
|
||||
if !c.headerSent {
|
||||
if err := c.writeHeader(); err != nil {
|
||||
return 0, newError("failed to write request header").Base(err)
|
||||
return 0, errors.New("failed to write request header").Base(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,15 +161,15 @@ func (c *ConnReader) ParseHeader() error {
|
|||
var command [1]byte
|
||||
var hash [56]byte
|
||||
if _, err := io.ReadFull(c.Reader, hash[:]); err != nil {
|
||||
return newError("failed to read user hash").Base(err)
|
||||
return errors.New("failed to read user hash").Base(err)
|
||||
}
|
||||
|
||||
if _, err := io.ReadFull(c.Reader, crlf[:]); err != nil {
|
||||
return newError("failed to read crlf").Base(err)
|
||||
return errors.New("failed to read crlf").Base(err)
|
||||
}
|
||||
|
||||
if _, err := io.ReadFull(c.Reader, command[:]); err != nil {
|
||||
return newError("failed to read command").Base(err)
|
||||
return errors.New("failed to read command").Base(err)
|
||||
}
|
||||
|
||||
network := net.Network_TCP
|
||||
|
@ -178,12 +179,12 @@ func (c *ConnReader) ParseHeader() error {
|
|||
|
||||
addr, port, err := addrParser.ReadAddressPort(nil, c.Reader)
|
||||
if err != nil {
|
||||
return newError("failed to read address and port").Base(err)
|
||||
return errors.New("failed to read address and port").Base(err)
|
||||
}
|
||||
c.Target = net.Destination{Network: network, Address: addr, Port: port}
|
||||
|
||||
if _, err := io.ReadFull(c.Reader, crlf[:]); err != nil {
|
||||
return newError("failed to read crlf").Base(err)
|
||||
return errors.New("failed to read crlf").Base(err)
|
||||
}
|
||||
|
||||
c.headerParsed = true
|
||||
|
@ -217,22 +218,22 @@ type PacketReader struct {
|
|||
func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
||||
addr, port, err := addrParser.ReadAddressPort(nil, r)
|
||||
if err != nil {
|
||||
return nil, newError("failed to read address and port").Base(err)
|
||||
return nil, errors.New("failed to read address and port").Base(err)
|
||||
}
|
||||
|
||||
var lengthBuf [2]byte
|
||||
if _, err := io.ReadFull(r, lengthBuf[:]); err != nil {
|
||||
return nil, newError("failed to read payload length").Base(err)
|
||||
return nil, errors.New("failed to read payload length").Base(err)
|
||||
}
|
||||
|
||||
remain := int(binary.BigEndian.Uint16(lengthBuf[:]))
|
||||
if remain > maxLength {
|
||||
return nil, newError("oversize payload")
|
||||
return nil, errors.New("oversize payload")
|
||||
}
|
||||
|
||||
var crlf [2]byte
|
||||
if _, err := io.ReadFull(r, crlf[:]); err != nil {
|
||||
return nil, newError("failed to read crlf").Base(err)
|
||||
return nil, errors.New("failed to read crlf").Base(err)
|
||||
}
|
||||
|
||||
dest := net.UDPDestination(addr, port)
|
||||
|
@ -249,7 +250,7 @@ func (r *PacketReader) ReadMultiBuffer() (buf.MultiBuffer, error) {
|
|||
n, err := b.ReadFullFrom(r, int32(length))
|
||||
if err != nil {
|
||||
buf.ReleaseMulti(mb)
|
||||
return nil, newError("failed to read payload").Base(err)
|
||||
return nil, errors.New("failed to read payload").Base(err)
|
||||
}
|
||||
|
||||
remain -= int(n)
|
||||
|
|
|
@ -47,11 +47,11 @@ func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
|
|||
for _, user := range config.Users {
|
||||
u, err := user.ToMemoryUser()
|
||||
if err != nil {
|
||||
return nil, newError("failed to get trojan user").Base(err).AtError()
|
||||
return nil, errors.New("failed to get trojan user").Base(err).AtError()
|
||||
}
|
||||
|
||||
if err := validator.Add(u); err != nil {
|
||||
return nil, newError("failed to add user").Base(err).AtError()
|
||||
return nil, errors.New("failed to add user").Base(err).AtError()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,8 +132,6 @@ func (s *Server) Network() []net.Network {
|
|||
|
||||
// Process implements proxy.Inbound.Process().
|
||||
func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Connection, dispatcher routing.Dispatcher) error {
|
||||
sid := session.ExportIDToError(ctx)
|
||||
|
||||
iConn := conn
|
||||
statConn, ok := iConn.(*stat.CounterConnection)
|
||||
if ok {
|
||||
|
@ -142,16 +140,16 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Con
|
|||
|
||||
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()
|
||||
return errors.New("unable to set read deadline").Base(err).AtWarning()
|
||||
}
|
||||
|
||||
first := buf.FromBytes(make([]byte, buf.Size))
|
||||
first.Clear()
|
||||
firstLen, err := first.ReadFrom(conn)
|
||||
if err != nil {
|
||||
return newError("failed to read first request").Base(err)
|
||||
return errors.New("failed to read first request").Base(err)
|
||||
}
|
||||
newError("firstLen = ", firstLen).AtInfo().WriteToLog(sid)
|
||||
errors.LogInfo(ctx, "firstLen = ", firstLen)
|
||||
|
||||
bufferedReader := &buf.BufferedReader{
|
||||
Reader: buf.NewReader(conn),
|
||||
|
@ -166,7 +164,7 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Con
|
|||
shouldFallback := false
|
||||
if firstLen < 58 || first.Byte(56) != '\r' {
|
||||
// invalid protocol
|
||||
err = newError("not trojan protocol")
|
||||
err = errors.New("not trojan protocol")
|
||||
log.Record(&log.AccessMessage{
|
||||
From: conn.RemoteAddr(),
|
||||
To: "",
|
||||
|
@ -179,7 +177,7 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Con
|
|||
user = s.validator.Get(hexString(first.BytesTo(56)))
|
||||
if user == nil {
|
||||
// invalid user, let's fallback
|
||||
err = newError("not a valid user")
|
||||
err = errors.New("not a valid user")
|
||||
log.Record(&log.AccessMessage{
|
||||
From: conn.RemoteAddr(),
|
||||
To: "",
|
||||
|
@ -192,9 +190,9 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Con
|
|||
}
|
||||
|
||||
if isfb && shouldFallback {
|
||||
return s.fallback(ctx, sid, err, sessionPolicy, conn, iConn, napfb, first, firstLen, bufferedReader)
|
||||
return s.fallback(ctx, err, sessionPolicy, conn, iConn, napfb, first, firstLen, bufferedReader)
|
||||
} else if shouldFallback {
|
||||
return newError("invalid protocol or invalid user")
|
||||
return errors.New("invalid protocol or invalid user")
|
||||
}
|
||||
|
||||
clientReader := &ConnReader{Reader: bufferedReader}
|
||||
|
@ -205,12 +203,12 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Con
|
|||
Status: log.AccessRejected,
|
||||
Reason: err,
|
||||
})
|
||||
return newError("failed to create request from: ", conn.RemoteAddr()).Base(err)
|
||||
return errors.New("failed to create request from: ", conn.RemoteAddr()).Base(err)
|
||||
}
|
||||
|
||||
destination := clientReader.Target
|
||||
if err := conn.SetReadDeadline(time.Time{}); err != nil {
|
||||
return newError("unable to set read deadline").Base(err).AtWarning()
|
||||
return errors.New("unable to set read deadline").Base(err).AtWarning()
|
||||
}
|
||||
|
||||
inbound := session.InboundFromContext(ctx)
|
||||
|
@ -231,7 +229,7 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn stat.Con
|
|||
Email: user.Email,
|
||||
})
|
||||
|
||||
newError("received request for ", destination).WriteToLog(sid)
|
||||
errors.LogInfo(ctx, "received request for ", destination)
|
||||
return s.handleConnection(ctx, sessionPolicy, destination, clientReader, buf.NewWriter(conn), dispatcher)
|
||||
}
|
||||
|
||||
|
@ -243,7 +241,7 @@ func (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReade
|
|||
}
|
||||
|
||||
if err := clientWriter.WriteMultiBuffer(buf.MultiBuffer{udpPayload}); err != nil {
|
||||
newError("failed to write response").Base(err).AtWarning().WriteToLog(session.ExportIDToError(ctx))
|
||||
errors.LogWarningInner(ctx, err, "failed to write response")
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -260,7 +258,7 @@ func (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReade
|
|||
mb, err := clientReader.ReadMultiBuffer()
|
||||
if err != nil {
|
||||
if errors.Cause(err) != io.EOF {
|
||||
return newError("unexpected EOF").Base(err)
|
||||
return errors.New("unexpected EOF").Base(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -281,7 +279,7 @@ func (s *Server) handleUDPPayload(ctx context.Context, clientReader *PacketReade
|
|||
Email: user.Email,
|
||||
})
|
||||
}
|
||||
newError("tunnelling request to ", destination).WriteToLog(session.ExportIDToError(ctx))
|
||||
errors.LogInfo(ctx, "tunnelling request to ", destination)
|
||||
|
||||
if !s.cone || dest == nil {
|
||||
dest = &destination
|
||||
|
@ -306,13 +304,13 @@ func (s *Server) handleConnection(ctx context.Context, sessionPolicy policy.Sess
|
|||
|
||||
link, err := dispatcher.Dispatch(ctx, destination)
|
||||
if err != nil {
|
||||
return newError("failed to dispatch request to ", destination).Base(err)
|
||||
return errors.New("failed to dispatch request to ", destination).Base(err)
|
||||
}
|
||||
|
||||
requestDone := func() error {
|
||||
defer timer.SetTimeout(sessionPolicy.Timeouts.DownlinkOnly)
|
||||
if buf.Copy(clientReader, link.Writer, buf.UpdateActivity(timer)) != nil {
|
||||
return newError("failed to transfer request").Base(err)
|
||||
return errors.New("failed to transfer request").Base(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -321,7 +319,7 @@ func (s *Server) handleConnection(ctx context.Context, sessionPolicy policy.Sess
|
|||
defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)
|
||||
|
||||
if err := buf.Copy(link.Reader, clientWriter, buf.UpdateActivity(timer)); err != nil {
|
||||
return newError("failed to write response").Base(err)
|
||||
return errors.New("failed to write response").Base(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -330,17 +328,17 @@ func (s *Server) handleConnection(ctx context.Context, sessionPolicy policy.Sess
|
|||
if err := task.Run(ctx, requestDonePost, responseDone); err != nil {
|
||||
common.Must(common.Interrupt(link.Reader))
|
||||
common.Must(common.Interrupt(link.Writer))
|
||||
return newError("connection ends").Base(err)
|
||||
return errors.New("connection ends").Base(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) fallback(ctx context.Context, sid errors.ExportOption, err error, sessionPolicy policy.Session, connection stat.Connection, iConn stat.Connection, napfb map[string]map[string]map[string]*Fallback, first *buf.Buffer, firstLen int64, reader buf.Reader) error {
|
||||
func (s *Server) fallback(ctx context.Context, err error, sessionPolicy policy.Session, connection stat.Connection, iConn stat.Connection, napfb map[string]map[string]map[string]*Fallback, first *buf.Buffer, firstLen int64, reader buf.Reader) error {
|
||||
if err := connection.SetReadDeadline(time.Time{}); err != nil {
|
||||
newError("unable to set back read deadline").Base(err).AtWarning().WriteToLog(sid)
|
||||
errors.LogWarningInner(ctx, err, "unable to set back read deadline")
|
||||
}
|
||||
newError("fallback starts").Base(err).AtInfo().WriteToLog(sid)
|
||||
errors.LogInfoInner(ctx, err, "fallback starts")
|
||||
|
||||
name := ""
|
||||
alpn := ""
|
||||
|
@ -348,14 +346,14 @@ func (s *Server) fallback(ctx context.Context, sid errors.ExportOption, err erro
|
|||
cs := tlsConn.ConnectionState()
|
||||
name = cs.ServerName
|
||||
alpn = cs.NegotiatedProtocol
|
||||
newError("realName = " + name).AtInfo().WriteToLog(sid)
|
||||
newError("realAlpn = " + alpn).AtInfo().WriteToLog(sid)
|
||||
errors.LogInfo(ctx, "realName = " + name)
|
||||
errors.LogInfo(ctx, "realAlpn = " + alpn)
|
||||
} else if realityConn, ok := iConn.(*reality.Conn); ok {
|
||||
cs := realityConn.ConnectionState()
|
||||
name = cs.ServerName
|
||||
alpn = cs.NegotiatedProtocol
|
||||
newError("realName = " + name).AtInfo().WriteToLog(sid)
|
||||
newError("realAlpn = " + alpn).AtInfo().WriteToLog(sid)
|
||||
errors.LogInfo(ctx, "realName = " + name)
|
||||
errors.LogInfo(ctx, "realAlpn = " + alpn)
|
||||
}
|
||||
name = strings.ToLower(name)
|
||||
alpn = strings.ToLower(alpn)
|
||||
|
@ -377,7 +375,7 @@ func (s *Server) fallback(ctx context.Context, sid errors.ExportOption, err erro
|
|||
}
|
||||
apfb := napfb[name]
|
||||
if apfb == nil {
|
||||
return newError(`failed to find the default "name" config`).AtWarning()
|
||||
return errors.New(`failed to find the default "name" config`).AtWarning()
|
||||
}
|
||||
|
||||
if apfb[alpn] == nil {
|
||||
|
@ -385,7 +383,7 @@ func (s *Server) fallback(ctx context.Context, sid errors.ExportOption, err erro
|
|||
}
|
||||
pfb := apfb[alpn]
|
||||
if pfb == nil {
|
||||
return newError(`failed to find the default "alpn" config`).AtWarning()
|
||||
return errors.New(`failed to find the default "alpn" config`).AtWarning()
|
||||
}
|
||||
|
||||
path := ""
|
||||
|
@ -405,7 +403,7 @@ func (s *Server) fallback(ctx context.Context, sid errors.ExportOption, err erro
|
|||
}
|
||||
if k == '?' || k == ' ' {
|
||||
path = string(firstBytes[i:j])
|
||||
newError("realPath = " + path).AtInfo().WriteToLog(sid)
|
||||
errors.LogInfo(ctx, "realPath = " + path)
|
||||
if pfb[path] == nil {
|
||||
path = ""
|
||||
}
|
||||
|
@ -419,7 +417,7 @@ func (s *Server) fallback(ctx context.Context, sid errors.ExportOption, err erro
|
|||
}
|
||||
fb := pfb[path]
|
||||
if fb == nil {
|
||||
return newError(`failed to find the default "path" config`).AtWarning()
|
||||
return errors.New(`failed to find the default "path" config`).AtWarning()
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
|
@ -435,7 +433,7 @@ func (s *Server) fallback(ctx context.Context, sid errors.ExportOption, err erro
|
|||
}
|
||||
return nil
|
||||
}); err != nil {
|
||||
return newError("failed to dial to " + fb.Dest).Base(err).AtWarning()
|
||||
return errors.New("failed to dial to " + fb.Dest).Base(err).AtWarning()
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
|
@ -495,11 +493,11 @@ func (s *Server) fallback(ctx context.Context, sid errors.ExportOption, err erro
|
|||
common.Must2(pro.Write([]byte{byte(p1 >> 8), byte(p1), byte(p2 >> 8), byte(p2)}))
|
||||
}
|
||||
if err := serverWriter.WriteMultiBuffer(buf.MultiBuffer{pro}); err != nil {
|
||||
return newError("failed to set PROXY protocol v", fb.Xver).Base(err).AtWarning()
|
||||
return errors.New("failed to set PROXY protocol v", fb.Xver).Base(err).AtWarning()
|
||||
}
|
||||
}
|
||||
if err := buf.Copy(reader, serverWriter, buf.UpdateActivity(timer)); err != nil {
|
||||
return newError("failed to fallback request payload").Base(err).AtInfo()
|
||||
return errors.New("failed to fallback request payload").Base(err).AtInfo()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -509,7 +507,7 @@ func (s *Server) fallback(ctx context.Context, sid errors.ExportOption, err erro
|
|||
getResponse := func() error {
|
||||
defer timer.SetTimeout(sessionPolicy.Timeouts.UplinkOnly)
|
||||
if err := buf.Copy(serverReader, writer, buf.UpdateActivity(timer)); err != nil {
|
||||
return newError("failed to deliver response payload").Base(err).AtInfo()
|
||||
return errors.New("failed to deliver response payload").Base(err).AtInfo()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -517,7 +515,7 @@ func (s *Server) fallback(ctx context.Context, sid errors.ExportOption, err erro
|
|||
if err := task.Run(ctx, task.OnSuccess(postRequest, task.Close(serverWriter)), task.OnSuccess(getResponse, task.Close(writer))); err != nil {
|
||||
common.Must(common.Interrupt(serverReader))
|
||||
common.Must(common.Interrupt(serverWriter))
|
||||
return newError("fallback ends").Base(err).AtInfo()
|
||||
return errors.New("fallback ends").Base(err).AtInfo()
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/xtls/xray-core/common/errors"
|
||||
"github.com/xtls/xray-core/common/protocol"
|
||||
)
|
||||
|
||||
|
@ -19,7 +20,7 @@ func (v *Validator) Add(u *protocol.MemoryUser) error {
|
|||
if u.Email != "" {
|
||||
_, loaded := v.email.LoadOrStore(strings.ToLower(u.Email), u)
|
||||
if loaded {
|
||||
return newError("User ", u.Email, " already exists.")
|
||||
return errors.New("User ", u.Email, " already exists.")
|
||||
}
|
||||
}
|
||||
v.users.Store(hexString(u.Account.(*MemoryAccount).Key), u)
|
||||
|
@ -29,12 +30,12 @@ func (v *Validator) Add(u *protocol.MemoryUser) error {
|
|||
// Del a trojan user with a non-empty Email.
|
||||
func (v *Validator) Del(e string) error {
|
||||
if e == "" {
|
||||
return newError("Email must not be empty.")
|
||||
return errors.New("Email must not be empty.")
|
||||
}
|
||||
le := strings.ToLower(e)
|
||||
u, _ := v.email.Load(le)
|
||||
if u == nil {
|
||||
return newError("User ", e, " not found.")
|
||||
return errors.New("User ", e, " not found.")
|
||||
}
|
||||
v.email.Delete(le)
|
||||
v.users.Delete(hexString(u.(*protocol.MemoryUser).Account.(*MemoryAccount).Key))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue