1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-09-18 01:46:06 -04:00

refactor error interface

This commit is contained in:
Darien Raymond 2017-04-06 15:13:09 +02:00
parent 65c6972eb5
commit fc31f9b94c
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
40 changed files with 272 additions and 249 deletions

View File

@ -58,13 +58,13 @@ func (v *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destin
if v.router != nil {
if tag, err := v.router.TakeDetour(ctx); err == nil {
if handler := v.ohm.GetHandler(tag); handler != nil {
log.Info("DefaultDispatcher: Taking detour [", tag, "] for [", destination, "].")
log.Trace(errors.New("taking detour [", tag, "] for [", destination, "]").Path("App", "Dispatcher", "Default"))
dispatcher = handler
} else {
log.Warning("DefaultDispatcher: Nonexisting tag: ", tag)
log.Trace(errors.New("nonexisting tag: ", tag).AtWarning().Path("App", "Dispatcher", "Default"))
}
} else {
log.Info("DefaultDispatcher: Default route for ", destination)
log.Trace(errors.New("default route for ", destination).Path("App", "Dispatcher", "Default"))
}
}

View File

@ -11,6 +11,7 @@ import (
"v2ray.com/core/app/log"
"v2ray.com/core/common/buf"
"v2ray.com/core/common/dice"
"v2ray.com/core/common/errors"
v2net "v2ray.com/core/common/net"
"v2ray.com/core/transport/internet/udp"
)
@ -200,7 +201,7 @@ func (v *LocalNameServer) QueryA(domain string) <-chan *ARecord {
ips, err := net.LookupIP(domain)
if err != nil {
log.Info("DNS: Failed to lookup IPs for domain ", domain)
log.Trace(errors.New("failed to lookup IPs for domain ", domain).Path("App", "DNS").Base(err))
return
}

View File

@ -21,7 +21,7 @@ var (
func InitAccessLogger(file string) error {
logger, err := internal.NewFileLogWriter(file)
if err != nil {
return errors.Base(err).Message("Failed to create access logger on file: ", file)
return errors.New("Failed to create access logger on file: ", file).Base(err).Path("App", "Log")
}
accessLoggerInstance = logger
return nil

View File

@ -43,7 +43,7 @@ func SetLogLevel(level LogLevel) {
func InitErrorLogger(file string) error {
logger, err := internal.NewFileLogWriter(file)
if err != nil {
return errors.Base(err).Message("Log: Failed to create error logger on file (", file, ")")
return errors.New("failed to create error logger on file (", file, ")").Base(err).Path("App", "Log")
}
streamLoggerInstance = logger
return nil
@ -81,6 +81,22 @@ func Error(val ...interface{}) {
})
}
func Trace(err error) {
s := errors.GetSeverity(err)
switch s {
case errors.SeverityDebug:
Debug(err)
case errors.SeverityInfo:
Info(err)
case errors.SeverityWarning:
Warning(err)
case errors.SeverityError:
Error(err)
default:
Info(err)
}
}
type Instance struct {
config *Config
}

View File

@ -54,12 +54,7 @@ func (w *tcpWorker) callback(conn internet.Connection) {
ctx = proxy.ContextWithInboundEntryPoint(ctx, v2net.TCPDestination(w.address, w.port))
ctx = proxy.ContextWithSource(ctx, v2net.DestinationFromAddr(conn.RemoteAddr()))
if err := w.proxy.Process(ctx, v2net.Network_TCP, conn, w.dispatcher); err != nil {
err := errors.Base(err).Message("Proxyman|TCPWorker: Connection ends.")
if errors.IsActionRequired(err) {
log.Warning(err)
} else {
log.Info(err)
}
log.Trace(errors.New("connection ends").Base(err).Path("Proxyman", "TCPWorker"))
}
cancel()
conn.Close()
@ -243,12 +238,7 @@ func (w *udpWorker) callback(b *buf.Buffer, source v2net.Destination, originalDe
ctx = proxy.ContextWithSource(ctx, source)
ctx = proxy.ContextWithInboundEntryPoint(ctx, v2net.UDPDestination(w.address, w.port))
if err := w.proxy.Process(ctx, v2net.Network_UDP, conn, w.dispatcher); err != nil {
err = errors.Base(err).Message("Proxyman|UDPWorker: Connection ends.")
if errors.IsActionRequired(err) {
log.Warning(err)
} else {
log.Info(err)
}
log.Trace(errors.New("connection ends").Base(err).Path("Proxymann|UDPWorker"))
}
w.removeConn(source)
cancel()

View File

@ -83,7 +83,7 @@ func (m *ClientManager) Dispatch(ctx context.Context, outboundRay ray.OutboundRa
client, err := NewClient(m.proxy, m.dialer, m)
if err != nil {
return errors.Base(err).Message("Proxyman|Mux|ClientManager: Failed to create client.")
return errors.New("failed to create client").Base(err).Path("Proxymann", "Mux", "ClientManager")
}
m.clients = append(m.clients, client)
client.Dispatch(ctx, outboundRay)

View File

@ -73,23 +73,13 @@ func (h *Handler) Dispatch(ctx context.Context, outboundRay ray.OutboundRay) {
if h.mux != nil {
err := h.mux.Dispatch(ctx, outboundRay)
if err != nil {
err = errors.Base(err).Message("Proxyman|OutboundHandler: Failed to process outbound traffic.")
if errors.IsActionRequired(err) {
log.Warning(err)
} else {
log.Info(err)
}
log.Trace(errors.New("failed to process outbound traffic").Base(err).Path("Proxyman", "OutboundHandler"))
}
} else {
err := h.proxy.Process(ctx, outboundRay, h)
// Ensure outbound ray is properly closed.
if err != nil && errors.Cause(err) != io.EOF {
err = errors.Base(err).Message("Proxyman|OutboundHandler: Failed to process outbound traffic.")
if errors.IsActionRequired(err) {
log.Warning(err)
} else {
log.Info(err)
}
log.Trace(errors.New("failed to process outbound traffic").Base(err).Path("Proxyman", "OutboundHandler"))
outboundRay.OutboundOutput().CloseError()
} else {
outboundRay.OutboundOutput().Close()
@ -105,7 +95,7 @@ func (h *Handler) Dial(ctx context.Context, dest v2net.Destination) (internet.Co
tag := h.senderSettings.ProxySettings.Tag
handler := h.outboundManager.GetHandler(tag)
if handler != nil {
log.Info("Proxyman|OutboundHandler: Proxying to ", tag)
log.Trace(errors.New("proxying to ", tag).AtDebug().Path("App", "Proxyman", "OutboundHandler"))
ctx = proxy.ContextWithTarget(ctx, dest)
stream := ray.NewRay(ctx)
go handler.Dispatch(ctx, stream)

View File

@ -3,78 +3,112 @@ package errors
import (
"fmt"
"strings"
"v2ray.com/core/common/serial"
)
type Severity int
const (
SeverityDebug Severity = iota
SeverityInfo
SeverityWarning
SeverityError
)
type hasInnerError interface {
// Inner returns the underlying error of this one.
Inner() error
}
type actionRequired interface {
ActionRequired() bool
type hasSeverity interface {
Severity() Severity
}
// Error is an error object with underlying error.
type Error struct {
message string
inner error
actionRequired bool
message string
inner error
severity Severity
path []string
}
// Error implements error.Error().
func (v Error) Error() string {
func (v *Error) Error() string {
msg := v.message
if v.inner != nil {
msg += " > " + v.inner.Error()
}
if len(v.path) > 0 {
msg = strings.Join(v.path, "|") + ": " + msg
}
return msg
}
// Inner implements hasInnerError.Inner()
func (v Error) Inner() error {
func (v *Error) Inner() error {
if v.inner == nil {
return nil
}
return v.inner
}
func (v Error) ActionRequired() bool {
return v.actionRequired
}
func (v Error) RequireUserAction() Error {
v.actionRequired = true
func (v *Error) Base(err error) *Error {
v.inner = err
return v
}
func (v Error) Message(msg ...interface{}) Error {
return Error{
inner: v,
message: serial.Concat(msg...),
}
func (v *Error) atSeverity(s Severity) *Error {
v.severity = s
return v
}
func (v Error) Format(format string, values ...interface{}) Error {
return v.Message(fmt.Sprintf(format, values...))
func (v *Error) Severity() Severity {
if v.inner == nil {
return v.severity
}
if s, ok := v.inner.(hasSeverity); ok {
as := s.Severity()
if as > v.severity {
return as
}
}
return v.severity
}
func (v *Error) AtDebug() *Error {
return v.atSeverity(SeverityDebug)
}
func (v *Error) AtInfo() *Error {
return v.atSeverity(SeverityInfo)
}
func (v *Error) AtWarning() *Error {
return v.atSeverity(SeverityWarning)
}
func (v *Error) AtError() *Error {
return v.atSeverity(SeverityError)
}
func (v *Error) Path(path ...string) *Error {
v.path = path
return v
}
// New returns a new error object with message formed from given arguments.
func New(msg ...interface{}) Error {
return Error{
message: serial.Concat(msg...),
func New(msg ...interface{}) *Error {
return &Error{
message: serial.Concat(msg...),
severity: SeverityInfo,
}
}
// Base returns an Error based on the given error.
func Base(err error) Error {
return Error{
inner: err,
}
}
func Format(format string, values ...interface{}) error {
func Format(format string, values ...interface{}) *Error {
return New(fmt.Sprintf(format, values...))
}
@ -93,16 +127,9 @@ func Cause(err error) error {
return err
}
func IsActionRequired(err error) bool {
for err != nil {
if ar, ok := err.(actionRequired); ok && ar.ActionRequired() {
return true
}
inner, ok := err.(hasInnerError)
if !ok || inner.Inner() == nil {
break
}
err = inner.Inner()
func GetSeverity(err error) Severity {
if s, ok := err.(hasSeverity); ok {
return s.Severity()
}
return false
return SeverityInfo
}

View File

@ -12,16 +12,16 @@ func TestActionRequired(t *testing.T) {
assert := assert.On(t)
err := New("TestError")
assert.Bool(IsActionRequired(err)).IsFalse()
assert.Bool(GetSeverity(err) == SeverityInfo).IsTrue()
err = Base(io.EOF).Message("TestError2")
assert.Bool(IsActionRequired(err)).IsFalse()
err = New("TestError2").Base(io.EOF)
assert.Bool(GetSeverity(err) == SeverityInfo).IsTrue()
err = Base(io.EOF).RequireUserAction().Message("TestError3")
assert.Bool(IsActionRequired(err)).IsTrue()
err = New("TestError3").Base(io.EOF).AtWarning()
assert.Bool(GetSeverity(err) == SeverityWarning).IsTrue()
err = Base(io.EOF).RequireUserAction().Message("TestError4")
err = Base(err).Message("TestError5")
assert.Bool(IsActionRequired(err)).IsTrue()
err = New("TestError4").Base(io.EOF).AtWarning()
err = New("TestError5").Base(err)
assert.Bool(GetSeverity(err) == SeverityWarning).IsTrue()
assert.String(err.Error()).Contains("EOF")
}

View File

@ -38,7 +38,7 @@ func (r *retryer) On(method func() error) error {
<-time.After(time.Duration(delay) * time.Millisecond)
attempt++
}
return errors.Base(ErrRetryFailed).Message(accumulatedError)
return errors.New(accumulatedError).Base(ErrRetryFailed)
}
// Timed returns a retry strategy with fixed interval.

View File

@ -45,7 +45,7 @@ func GetConfigFormat() core.ConfigFormat {
func startV2Ray() (core.Server, error) {
if len(configFile) == 0 {
return nil, errors.New("V2Ray: Config file is not set.")
return nil, errors.New("config file is not set").Path("Core")
}
var configInput io.Reader
if configFile == "stdin:" {
@ -54,19 +54,19 @@ func startV2Ray() (core.Server, error) {
fixedFile := os.ExpandEnv(configFile)
file, err := os.Open(fixedFile)
if err != nil {
return nil, errors.Base(err).Message("V2Ray: Config file not readable.")
return nil, errors.New("config file not readable").Path("Core").Base(err)
}
defer file.Close()
configInput = file
}
config, err := core.LoadConfig(GetConfigFormat(), configInput)
if err != nil {
return nil, errors.Base(err).Message("V2Ray: Failed to read config file: ", configFile)
return nil, errors.New("failed to read config file: ", configFile).Base(err).Path("Core")
}
server, err := core.New(config)
if err != nil {
return nil, errors.Base(err).Message("V2Ray: Failed to create initialize.")
return nil, errors.New("failed to create initialize").Base(err).Path("Core")
}
return server, nil
@ -88,12 +88,12 @@ func main() {
}
if *test {
fmt.Println("V2Ray: Configuration OK.")
fmt.Println("Configuration OK.")
return
}
if err := server.Start(); err != nil {
fmt.Println("V2Ray: Failed to start. ", err)
fmt.Println("Failed to start", err)
}
osSignals := make(chan os.Signal, 1)

View File

@ -102,7 +102,7 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
return nil
})
if err != nil {
return errors.Base(err).Message("Freedom: Failed to open connection to ", destination)
return errors.New("failed to open connection to ", destination).Base(err).Path("Freedom")
}
defer conn.Close()
@ -136,7 +136,7 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil {
input.CloseError()
output.CloseError()
return errors.Base(err).Message("Freedom: Connection ends.")
return errors.New("connection ends").Base(err).Path("Freedom")
}
runtime.KeepAlive(timer)

View File

@ -94,7 +94,7 @@ func (s *Server) Process(ctx context.Context, network v2net.Network, conn intern
}
dest, err := parseHost(host, defaultPort)
if err != nil {
return errors.Base(err).Message("HTTP: Malformed proxy host: ", host).RequireUserAction()
return errors.New("malformed proxy host: ", host).AtWarning().Base(err).Path("HTTP")
}
log.Access(conn.RemoteAddr(), request.URL, log.AccessAccepted, "")
@ -118,7 +118,7 @@ func (s *Server) handleConnect(ctx context.Context, request *http.Request, reade
Close: false,
}
if err := response.Write(writer); err != nil {
return errors.Base(err).Message("HTTP|Server: Failed to write back OK response.")
return errors.New("failed to write back OK response").Base(err).Path("HTTP", "Server")
}
timeout := time.Second * time.Duration(s.config.Timeout)
@ -152,7 +152,7 @@ func (s *Server) handleConnect(ctx context.Context, request *http.Request, reade
if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil {
ray.InboundInput().CloseError()
ray.InboundOutput().CloseError()
return errors.Base(err).Message("HTTP|Server: Connection ends.")
return errors.New("connection ends").Base(err).Path("HTTP", "Server")
}
runtime.KeepAlive(timer)
@ -251,7 +251,7 @@ func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, rea
if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil {
input.CloseError()
output.CloseError()
return errors.Base(err).Message("HTTP|Server: Connection ends.")
return errors.New("connection ends").Base(err).Path("HTTP", "Server")
}
return nil

View File

@ -60,7 +60,7 @@ func (v *Client) Process(ctx context.Context, outboundRay ray.OutboundRay, diale
return nil
})
if err != nil {
return errors.Base(err).RequireUserAction().Message("Shadowsocks|Client: Failed to find an available destination.")
return errors.New("failed to find an available destination").AtWarning().Base(err).Path("Shadowsocks", "Client")
}
log.Info("Shadowsocks|Client: Tunneling request to ", destination, " via ", server.Destination())
@ -81,7 +81,7 @@ func (v *Client) Process(ctx context.Context, outboundRay ray.OutboundRay, diale
user := server.PickUser()
rawAccount, err := user.GetTypedAccount()
if err != nil {
return errors.Base(err).Message("Shadowsocks|Client: Failed to get a valid user account.").RequireUserAction()
return errors.New("failed to get a valid user account").AtWarning().Base(err).Path("Shadowsocks", "Client")
}
account := rawAccount.(*ShadowsocksAccount)
request.User = user
@ -96,7 +96,7 @@ func (v *Client) Process(ctx context.Context, outboundRay ray.OutboundRay, diale
bufferedWriter := buf.NewBufferedWriter(conn)
bodyWriter, err := WriteTCPRequest(request, bufferedWriter)
if err != nil {
return errors.Base(err).Message("Shadowsocks|Client: Failed to write request")
return errors.New("failed to write request").Base(err).Path("Shadowsocks", "Client")
}
if err := bufferedWriter.SetBuffered(false); err != nil {
@ -127,7 +127,7 @@ func (v *Client) Process(ctx context.Context, outboundRay ray.OutboundRay, diale
})
if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil {
return errors.Base(err).Message("Shadowsocks|Client: Connection ends.")
return errors.New("connection ends").Base(err).Path("Shadowsocks", "Client")
}
return nil
@ -142,7 +142,7 @@ func (v *Client) Process(ctx context.Context, outboundRay ray.OutboundRay, diale
requestDone := signal.ExecuteAsync(func() error {
if err := buf.PipeUntilEOF(timer, outboundRay.OutboundInput(), writer); err != nil {
return errors.Base(err).Message("Shadowsocks|Client: Failed to transport all UDP request")
return errors.New("failed to transport all UDP request").Base(err).Path("Shadowsocks", "Client")
}
return nil
})
@ -156,13 +156,13 @@ func (v *Client) Process(ctx context.Context, outboundRay ray.OutboundRay, diale
}
if err := buf.PipeUntilEOF(timer, reader, outboundRay.OutboundOutput()); err != nil {
return errors.Base(err).Message("Shadowsocks|Client: Failed to transport all UDP response.")
return errors.New("failed to transport all UDP response").Base(err).Path("Shadowsocks", "Client")
}
return nil
})
if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil {
return errors.Base(err).Message("Shadowsocks|Client: Connection ends.")
return errors.New("connection ends").Base(err).Path("Shadowsocks", "Client")
}
return nil

View File

@ -41,7 +41,7 @@ func (v *Account) GetCipher() (Cipher, error) {
func (v *Account) AsAccount() (protocol.Account, error) {
cipher, err := v.GetCipher()
if err != nil {
return nil, errors.Base(err).Message("Shadowsocks|Account: Failed to get cipher.")
return nil, errors.New("failed to get cipher").Base(err).Path("Shadowsocks", "Account")
}
return &ShadowsocksAccount{
Cipher: cipher,

View File

@ -25,7 +25,7 @@ const (
func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHeader, buf.Reader, error) {
rawAccount, err := user.GetTypedAccount()
if err != nil {
return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to parse account.")
return nil, nil, errors.New("failed to parse account").Path("Shadowsocks", "TCP").Base(err)
}
account := rawAccount.(*ShadowsocksAccount)
@ -35,14 +35,14 @@ func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHea
ivLen := account.Cipher.IVSize()
err = buffer.AppendSupplier(buf.ReadFullFrom(reader, ivLen))
if err != nil {
return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read IV.")
return nil, nil, errors.New("failed to read IV").Path("Shadowsocks", "TCP").Base(err)
}
iv := append([]byte(nil), buffer.BytesTo(ivLen)...)
stream, err := account.Cipher.NewDecodingStream(account.Key, iv)
if err != nil {
return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to initialize decoding stream.")
return nil, nil, errors.New("failed to initialize decoding stream").Path("Shadowsocks", "TCP").Base(err)
}
reader = crypto.NewCryptionReader(stream, reader)
@ -56,7 +56,7 @@ func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHea
buffer.Clear()
err = buffer.AppendSupplier(buf.ReadFullFrom(reader, 1))
if err != nil {
return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read address type.")
return nil, nil, errors.New("failed to read address type").Path("Shadowsocks", "TCP").Base(err)
}
addrType := (buffer.Byte(0) & 0x0F)
@ -65,35 +65,35 @@ func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHea
}
if request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Disabled {
return nil, nil, errors.New("Shadowsocks|TCP: Rejecting connection with OTA enabled, while server disables OTA.")
return nil, nil, errors.New("rejecting connection with OTA enabled, while server disables OTA").Path("Shadowsocks", "TCP")
}
if !request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Enabled {
return nil, nil, errors.New("Shadowsocks|TCP: Rejecting connection with OTA disabled, while server enables OTA.")
return nil, nil, errors.New("rejecting connection with OTA disabled, while server enables OTA").Path("Shadowsocks", "TCP")
}
switch addrType {
case AddrTypeIPv4:
err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 4))
if err != nil {
return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read IPv4 address.")
return nil, nil, errors.New("failed to read IPv4 address").Path("Shadowsocks", "TCP").Base(err)
}
request.Address = v2net.IPAddress(buffer.BytesFrom(-4))
case AddrTypeIPv6:
err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 16))
if err != nil {
return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read IPv6 address.")
return nil, nil, errors.New("failed to read IPv6 address").Path("Shadowsocks", "TCP").Base(err)
}
request.Address = v2net.IPAddress(buffer.BytesFrom(-16))
case AddrTypeDomain:
err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 1))
if err != nil {
return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read domain lenth.")
return nil, nil, errors.New("failed to read domain lenth.").Path("Shadowsocks", "TCP").Base(err)
}
domainLength := int(buffer.BytesFrom(-1)[0])
err = buffer.AppendSupplier(buf.ReadFullFrom(reader, domainLength))
if err != nil {
return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read domain.")
return nil, nil, errors.New("failed to read domain").Path("Shadowsocks", "TCP").Base(err)
}
request.Address = v2net.DomainAddress(string(buffer.BytesFrom(-domainLength)))
default:
@ -102,7 +102,7 @@ func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHea
err = buffer.AppendSupplier(buf.ReadFullFrom(reader, 2))
if err != nil {
return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read port.")
return nil, nil, errors.New("failed to read port").Path("Shadowsocks", "TCP").Base(err)
}
request.Port = v2net.PortFromBytes(buffer.BytesFrom(-2))
@ -112,16 +112,16 @@ func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHea
err := buffer.AppendSupplier(buf.ReadFullFrom(reader, AuthSize))
if err != nil {
return nil, nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read OTA.")
return nil, nil, errors.New("Failed to read OTA").Path("Shadowsocks", "TCP").Base(err)
}
if !bytes.Equal(actualAuth, buffer.BytesFrom(-AuthSize)) {
return nil, nil, errors.New("Shadowsocks|TCP: Invalid OTA")
return nil, nil, errors.New("invalid OTA").Path("Shadowsocks", "TCP")
}
}
if request.Address == nil {
return nil, nil, errors.New("Shadowsocks|TCP: Invalid remote address.")
return nil, nil, errors.New("invalid remote address.").Path("Shadowsocks", "TCP")
}
var chunkReader buf.Reader
@ -138,7 +138,7 @@ func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Wri
user := request.User
rawAccount, err := user.GetTypedAccount()
if err != nil {
return nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to parse account.")
return nil, errors.New("failed to parse account").Path("Shadowsocks", "TCP").Base(err)
}
account := rawAccount.(*ShadowsocksAccount)
@ -146,12 +146,12 @@ func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Wri
rand.Read(iv)
_, err = writer.Write(iv)
if err != nil {
return nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to write IV.")
return nil, errors.New("failed to write IV").Path("Shadowsocks", "TCP")
}
stream, err := account.Cipher.NewEncodingStream(account.Key, iv)
if err != nil {
return nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to create encoding stream.")
return nil, errors.New("failed to create encoding stream").Path("Shadowsocks", "TCP").Base(err)
}
writer = crypto.NewCryptionWriter(stream, writer)
@ -183,7 +183,7 @@ func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Wri
_, err = writer.Write(header.Bytes())
if err != nil {
return nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to write header.")
return nil, errors.New("Shadowsocks|TCP: Failed to write header.").Base(err)
}
var chunkWriter buf.Writer
@ -199,19 +199,19 @@ func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Wri
func ReadTCPResponse(user *protocol.User, reader io.Reader) (buf.Reader, error) {
rawAccount, err := user.GetTypedAccount()
if err != nil {
return nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to parse account.")
return nil, errors.New("Shadowsocks|TCP: Failed to parse account.").Base(err)
}
account := rawAccount.(*ShadowsocksAccount)
iv := make([]byte, account.Cipher.IVSize())
_, err = io.ReadFull(reader, iv)
if err != nil {
return nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to read IV.")
return nil, errors.New("Shadowsocks|TCP: Failed to read IV.").Base(err)
}
stream, err := account.Cipher.NewDecodingStream(account.Key, iv)
if err != nil {
return nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to initialize decoding stream.")
return nil, errors.New("Shadowsocks|TCP: Failed to initialize decoding stream.").Base(err)
}
return buf.NewReader(crypto.NewCryptionReader(stream, reader)), nil
}
@ -220,7 +220,7 @@ func WriteTCPResponse(request *protocol.RequestHeader, writer io.Writer) (buf.Wr
user := request.User
rawAccount, err := user.GetTypedAccount()
if err != nil {
return nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to parse account.")
return nil, errors.New("Shadowsocks|TCP: Failed to parse account.").Base(err)
}
account := rawAccount.(*ShadowsocksAccount)
@ -228,12 +228,12 @@ func WriteTCPResponse(request *protocol.RequestHeader, writer io.Writer) (buf.Wr
rand.Read(iv)
_, err = writer.Write(iv)
if err != nil {
return nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to write IV.")
return nil, errors.New("Shadowsocks|TCP: Failed to write IV.").Base(err)
}
stream, err := account.Cipher.NewEncodingStream(account.Key, iv)
if err != nil {
return nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to create encoding stream.")
return nil, errors.New("Shadowsocks|TCP: Failed to create encoding stream.").Base(err)
}
return buf.NewWriter(crypto.NewCryptionWriter(stream, writer)), nil
@ -243,7 +243,7 @@ func EncodeUDPPacket(request *protocol.RequestHeader, payload *buf.Buffer) (*buf
user := request.User
rawAccount, err := user.GetTypedAccount()
if err != nil {
return nil, errors.Base(err).Message("Shadowsocks|UDP: Failed to parse account.")
return nil, errors.New("Shadowsocks|UDP: Failed to parse account.").Base(err)
}
account := rawAccount.(*ShadowsocksAccount)
@ -278,7 +278,7 @@ func EncodeUDPPacket(request *protocol.RequestHeader, payload *buf.Buffer) (*buf
stream, err := account.Cipher.NewEncodingStream(account.Key, iv)
if err != nil {
return nil, errors.Base(err).Message("Shadowsocks|TCP: Failed to create encoding stream.")
return nil, errors.New("Shadowsocks|TCP: Failed to create encoding stream.").Base(err)
}
stream.XORKeyStream(buffer.BytesFrom(ivLen), buffer.BytesFrom(ivLen))
@ -288,7 +288,7 @@ func EncodeUDPPacket(request *protocol.RequestHeader, payload *buf.Buffer) (*buf
func DecodeUDPPacket(user *protocol.User, payload *buf.Buffer) (*protocol.RequestHeader, *buf.Buffer, error) {
rawAccount, err := user.GetTypedAccount()
if err != nil {
return nil, nil, errors.Base(err).Message("Shadowsocks|UDP: Failed to parse account.")
return nil, nil, errors.New("Shadowsocks|UDP: Failed to parse account.").Base(err)
}
account := rawAccount.(*ShadowsocksAccount)
@ -298,7 +298,7 @@ func DecodeUDPPacket(user *protocol.User, payload *buf.Buffer) (*protocol.Reques
stream, err := account.Cipher.NewDecodingStream(account.Key, iv)
if err != nil {
return nil, nil, errors.Base(err).Message("Shadowsocks|UDP: Failed to initialize decoding stream.")
return nil, nil, errors.New("Shadowsocks|UDP: Failed to initialize decoding stream.").Base(err)
}
stream.XORKeyStream(payload.Bytes(), payload.Bytes())

View File

@ -28,15 +28,15 @@ type Server struct {
func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
space := app.SpaceFromContext(ctx)
if space == nil {
return nil, errors.New("Shadowsocks|Server: No space in context.")
return nil, errors.New("no space in context").Path("Shadowsocks", "Server")
}
if config.GetUser() == nil {
return nil, errors.New("Shadowsocks|Server: User is not specified.")
return nil, errors.New("user is not specified").Path("Shadowsocks", "Server")
}
rawAccount, err := config.User.GetTypedAccount()
if err != nil {
return nil, errors.Base(err).Message("Shadowsocks|Server: Failed to get user account.")
return nil, errors.New("failed to get user account").Base(err).Path("Shadowsocks", "Server")
}
account := rawAccount.(*ShadowsocksAccount)
@ -68,7 +68,7 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet
case net.Network_UDP:
return s.handlerUDPPayload(ctx, conn, dispatcher)
default:
return errors.New("Shadowsocks|Server: Unknown network: ", network)
return errors.New("unknown network: ", network).Path("Shadowsocks", "Server")
}
}
@ -85,7 +85,7 @@ func (v *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
request, data, err := DecodeUDPPacket(v.user, payload)
if err != nil {
if source, ok := proxy.SourceFromContext(ctx); ok {
log.Info("Shadowsocks|Server: Skipping invalid UDP packet from: ", source, ": ", err)
log.Trace(errors.New("dropping invalid UDP packet from: ", source).Base(err).Path("Shadowsocks", "Server"))
log.Access(source, "", log.AccessRejected, err)
}
payload.Release()
@ -93,13 +93,13 @@ func (v *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
}
if request.Option.Has(RequestOptionOneTimeAuth) && v.account.OneTimeAuth == Account_Disabled {
log.Info("Shadowsocks|Server: Client payload enables OTA but server doesn't allow it.")
log.Trace(errors.New("client payload enables OTA but server doesn't allow it").Path("Shadowsocks", "Server"))
payload.Release()
continue
}
if !request.Option.Has(RequestOptionOneTimeAuth) && v.account.OneTimeAuth == Account_Enabled {
log.Info("Shadowsocks|Server: Client payload disables OTA but server forces it.")
log.Trace(errors.New("client payload disables OTA but server forces it").Path("Shadowsocks", "Server"))
payload.Release()
continue
}
@ -108,7 +108,7 @@ func (v *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
if source, ok := proxy.SourceFromContext(ctx); ok {
log.Access(source, dest, log.AccessAccepted, "")
}
log.Info("Shadowsocks|Server: Tunnelling request to ", dest)
log.Trace(errors.New("tunnelling request to ", dest).Path("Shadowsocks", "Server"))
ctx = protocol.ContextWithUser(ctx, request.User)
udpServer.Dispatch(ctx, dest, data, func(payload *buf.Buffer) {
@ -116,7 +116,7 @@ func (v *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
data, err := EncodeUDPPacket(request, payload)
if err != nil {
log.Warning("Shadowsocks|Server: Failed to encode UDP packet: ", err)
log.Trace(errors.New("failed to encode UDP packet").Base(err).Path("Shadowsocks", "Server").AtWarning())
return
}
defer data.Release()
@ -134,7 +134,7 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
request, bodyReader, err := ReadTCPSession(s.user, bufferedReader)
if err != nil {
log.Access(conn.RemoteAddr(), "", log.AccessRejected, err)
return errors.Base(err).Message("Shadowsocks|Server: Failed to create request from: ", conn.RemoteAddr())
return errors.New("failed to create request from: ", conn.RemoteAddr()).Base(err).Path("Shadowsocks", "Server")
}
conn.SetReadDeadline(time.Time{})
@ -142,7 +142,7 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
dest := request.Destination()
log.Access(conn.RemoteAddr(), dest, log.AccessAccepted, "")
log.Info("Shadowsocks|Server: Tunnelling request to ", dest)
log.Trace(errors.New("tunnelling request to ", dest).Path("Shadowsocks", "Server"))
ctx = protocol.ContextWithUser(ctx, request.User)
@ -157,7 +157,7 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
bufferedWriter := buf.NewBufferedWriter(conn)
responseWriter, err := WriteTCPResponse(request, bufferedWriter)
if err != nil {
return errors.Base(err).Message("Shadowsocks|Server: Failed to write response.")
return errors.New("failed to write response").Base(err).Path("Shadowsocks", "Server")
}
payload, err := ray.InboundOutput().Read()
@ -174,7 +174,7 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
}
if err := buf.PipeUntilEOF(timer, ray.InboundOutput(), responseWriter); err != nil {
return errors.Base(err).Message("Shadowsocks|Server: Failed to transport all TCP response.")
return errors.New("failed to transport all TCP response").Base(err).Path("Shadowsocks", "Server")
}
return nil
@ -184,7 +184,7 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
defer ray.InboundInput().Close()
if err := buf.PipeUntilEOF(timer, bodyReader, ray.InboundInput()); err != nil {
return errors.Base(err).Message("Shadowsocks|Server: Failed to transport all TCP request.")
return errors.New("failed to transport all TCP request").Base(err).Path("Shadowsocks", "Server")
}
return nil
})
@ -192,7 +192,7 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil {
ray.InboundInput().CloseError()
ray.InboundOutput().CloseError()
return errors.Base(err).Message("Shadowsocks|Server: Connection ends.")
return errors.New("connection ends").Base(err).Path("Shadowsocks", "Server")
}
runtime.KeepAlive(timer)

View File

@ -55,7 +55,7 @@ func (c *Client) Process(ctx context.Context, ray ray.OutboundRay, dialer proxy.
})
if err != nil {
return errors.Base(err).Message("Socks|Client: Failed to find an available destination.")
return errors.New("failed to find an available destination").Base(err).Path("Socks", "Client")
}
defer conn.Close()
@ -78,7 +78,7 @@ func (c *Client) Process(ctx context.Context, ray ray.OutboundRay, dialer proxy.
udpRequest, err := ClientHandshake(request, conn, conn)
if err != nil {
return errors.Base(err).RequireUserAction().Message("Socks|Client: Failed to establish connection to server.")
return errors.New("failed to establish connection to server").AtWarning().Base(err).Path("Socks", "Client")
}
ctx, timer := signal.CancelAfterInactivity(ctx, time.Minute*2)
@ -96,7 +96,7 @@ func (c *Client) Process(ctx context.Context, ray ray.OutboundRay, dialer proxy.
} else if request.Command == protocol.RequestCommandUDP {
udpConn, err := dialer.Dial(ctx, udpRequest.Destination())
if err != nil {
return errors.Base(err).Message("Socks|Client: Failed to create UDP connection.")
return errors.New("failed to create UDP connection").Base(err).Path("Socks", "Client")
}
defer udpConn.Close()
requestFunc = func() error {
@ -112,7 +112,7 @@ func (c *Client) Process(ctx context.Context, ray ray.OutboundRay, dialer proxy.
requestDone := signal.ExecuteAsync(requestFunc)
responseDone := signal.ExecuteAsync(responseFunc)
if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil {
return errors.Base(err).Message("Socks|Client: Connection ends.")
return errors.New("connection ends").Base(err).Path("Socks", "Client")
}
runtime.KeepAlive(timer)

View File

@ -44,13 +44,13 @@ func (s *ServerSession) Handshake(reader io.Reader, writer io.Writer) (*protocol
request := new(protocol.RequestHeader)
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil {
return nil, errors.Base(err).Message("Socks|Server: Insufficient header.")
return nil, errors.New("insufficient header").Base(err).Path("Socks", "Server")
}
version := buffer.Byte(0)
if version == socks4Version {
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 6)); err != nil {
return nil, errors.Base(err).Message("Socks|Server: Insufficient header.")
return nil, errors.New("insufficient header").Base(err).Path("Socks", "Server")
}
port := v2net.PortFromBytes(buffer.BytesRange(2, 4))
address := v2net.IPAddress(buffer.BytesRange(4, 8))
@ -61,7 +61,7 @@ func (s *ServerSession) Handshake(reader io.Reader, writer io.Writer) (*protocol
if address.IP()[0] == 0x00 {
domain, err := readUntilNull(reader)
if err != nil {
return nil, errors.Base(err).Message("Socks|Server: Failed to read domain for socks 4a.")
return nil, errors.New("failed to read domain for socks 4a").Base(err).Path("Socks", "Server")
}
address = v2net.DomainAddress(domain)
}
@ -85,7 +85,7 @@ func (s *ServerSession) Handshake(reader io.Reader, writer io.Writer) (*protocol
if version == socks5Version {
nMethod := int(buffer.Byte(1))
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, nMethod)); err != nil {
return nil, errors.Base(err).Message("Socks|Server: Failed to read auth methods.")
return nil, errors.New("failed to read auth methods").Base(err).Path("Socks", "Server")
}
var expectedAuth byte = authNotRequired
@ -95,37 +95,37 @@ func (s *ServerSession) Handshake(reader io.Reader, writer io.Writer) (*protocol
if !hasAuthMethod(expectedAuth, buffer.BytesRange(2, 2+nMethod)) {
writeSocks5AuthenticationResponse(writer, socks5Version, authNoMatchingMethod)
return nil, errors.New("Socks|Server: No matching auth method.")
return nil, errors.New("no matching auth method").Path("Socks", "Server")
}
if err := writeSocks5AuthenticationResponse(writer, socks5Version, expectedAuth); err != nil {
return nil, errors.Base(err).Message("Socks|Server: Failed to write auth response.")
return nil, errors.New("failed to write auth response").Base(err).Path("Socks", "Server")
}
if expectedAuth == authPassword {
username, password, err := readUsernamePassword(reader)
if err != nil {
return nil, errors.Base(err).Message("Socks|Server: Failed to read username and password for authentication.")
return nil, errors.New("failed to read username and password for authentication").Base(err).Path("Socks", "Server")
}
if !s.config.HasAccount(username, password) {
writeSocks5AuthenticationResponse(writer, 0x01, 0xFF)
return nil, errors.New("Socks|Server: Invalid username or password.")
return nil, errors.New("invalid username or password").Path("Socks", "Server")
}
if err := writeSocks5AuthenticationResponse(writer, 0x01, 0x00); err != nil {
return nil, errors.Base(err).Message("Socks|Server: Failed to write auth response.")
return nil, errors.New("failed to write auth response").Base(err).Path("Socks", "Server")
}
}
buffer.Clear()
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 4)); err != nil {
return nil, errors.Base(err).Message("Socks|Server: Failed to read request.")
return nil, errors.New("failed to read request").Base(err).Path("Socks", "Server")
}
cmd := buffer.Byte(1)
if cmd == cmdTCPBind || (cmd == cmdUDPPort && !s.config.UdpEnabled) {
writeSocks5Response(writer, statusCmdNotSupport, v2net.AnyIP, v2net.Port(0))
return nil, errors.New("Socks|Server: Unsupported command: ", cmd)
return nil, errors.New("unsupported command: ", cmd).Path("Socks", "Server")
}
switch cmd {
@ -161,7 +161,7 @@ func (s *ServerSession) Handshake(reader io.Reader, writer io.Writer) (*protocol
}
request.Address = v2net.ParseAddress(string(buffer.BytesFrom(-domainLength)))
default:
return nil, errors.New("Socks|Server: Unknown address type: ", addrType)
return nil, errors.New("Unknown address type: ", addrType).Path("Socks", "Server")
}
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil {
@ -186,7 +186,7 @@ func (s *ServerSession) Handshake(reader io.Reader, writer io.Writer) (*protocol
return request, nil
}
return nil, errors.New("Socks|Server: Unknown Socks version: ", version)
return nil, errors.New("unknown Socks version: ", version).Path("Socks", "Server")
}
func readUsernamePassword(reader io.Reader) (string, string, error) {
@ -230,7 +230,7 @@ func readUntilNull(reader io.Reader) (string, error) {
}
size++
if size == 256 {
return "", errors.New("Socks|Server: Buffer overrun.")
return "", errors.New("buffer overrun").Path("Socks", "Server")
}
}
}
@ -400,10 +400,10 @@ func ClientHandshake(request *protocol.RequestHeader, reader io.Reader, writer i
}
if b.Byte(0) != socks5Version {
return nil, errors.New("Socks|Client: Unexpected server version: ", b.Byte(0)).RequireUserAction()
return nil, errors.New("Socks|Client: Unexpected server version: ", b.Byte(0)).AtWarning()
}
if b.Byte(1) != authByte {
return nil, errors.New("Socks|Client: auth method not supported.").RequireUserAction()
return nil, errors.New("Socks|Client: auth method not supported.").AtWarning()
}
if authByte == authPassword {

View File

@ -29,7 +29,7 @@ type Server struct {
func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
space := app.SpaceFromContext(ctx)
if space == nil {
return nil, errors.New("Socks|Server: No space in context.").RequireUserAction()
return nil, errors.New("Socks|Server: No space in context.").AtWarning()
}
s := &Server{
config: config,
@ -129,7 +129,7 @@ func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writ
v2reader := buf.NewReader(reader)
if err := buf.PipeUntilEOF(timer, v2reader, input); err != nil {
return errors.Base(err).Message("Socks|Server: Failed to transport all TCP request.")
return errors.New("failed to transport all TCP request").Base(err).Path("Socks", "Server")
}
return nil
})
@ -137,7 +137,7 @@ func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writ
responseDone := signal.ExecuteAsync(func() error {
v2writer := buf.NewWriter(writer)
if err := buf.PipeUntilEOF(timer, output, v2writer); err != nil {
return errors.Base(err).Message("Socks|Server: Failed to transport all TCP response.")
return errors.New("failed to transport all TCP response").Base(err).Path("Socks", "Server")
}
return nil
})
@ -145,7 +145,7 @@ func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writ
if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil {
input.CloseError()
output.CloseError()
return errors.Base(err).Message("Socks|Server: Connection ends.")
return errors.New("connection ends").Base(err).Path("Socks", "Server")
}
runtime.KeepAlive(timer)
@ -157,7 +157,7 @@ func (v *Server) handleUDPPayload(ctx context.Context, conn internet.Connection,
udpServer := udp.NewDispatcher(dispatcher)
if source, ok := proxy.SourceFromContext(ctx); ok {
log.Info("Socks|Server: Client UDP connection from ", source)
log.Trace(errors.New("client UDP connection from ", source).Path("Socks", "Server"))
}
reader := buf.NewReader(conn)

View File

@ -123,7 +123,7 @@ func (v *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Request
_, err := io.ReadFull(reader, buffer[:protocol.IDBytesLen])
if err != nil {
return nil, errors.Base(err).Message("VMess|Server: Failed to read request header.")
return nil, errors.New("failed to read request header").Base(err).Path("VMess", "Server")
}
user, timestamp, valid := v.userValidator.Get(buffer[:protocol.IDBytesLen])
@ -136,7 +136,7 @@ func (v *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Request
iv := timestampHash.Sum(nil)
account, err := user.GetTypedAccount()
if err != nil {
return nil, errors.Base(err).Message("VMess|Server: Failed to get user account.")
return nil, errors.New("failed to get user account").Base(err).Path("VMess", "Server")
}
vmessAccount := account.(*vmess.InternalAccount)
@ -145,7 +145,7 @@ func (v *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Request
nBytes, err := io.ReadFull(decryptor, buffer[:41])
if err != nil {
return nil, errors.Base(err).Message("VMess|Server: Failed to read request header.")
return nil, errors.New("failed to read request header").Base(err).Path("VMess", "Server")
}
bufferLen := nBytes
@ -155,7 +155,7 @@ func (v *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Request
}
if request.Version != Version {
return nil, errors.New("VMess|Server: Invalid protocol version ", request.Version)
return nil, errors.New("invalid protocol version ", request.Version).Path("VMess", "Server")