refactor error messages

This commit is contained in:
Darien Raymond 2017-04-09 01:43:25 +02:00
parent 8175a751db
commit 35248497d2
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
141 changed files with 710 additions and 481 deletions

3
app/app.go Normal file
View File

@ -0,0 +1,3 @@
package app
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg app -path App

View File

@ -1,5 +1,7 @@
package impl package impl
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg impl -path App,Dispatcher,Default
import ( import (
"context" "context"
@ -9,7 +11,6 @@ import (
"v2ray.com/core/app/proxyman" "v2ray.com/core/app/proxyman"
"v2ray.com/core/app/router" "v2ray.com/core/app/router"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
"v2ray.com/core/proxy" "v2ray.com/core/proxy"
"v2ray.com/core/transport/ray" "v2ray.com/core/transport/ray"
@ -23,13 +24,13 @@ type DefaultDispatcher struct {
func NewDefaultDispatcher(ctx context.Context, config *dispatcher.Config) (*DefaultDispatcher, error) { func NewDefaultDispatcher(ctx context.Context, config *dispatcher.Config) (*DefaultDispatcher, error) {
space := app.SpaceFromContext(ctx) space := app.SpaceFromContext(ctx)
if space == nil { if space == nil {
return nil, errors.New("no space in context").Path("App", "Dispatcher", "Default") return nil, newError("no space in context")
} }
d := &DefaultDispatcher{} d := &DefaultDispatcher{}
space.OnInitialize(func() error { space.OnInitialize(func() error {
d.ohm = proxyman.OutboundHandlerManagerFromSpace(space) d.ohm = proxyman.OutboundHandlerManagerFromSpace(space)
if d.ohm == nil { if d.ohm == nil {
return errors.New("OutboundHandlerManager is not found in the space").Path("App", "Dispatcher", "Default") return newError("OutboundHandlerManager is not found in the space")
} }
d.router = router.FromSpace(space) d.router = router.FromSpace(space)
return nil return nil
@ -58,13 +59,13 @@ func (v *DefaultDispatcher) Dispatch(ctx context.Context, destination net.Destin
if v.router != nil { if v.router != nil {
if tag, err := v.router.TakeDetour(ctx); err == nil { if tag, err := v.router.TakeDetour(ctx); err == nil {
if handler := v.ohm.GetHandler(tag); handler != nil { if handler := v.ohm.GetHandler(tag); handler != nil {
log.Trace(errors.New("taking detour [", tag, "] for [", destination, "]").Path("App", "Dispatcher", "Default")) log.Trace(newError("taking detour [", tag, "] for [", destination, "]"))
dispatcher = handler dispatcher = handler
} else { } else {
log.Trace(errors.New("nonexisting tag: ", tag).AtWarning().Path("App", "Dispatcher", "Default")) log.Trace(newError("nonexisting tag: ", tag).AtWarning())
} }
} else { } else {
log.Trace(errors.New("default route for ", destination).Path("App", "Dispatcher", "Default")) log.Trace(newError("default route for ", destination))
} }
} }

View File

@ -0,0 +1,7 @@
package impl
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).Path("App", "Dispatcher", "Default")
}

View File

@ -4,7 +4,6 @@ import (
"net" "net"
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/common/errors"
) )
func (v *Config) GetInternalHosts() map[string]net.IP { func (v *Config) GetInternalHosts() map[string]net.IP {
@ -12,7 +11,7 @@ func (v *Config) GetInternalHosts() map[string]net.IP {
for domain, ipOrDomain := range v.GetHosts() { for domain, ipOrDomain := range v.GetHosts() {
address := ipOrDomain.AsAddress() address := ipOrDomain.AsAddress()
if address.Family().IsDomain() { if address.Family().IsDomain() {
log.Trace(errors.New("ignoring domain address in static hosts: ", address.Domain()).AtWarning().Path("App", "DNS", "Config")) log.Trace(newError("ignoring domain address in static hosts: ", address.Domain()).AtWarning())
continue continue
} }
hosts[domain] = address.IP() hosts[domain] = address.IP()

View File

@ -1,5 +1,7 @@
package dns package dns
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg dns -path App,DNS
import ( import (
"net" "net"

View File

@ -0,0 +1,5 @@
package dns
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("App", "DNS") }

View File

@ -0,0 +1,7 @@
package server
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).Path("App", "DNS", "Server")
}

View File

@ -11,7 +11,6 @@ import (
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/dice" "v2ray.com/core/common/dice"
"v2ray.com/core/common/errors"
v2net "v2ray.com/core/common/net" v2net "v2ray.com/core/common/net"
"v2ray.com/core/transport/internet/udp" "v2ray.com/core/transport/internet/udp"
) )
@ -89,7 +88,7 @@ func (v *UDPNameServer) AssignUnusedID(response chan<- *ARecord) uint16 {
if _, found := v.requests[id]; found { if _, found := v.requests[id]; found {
continue continue
} }
log.Trace(errors.New("add pending request id ", id).AtDebug().Path("App", "DNS", "UDPNameServer")) log.Trace(newError("add pending request id ", id).AtDebug())
v.requests[id] = &PendingRequest{ v.requests[id] = &PendingRequest{
expire: time.Now().Add(time.Second * 8), expire: time.Now().Add(time.Second * 8),
response: response, response: response,
@ -105,7 +104,7 @@ func (v *UDPNameServer) HandleResponse(payload *buf.Buffer) {
msg := new(dns.Msg) msg := new(dns.Msg)
err := msg.Unpack(payload.Bytes()) err := msg.Unpack(payload.Bytes())
if err != nil { if err != nil {
log.Trace(errors.New("failed to parse DNS response").Base(err).AtWarning().Path("App", "DNS", "UDPNameServer")) log.Trace(newError("failed to parse DNS response").Base(err).AtWarning())
return return
} }
record := &ARecord{ record := &ARecord{
@ -113,7 +112,7 @@ func (v *UDPNameServer) HandleResponse(payload *buf.Buffer) {
} }
id := msg.Id id := msg.Id
ttl := DefaultTTL ttl := DefaultTTL
log.Trace(errors.New("handling response for id ", id, " content: ", msg.String()).AtDebug().Path("App", "DNS", "UDPNameServer")) log.Trace(newError("handling response for id ", id, " content: ", msg.String()).AtDebug())
v.Lock() v.Lock()
request, found := v.requests[id] request, found := v.requests[id]
@ -201,7 +200,7 @@ func (v *LocalNameServer) QueryA(domain string) <-chan *ARecord {
ips, err := net.LookupIP(domain) ips, err := net.LookupIP(domain)
if err != nil { if err != nil {
log.Trace(errors.New("failed to lookup IPs for domain ", domain).Path("App", "DNS", "LocalNameServer").Base(err)) log.Trace(newError("failed to lookup IPs for domain ", domain).Base(err))
return return
} }

View File

@ -1,5 +1,7 @@
package server package server
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg server -path App,DNS,Server
import ( import (
"context" "context"
"net" "net"
@ -12,7 +14,6 @@ import (
"v2ray.com/core/app/dns" "v2ray.com/core/app/dns"
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/errors"
v2net "v2ray.com/core/common/net" v2net "v2ray.com/core/common/net"
) )
@ -35,7 +36,7 @@ type CacheServer struct {
func NewCacheServer(ctx context.Context, config *dns.Config) (*CacheServer, error) { func NewCacheServer(ctx context.Context, config *dns.Config) (*CacheServer, error) {
space := app.SpaceFromContext(ctx) space := app.SpaceFromContext(ctx)
if space == nil { if space == nil {
return nil, errors.New("no space in context").Path("App", "DNS", "CacheServer") return nil, newError("no space in context")
} }
server := &CacheServer{ server := &CacheServer{
records: make(map[string]*DomainRecord), records: make(map[string]*DomainRecord),
@ -45,7 +46,7 @@ func NewCacheServer(ctx context.Context, config *dns.Config) (*CacheServer, erro
space.OnInitialize(func() error { space.OnInitialize(func() error {
disp := dispatcher.FromSpace(space) disp := dispatcher.FromSpace(space)
if disp == nil { if disp == nil {
return errors.New("dispatcher is not found in the space").Path("App", "DNS", "CacheServer") return newError("dispatcher is not found in the space")
} }
for idx, destPB := range config.NameServers { for idx, destPB := range config.NameServers {
address := destPB.Address.AsAddress() address := destPB.Address.AsAddress()
@ -113,13 +114,13 @@ func (v *CacheServer) Get(domain string) []net.IP {
A: a, A: a,
} }
v.Unlock() v.Unlock()
log.Trace(errors.New("returning ", len(a.IPs), " IPs for domain ", domain).AtDebug().Path("App", "DNS", "CacheServer")) log.Trace(newError("returning ", len(a.IPs), " IPs for domain ", domain).AtDebug())
return a.IPs return a.IPs
case <-time.After(QueryTimeout): case <-time.After(QueryTimeout):
} }
} }
log.Trace(errors.New("returning nil for domain ", domain).AtDebug().Path("App", "DNS", "CacheServer")) log.Trace(newError("returning nil for domain ", domain).AtDebug())
return nil return nil
} }

5
app/errors.generated.go Normal file
View File

@ -0,0 +1,5 @@
package app
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("App") }

View File

@ -1,9 +1,6 @@
package log package log
import ( import "v2ray.com/core/app/log/internal"
"v2ray.com/core/app/log/internal"
"v2ray.com/core/common/errors"
)
// AccessStatus is the status of an access request from clients. // AccessStatus is the status of an access request from clients.
type AccessStatus string type AccessStatus string
@ -21,7 +18,7 @@ var (
func InitAccessLogger(file string) error { func InitAccessLogger(file string) error {
logger, err := internal.NewFileLogWriter(file) logger, err := internal.NewFileLogWriter(file)
if err != nil { if err != nil {
return errors.New("failed to create access logger on file: ", file).Base(err).Path("App", "Log") return newError("failed to create access logger on file: ", file).Base(err)
} }
accessLoggerInstance = logger accessLoggerInstance = logger
return nil return nil

View File

@ -0,0 +1,5 @@
package log
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("App", "Log") }

View File

@ -1,5 +1,7 @@
package log package log
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg log -path App,Log
import ( import (
"context" "context"
@ -43,7 +45,7 @@ func SetLogLevel(level LogLevel) {
func InitErrorLogger(file string) error { func InitErrorLogger(file string) error {
logger, err := internal.NewFileLogWriter(file) logger, err := internal.NewFileLogWriter(file)
if err != nil { if err != nil {
return errors.New("failed to create error logger on file (", file, ")").Base(err).Path("App", "Log") return newError("failed to create error logger on file (", file, ")").Base(err)
} }
streamLoggerInstance = logger streamLoggerInstance = logger
return nil return nil

View File

@ -3,7 +3,6 @@ package proxyman
import ( import (
"context" "context"
"v2ray.com/core/common/errors"
"v2ray.com/core/proxy" "v2ray.com/core/proxy"
) )
@ -23,7 +22,7 @@ func (s *AllocationStrategy) GetRefreshValue() uint32 {
func (c *OutboundHandlerConfig) GetProxyHandler(ctx context.Context) (proxy.Outbound, error) { func (c *OutboundHandlerConfig) GetProxyHandler(ctx context.Context) (proxy.Outbound, error) {
if c == nil { if c == nil {
return nil, errors.New("OutboundHandlerConfig is nil").Path("App", "Proxyman", "Outbound", "OutboundHandlerConfig") return nil, newError("OutboundHandlerConfig is nil")
} }
config, err := c.ProxySettings.GetInstance() config, err := c.ProxySettings.GetInstance()
if err != nil { if err != nil {

View File

@ -0,0 +1,7 @@
package proxyman
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).Path("App", "Proxyman")
}

View File

@ -7,7 +7,6 @@ import (
"v2ray.com/core/app/proxyman" "v2ray.com/core/app/proxyman"
"v2ray.com/core/app/proxyman/mux" "v2ray.com/core/app/proxyman/mux"
"v2ray.com/core/common/dice" "v2ray.com/core/common/dice"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
"v2ray.com/core/proxy" "v2ray.com/core/proxy"
) )
@ -37,7 +36,7 @@ func NewAlwaysOnInboundHandler(ctx context.Context, tag string, receiverConfig *
} }
for port := pr.From; port <= pr.To; port++ { for port := pr.From; port <= pr.To; port++ {
if nl.HasNetwork(net.Network_TCP) { if nl.HasNetwork(net.Network_TCP) {
log.Trace(errors.New("creating tcp worker on ", address, ":", port).AtDebug().Path("App", "Proxyman", "Inbound", "AlwaysOnInboundHandler")) log.Trace(newError("creating tcp worker on ", address, ":", port).AtDebug())
worker := &tcpWorker{ worker := &tcpWorker{
address: address, address: address,
port: net.Port(port), port: net.Port(port),

View File

@ -9,7 +9,6 @@ import (
"v2ray.com/core/app/proxyman" "v2ray.com/core/app/proxyman"
"v2ray.com/core/app/proxyman/mux" "v2ray.com/core/app/proxyman/mux"
"v2ray.com/core/common/dice" "v2ray.com/core/common/dice"
"v2ray.com/core/common/errors"
v2net "v2ray.com/core/common/net" v2net "v2ray.com/core/common/net"
"v2ray.com/core/proxy" "v2ray.com/core/proxy"
) )
@ -93,7 +92,7 @@ func (h *DynamicInboundHandler) refresh() error {
port := h.allocatePort() port := h.allocatePort()
p, err := proxy.CreateInboundHandler(ctx, h.proxyConfig) p, err := proxy.CreateInboundHandler(ctx, h.proxyConfig)
if err != nil { if err != nil {
log.Trace(errors.New("failed to create proxy instance").Base(err).Path("App", "Proxyman", "Inbound", "DynamicInboundHandler").AtWarning()) log.Trace(newError("failed to create proxy instance").Base(err).AtWarning())
continue continue
} }
nl := p.Network() nl := p.Network()
@ -108,7 +107,7 @@ func (h *DynamicInboundHandler) refresh() error {
dispatcher: h.mux, dispatcher: h.mux,
} }
if err := worker.Start(); err != nil { if err := worker.Start(); err != nil {
log.Trace(errors.New("failed to create TCP worker").Base(err).AtWarning().Path("App", "Proxyman", "Inbound", "DynamicInboundHandler")) log.Trace(newError("failed to create TCP worker").Base(err).AtWarning())
continue continue
} }
workers = append(workers, worker) workers = append(workers, worker)
@ -124,7 +123,7 @@ func (h *DynamicInboundHandler) refresh() error {
dispatcher: h.mux, dispatcher: h.mux,
} }
if err := worker.Start(); err != nil { if err := worker.Start(); err != nil {
log.Trace(errors.New("failed to create UDP worker").Base(err).AtWarning().Path("App", "Proxyman", "Inbound", "DynamicInboundHandler")) log.Trace(newError("failed to create UDP worker").Base(err).AtWarning())
continue continue
} }
workers = append(workers, worker) workers = append(workers, worker)

View File

@ -0,0 +1,7 @@
package inbound
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).Path("App", "Proxyman", "Inbound")
}

View File

@ -1,11 +1,12 @@
package inbound package inbound
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg inbound -path App,Proxyman,Inbound
import ( import (
"context" "context"
"v2ray.com/core/app/proxyman" "v2ray.com/core/app/proxyman"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/errors"
) )
type DefaultInboundHandlerManager struct { type DefaultInboundHandlerManager struct {
@ -26,7 +27,7 @@ func (m *DefaultInboundHandlerManager) AddHandler(ctx context.Context, config *p
} }
receiverSettings, ok := rawReceiverSettings.(*proxyman.ReceiverConfig) receiverSettings, ok := rawReceiverSettings.(*proxyman.ReceiverConfig)
if !ok { if !ok {
return errors.New("not a ReceiverConfig").Path("App", "Proxyman", "Inbound", "DefaultInboundHandlerManager") return newError("not a ReceiverConfig")
} }
proxySettings, err := config.ProxySettings.GetInstance() proxySettings, err := config.ProxySettings.GetInstance()
if err != nil { if err != nil {
@ -50,7 +51,7 @@ func (m *DefaultInboundHandlerManager) AddHandler(ctx context.Context, config *p
} }
if handler == nil { if handler == nil {
return errors.New("unknown allocation strategy: ", receiverSettings.AllocationStrategy.Type).Path("App", "Proxyman", "Inbound", "DefaultInboundHandlerManager") return newError("unknown allocation strategy: ", receiverSettings.AllocationStrategy.Type)
} }
m.handlers = append(m.handlers, handler) m.handlers = append(m.handlers, handler)
@ -63,7 +64,7 @@ func (m *DefaultInboundHandlerManager) AddHandler(ctx context.Context, config *p
func (m *DefaultInboundHandlerManager) GetHandler(ctx context.Context, tag string) (proxyman.InboundHandler, error) { func (m *DefaultInboundHandlerManager) GetHandler(ctx context.Context, tag string) (proxyman.InboundHandler, error) {
handler, found := m.taggedHandlers[tag] handler, found := m.taggedHandlers[tag]
if !found { if !found {
return nil, errors.New("handler not found: ", tag).Path("App", "Proxyman", "Inbound", "DefaultInboundHandlerManager") return nil, newError("handler not found: ", tag)
} }
return handler, nil return handler, nil
} }

View File

@ -11,7 +11,6 @@ import (
"v2ray.com/core/app/dispatcher" "v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/errors"
v2net "v2ray.com/core/common/net" v2net "v2ray.com/core/common/net"
"v2ray.com/core/proxy" "v2ray.com/core/proxy"
"v2ray.com/core/transport/internet" "v2ray.com/core/transport/internet"
@ -54,7 +53,7 @@ func (w *tcpWorker) callback(conn internet.Connection) {
ctx = proxy.ContextWithInboundEntryPoint(ctx, v2net.TCPDestination(w.address, w.port)) ctx = proxy.ContextWithInboundEntryPoint(ctx, v2net.TCPDestination(w.address, w.port))
ctx = proxy.ContextWithSource(ctx, v2net.DestinationFromAddr(conn.RemoteAddr())) ctx = proxy.ContextWithSource(ctx, v2net.DestinationFromAddr(conn.RemoteAddr()))
if err := w.proxy.Process(ctx, v2net.Network_TCP, conn, w.dispatcher); err != nil { if err := w.proxy.Process(ctx, v2net.Network_TCP, conn, w.dispatcher); err != nil {
log.Trace(errors.New("connection ends").Base(err).Path("App", "Proxyman", "Inbound", "TCPWorker")) log.Trace(newError("connection ends").Base(err))
} }
cancel() cancel()
conn.Close() conn.Close()
@ -231,7 +230,7 @@ func (w *udpWorker) callback(b *buf.Buffer, source v2net.Destination, originalDe
ctx = proxy.ContextWithSource(ctx, source) ctx = proxy.ContextWithSource(ctx, source)
ctx = proxy.ContextWithInboundEntryPoint(ctx, v2net.UDPDestination(w.address, w.port)) ctx = proxy.ContextWithInboundEntryPoint(ctx, v2net.UDPDestination(w.address, w.port))
if err := w.proxy.Process(ctx, v2net.Network_UDP, conn, w.dispatcher); err != nil { if err := w.proxy.Process(ctx, v2net.Network_UDP, conn, w.dispatcher); err != nil {
log.Trace(errors.New("connection ends").Base(err).Path("App", "Proxymann", "Inbound", "UDPWorker")) log.Trace(newError("connection ends").Base(err))
} }
w.removeConn(source) w.removeConn(source)
cancel() cancel()

View File

@ -0,0 +1,7 @@
package mux
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).Path("App", "Proxyman", "Mux")
}

View File

@ -2,7 +2,6 @@ package mux
import ( import (
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
"v2ray.com/core/common/serial" "v2ray.com/core/common/serial"
) )
@ -114,7 +113,7 @@ func (f FrameMetadata) AsSupplier() buf.Supplier {
func ReadFrameFrom(b []byte) (*FrameMetadata, error) { func ReadFrameFrom(b []byte) (*FrameMetadata, error) {
if len(b) < 4 { if len(b) < 4 {
return nil, errors.New("insufficient buffer: ", len(b)).Path("App", "Proxyman", "Mux", "Frame") return nil, newError("insufficient buffer: ", len(b))
} }
f := &FrameMetadata{ f := &FrameMetadata{
@ -144,7 +143,7 @@ func ReadFrameFrom(b []byte) (*FrameMetadata, error) {
addr = net.DomainAddress(string(b[1 : 1+nDomain])) addr = net.DomainAddress(string(b[1 : 1+nDomain]))
b = b[nDomain+1:] b = b[nDomain+1:]
default: default:
return nil, errors.New("unknown address type: ", addrType).Path("App", "Proxyman", "Mux", "Frame") return nil, newError("unknown address type: ", addrType)
} }
switch network { switch network {
case TargetNetworkTCP: case TargetNetworkTCP:
@ -152,7 +151,7 @@ func ReadFrameFrom(b []byte) (*FrameMetadata, error) {
case TargetNetworkUDP: case TargetNetworkUDP:
f.Target = net.UDPDestination(addr, port) f.Target = net.UDPDestination(addr, port)
default: default:
return nil, errors.New("unknown network type: ", network).Path("App", "Proxyman", "Mux", "Frame") return nil, newError("unknown network type: ", network)
} }
} }

View File

@ -1,5 +1,7 @@
package mux package mux
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg mux -path App,Proxyman,Mux
import ( import (
"context" "context"
"sync" "sync"
@ -9,7 +11,6 @@ import (
"v2ray.com/core/app/dispatcher" "v2ray.com/core/app/dispatcher"
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
"v2ray.com/core/common/signal" "v2ray.com/core/common/signal"
"v2ray.com/core/proxy" "v2ray.com/core/proxy"
@ -83,7 +84,7 @@ func (m *ClientManager) Dispatch(ctx context.Context, outboundRay ray.OutboundRa
client, err := NewClient(m.proxy, m.dialer, m) client, err := NewClient(m.proxy, m.dialer, m)
if err != nil { if err != nil {
return errors.New("failed to create client").Base(err).Path("App", "Proxyman", "Mux", "ClientManager") return newError("failed to create client").Base(err)
} }
m.clients = append(m.clients, client) m.clients = append(m.clients, client)
client.Dispatch(ctx, outboundRay) client.Dispatch(ctx, outboundRay)
@ -200,16 +201,16 @@ func fetchInput(ctx context.Context, s *session, output buf.Writer) {
defer writer.Close() defer writer.Close()
defer s.closeUplink() defer s.closeUplink()
log.Trace(errors.New("dispatching request to ", dest).Path("Proxyman", "Mux", "Client")) log.Trace(newError("dispatching request to ", dest))
data, _ := s.input.ReadTimeout(time.Millisecond * 500) data, _ := s.input.ReadTimeout(time.Millisecond * 500)
if data != nil { if data != nil {
if err := writer.Write(data); err != nil { if err := writer.Write(data); err != nil {
log.Trace(errors.New("failed to write first payload").Base(err).Path("Proxyman", "Mux", "Client")) log.Trace(newError("failed to write first payload").Base(err))
return return
} }
} }
if err := buf.PipeUntilEOF(signal.BackgroundTimer(), s.input, writer); err != nil { if err := buf.PipeUntilEOF(signal.BackgroundTimer(), s.input, writer); err != nil {
log.Trace(errors.New("failed to fetch all input").Base(err).Path("Proxyman", "Mux", "Client")) log.Trace(newError("failed to fetch all input").Base(err))
} }
} }
@ -287,7 +288,7 @@ func (m *Client) fetchOutput() {
for { for {
meta, err := reader.ReadMetadata() meta, err := reader.ReadMetadata()
if err != nil { if err != nil {
log.Trace(errors.New("failed to read metadata").Base(err).Path("Proxyman", "Mux", "Client")) log.Trace(newError("failed to read metadata").Base(err))
break break
} }
m.access.RLock() m.access.RLock()
@ -308,7 +309,7 @@ func (m *Client) fetchOutput() {
} }
if err != nil { if err != nil {
log.Trace(errors.New("failed to read data").Base(err).Path("Proxyman", "Mux", "Client")) log.Trace(newError("failed to read data").Base(err))
break break
} }
} }
@ -324,7 +325,7 @@ func NewServer(ctx context.Context) *Server {
space.OnInitialize(func() error { space.OnInitialize(func() error {
d := dispatcher.FromSpace(space) d := dispatcher.FromSpace(space)
if d == nil { if d == nil {
return errors.New("no dispatcher in space").Path("Proxyman", "Mux", "Server") return newError("no dispatcher in space")
} }
s.dispatcher = d s.dispatcher = d
return nil return nil
@ -363,7 +364,7 @@ func (w *ServerWorker) remove(id uint16) {
func handle(ctx context.Context, s *session, output buf.Writer) { func handle(ctx context.Context, s *session, output buf.Writer) {
writer := NewResponseWriter(s.id, output) writer := NewResponseWriter(s.id, output)
if err := buf.PipeUntilEOF(signal.BackgroundTimer(), s.input, writer); err != nil { if err := buf.PipeUntilEOF(signal.BackgroundTimer(), s.input, writer); err != nil {
log.Trace(errors.New("session ", s.id, " ends: ").Base(err).Path("Proxyman", "Mux", "ServerWorker")) log.Trace(newError("session ", s.id, " ends: ").Base(err))
} }
writer.Close() writer.Close()
s.closeDownlink() s.closeDownlink()
@ -381,7 +382,7 @@ func (w *ServerWorker) run(ctx context.Context) {
meta, err := reader.ReadMetadata() meta, err := reader.ReadMetadata()
if err != nil { if err != nil {
log.Trace(errors.New("failed to read metadata").Base(err).Path("Proxyman", "Mux", "ServerWorker")) log.Trace(newError("failed to read metadata").Base(err))
return return
} }
@ -395,10 +396,10 @@ func (w *ServerWorker) run(ctx context.Context) {
} }
if meta.SessionStatus == SessionStatusNew { if meta.SessionStatus == SessionStatusNew {
log.Trace(errors.New("received request for ", meta.Target).Path("Proxyman", "Mux", "ServerWorker")) log.Trace(newError("received request for ", meta.Target))
inboundRay, err := w.dispatcher.Dispatch(ctx, meta.Target) inboundRay, err := w.dispatcher.Dispatch(ctx, meta.Target)
if err != nil { if err != nil {
log.Trace(errors.New("failed to dispatch request.").Base(err).Path("Proxymann", "Mux", "ServerWorker")) log.Trace(newError("failed to dispatch request.").Base(err))
continue continue
} }
s = &session{ s = &session{
@ -424,7 +425,7 @@ func (w *ServerWorker) run(ctx context.Context) {
} }
if err != nil { if err != nil {
log.Trace(errors.New("failed to read data").Base(err).Path("Proxymann", "Mux", "ServerWorker")) log.Trace(newError("failed to read data").Base(err))
break break
} }
} }

View File

@ -4,7 +4,6 @@ import (
"io" "io"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/serial" "v2ray.com/core/common/serial"
) )
@ -30,7 +29,7 @@ func (r *Reader) ReadMetadata() (*FrameMetadata, error) {
} }
metaLen := serial.BytesToUint16(b.Bytes()) metaLen := serial.BytesToUint16(b.Bytes())
if metaLen > 512 { if metaLen > 512 {
return nil, errors.New("invalid metalen ", metaLen).Path("App", "Proxyman", "Mux", "Reader") return nil, newError("invalid metalen ", metaLen)
} }
b.Clear() b.Clear()
if err := b.AppendSupplier(buf.ReadFullFrom(r.reader, int(metaLen))); err != nil { if err := b.AppendSupplier(buf.ReadFullFrom(r.reader, int(metaLen))); err != nil {

View File

@ -0,0 +1,7 @@
package outbound
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).Path("App", "Proxyman", "Outbound")
}

View File

@ -32,12 +32,12 @@ func NewHandler(ctx context.Context, config *proxyman.OutboundHandlerConfig) (*H
} }
space := app.SpaceFromContext(ctx) space := app.SpaceFromContext(ctx)
if space == nil { if space == nil {
return nil, errors.New("no space in context").Path("App", "Proxyman", "Outbound", "Handler") return nil, newError("no space in context")
} }
space.OnInitialize(func() error { space.OnInitialize(func() error {
ohm := proxyman.OutboundHandlerManagerFromSpace(space) ohm := proxyman.OutboundHandlerManagerFromSpace(space)
if ohm == nil { if ohm == nil {
return errors.New("no OutboundManager in space").Path("App", "Proxyman", "Outbound", "Handler") return newError("no OutboundManager in space")
} }
h.outboundManager = ohm h.outboundManager = ohm
return nil return nil
@ -52,7 +52,7 @@ func NewHandler(ctx context.Context, config *proxyman.OutboundHandlerConfig) (*H
case *proxyman.SenderConfig: case *proxyman.SenderConfig:
h.senderSettings = s h.senderSettings = s
default: default:
return nil, errors.New("settings is not SenderConfig").Path("App", "Proxyman", "Outbound", "Handler") return nil, newError("settings is not SenderConfig")
} }
} }
@ -73,13 +73,13 @@ func (h *Handler) Dispatch(ctx context.Context, outboundRay ray.OutboundRay) {
if h.mux != nil { if h.mux != nil {
err := h.mux.Dispatch(ctx, outboundRay) err := h.mux.Dispatch(ctx, outboundRay)
if err != nil { if err != nil {
log.Trace(errors.New("failed to process outbound traffic").Base(err).Path("App", "Proxyman", "Outbound", "Handler")) log.Trace(newError("failed to process outbound traffic").Base(err))
} }
} else { } else {
err := h.proxy.Process(ctx, outboundRay, h) err := h.proxy.Process(ctx, outboundRay, h)
// Ensure outbound ray is properly closed. // Ensure outbound ray is properly closed.
if err != nil && errors.Cause(err) != io.EOF { if err != nil && errors.Cause(err) != io.EOF {
log.Trace(errors.New("failed to process outbound traffic").Base(err).Path("App", "Proxyman", "Outbound", "Handler")) log.Trace(newError("failed to process outbound traffic").Base(err))
outboundRay.OutboundOutput().CloseError() outboundRay.OutboundOutput().CloseError()
} else { } else {
outboundRay.OutboundOutput().Close() outboundRay.OutboundOutput().Close()
@ -95,14 +95,14 @@ func (h *Handler) Dial(ctx context.Context, dest v2net.Destination) (internet.Co
tag := h.senderSettings.ProxySettings.Tag tag := h.senderSettings.ProxySettings.Tag
handler := h.outboundManager.GetHandler(tag) handler := h.outboundManager.GetHandler(tag)
if handler != nil { if handler != nil {
log.Trace(errors.New("proxying to ", tag).AtDebug().Path("App", "Proxyman", "Outbound", "Handler")) log.Trace(newError("proxying to ", tag).AtDebug())
ctx = proxy.ContextWithTarget(ctx, dest) ctx = proxy.ContextWithTarget(ctx, dest)
stream := ray.NewRay(ctx) stream := ray.NewRay(ctx)
go handler.Dispatch(ctx, stream) go handler.Dispatch(ctx, stream)
return NewConnection(stream), nil return NewConnection(stream), nil
} }
log.Trace(errors.New("failed to get outbound handler with tag: ", tag).AtWarning().Path("App", "Proxyman", "Outbound", "Handler")) log.Trace(newError("failed to get outbound handler with tag: ", tag).AtWarning())
} }
if h.senderSettings.Via != nil { if h.senderSettings.Via != nil {

View File

@ -1,5 +1,7 @@
package outbound package outbound
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg outbound -path App,Proxyman,Outbound
import ( import (
"context" "context"
"sync" "sync"

View File

@ -1,6 +1,8 @@
// Package proxyman defines applications for manageing inbound and outbound proxies. // Package proxyman defines applications for manageing inbound and outbound proxies.
package proxyman package proxyman
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg proxyman -path App,Proxyman
import ( import (
"context" "context"

View File

@ -4,7 +4,6 @@ import (
"context" "context"
"net" "net"
"v2ray.com/core/common/errors"
v2net "v2ray.com/core/common/net" v2net "v2ray.com/core/common/net"
) )
@ -53,7 +52,7 @@ func (v *RoutingRule) BuildCondition() (Condition, error) {
} }
ipv6Cond.Add(matcher) ipv6Cond.Add(matcher)
default: default:
return nil, errors.New("Router: Invalid IP length.") return nil, newError("Router: Invalid IP length.")
} }
} }
@ -94,7 +93,7 @@ func (v *RoutingRule) BuildCondition() (Condition, error) {
} }
ipv6Cond.Add(matcher) ipv6Cond.Add(matcher)
default: default:
return nil, errors.New("Router: Invalid IP length.") return nil, newError("Router: Invalid IP length.")
} }
} }
@ -119,7 +118,7 @@ func (v *RoutingRule) BuildCondition() (Condition, error) {
} }
if conds.Len() == 0 { if conds.Len() == 0 {
return nil, errors.New("Router: This rule has no effective fields.") return nil, newError("Router: This rule has no effective fields.")
} }
return conds, nil return conds, nil

View File

@ -0,0 +1,5 @@
package router
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("App", "Router") }

View File

@ -1,5 +1,7 @@
package router package router
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg router -path App,Router
import ( import (
"context" "context"
@ -7,13 +9,12 @@ import (
"v2ray.com/core/app/dns" "v2ray.com/core/app/dns"
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
"v2ray.com/core/proxy" "v2ray.com/core/proxy"
) )
var ( var (
ErrNoRuleApplicable = errors.New("No rule applicable") ErrNoRuleApplicable = newError("No rule applicable")
) )
type Router struct { type Router struct {
@ -25,7 +26,7 @@ type Router struct {
func NewRouter(ctx context.Context, config *Config) (*Router, error) { func NewRouter(ctx context.Context, config *Config) (*Router, error) {
space := app.SpaceFromContext(ctx) space := app.SpaceFromContext(ctx)
if space == nil { if space == nil {
return nil, errors.New("Router: No space in context.") return nil, newError("Router: No space in context.")
} }
r := &Router{ r := &Router{
domainStrategy: config.DomainStrategy, domainStrategy: config.DomainStrategy,
@ -44,7 +45,7 @@ func NewRouter(ctx context.Context, config *Config) (*Router, error) {
r.dnsServer = dns.FromSpace(space) r.dnsServer = dns.FromSpace(space)
if r.dnsServer == nil { if r.dnsServer == nil {
return errors.New("Router: DNS is not found in the space.") return newError("Router: DNS is not found in the space.")
} }
return nil return nil
}) })
@ -76,7 +77,7 @@ func (v *Router) TakeDetour(ctx context.Context) (string, error) {
} }
if v.domainStrategy == Config_IpIfNonMatch && dest.Address.Family().IsDomain() { if v.domainStrategy == Config_IpIfNonMatch && dest.Address.Family().IsDomain() {
log.Trace(errors.New("looking up IP for ", dest).Path("App", "Router")) log.Trace(newError("looking up IP for ", dest))
ipDests := v.resolveIP(dest) ipDests := v.resolveIP(dest)
if ipDests != nil { if ipDests != nil {
ctx = proxy.ContextWithResolveIPs(ctx, ipDests) ctx = proxy.ContextWithResolveIPs(ctx, ipDests)

View File

@ -5,7 +5,6 @@ import (
"reflect" "reflect"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/errors"
) )
type Application interface { type Application interface {
@ -25,7 +24,7 @@ func CreateAppFromConfig(ctx context.Context, config interface{}) (Application,
case Application: case Application:
return a, nil return a, nil
default: default:
return nil, errors.New("App: Not an application.") return nil, newError("App: Not an application.")
} }
} }
@ -82,7 +81,7 @@ func (v *spaceImpl) GetApplication(appInterface interface{}) Application {
func (v *spaceImpl) AddApplication(app Application) error { func (v *spaceImpl) AddApplication(app Application) error {
if v == nil { if v == nil {
return errors.New("App: Nil space.") return newError("App: Nil space.")
} }
appType := reflect.TypeOf(app.Interface()) appType := reflect.TypeOf(app.Interface())
v.cache[appType] = app v.cache[appType] = app
@ -113,7 +112,7 @@ const (
func AddApplicationToSpace(ctx context.Context, appConfig interface{}) error { func AddApplicationToSpace(ctx context.Context, appConfig interface{}) error {
space := SpaceFromContext(ctx) space := SpaceFromContext(ctx)
if space == nil { if space == nil {
return errors.New("App: No space in context.") return newError("App: No space in context.")
} }
application, err := CreateAppFromConfig(ctx, appConfig) application, err := CreateAppFromConfig(ctx, appConfig)
if err != nil { if err != nil {

3
common/buf/buf.go Normal file
View File

@ -0,0 +1,3 @@
package buf
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg buf -path Buf

View File

@ -0,0 +1,5 @@
package buf
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("Buf") }

View File

@ -14,7 +14,7 @@ type Reader interface {
Read() (*Buffer, error) Read() (*Buffer, error)
} }
var ErrReadTimeout = errors.New("Buf: IO timeout.") var ErrReadTimeout = newError("Buf: IO timeout.")
type TimeoutReader interface { type TimeoutReader interface {
ReadTimeout(time.Duration) (*Buffer, error) ReadTimeout(time.Duration) (*Buffer, error)

View File

@ -2,6 +2,8 @@
// See each sub-package for detail. // See each sub-package for detail.
package common package common
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg common -path Common
// Must panics if err is not nil. // Must panics if err is not nil.
func Must(err error) { func Must(err error) {
if err != nil { if err != nil {

View File

@ -8,12 +8,11 @@ import (
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/serial" "v2ray.com/core/common/serial"
) )
var ( var (
errInsufficientBuffer = errors.New("insufficient buffer") errInsufficientBuffer = newError("insufficient buffer")
) )
type BytesGenerator interface { type BytesGenerator interface {
@ -52,7 +51,7 @@ type AEADAuthenticator struct {
func (v *AEADAuthenticator) Open(dst, cipherText []byte) ([]byte, error) { func (v *AEADAuthenticator) Open(dst, cipherText []byte) ([]byte, error) {
iv := v.NonceGenerator.Next() iv := v.NonceGenerator.Next()
if len(iv) != v.AEAD.NonceSize() { if len(iv) != v.AEAD.NonceSize() {
return nil, errors.New("Crypto:AEADAuthenticator: Invalid nonce size: ", len(iv)) return nil, newError("Crypto:AEADAuthenticator: Invalid nonce size: ", len(iv))
} }
additionalData := v.AdditionalDataGenerator.Next() additionalData := v.AdditionalDataGenerator.Next()
@ -62,7 +61,7 @@ func (v *AEADAuthenticator) Open(dst, cipherText []byte) ([]byte, error) {
func (v *AEADAuthenticator) Seal(dst, plainText []byte) ([]byte, error) { func (v *AEADAuthenticator) Seal(dst, plainText []byte) ([]byte, error) {
iv := v.NonceGenerator.Next() iv := v.NonceGenerator.Next()
if len(iv) != v.AEAD.NonceSize() { if len(iv) != v.AEAD.NonceSize() {
return nil, errors.New("Crypto:AEADAuthenticator: Invalid nonce size: ", len(iv)) return nil, newError("Crypto:AEADAuthenticator: Invalid nonce size: ", len(iv))
} }
additionalData := v.AdditionalDataGenerator.Next() additionalData := v.AdditionalDataGenerator.Next()
@ -128,13 +127,13 @@ func (v *AuthenticationReader) nextChunk(mask uint16) error {
return errInsufficientBuffer return errInsufficientBuffer
} }
if size > readerBufferSize-2 { if size > readerBufferSize-2 {
return errors.New("size too large: ", size).Path("Common", "Crypto", "AuthenticationReader") return newError("size too large: ", size)
} }
if size == v.auth.Overhead() { if size == v.auth.Overhead() {
return io.EOF return io.EOF
} }
if size < v.auth.Overhead() { if size < v.auth.Overhead() {
return errors.New("invalid packet size: ", size).Path("Common", "Crypto", "AuthenticationReader") return newError("invalid packet size: ", size)
} }
cipherChunk := v.buffer.BytesRange(2, size+2) cipherChunk := v.buffer.BytesRange(2, size+2)
plainChunk, err := v.auth.Open(cipherChunk[:0], cipherChunk) plainChunk, err := v.auth.Open(cipherChunk[:0], cipherChunk)

View File

@ -1,2 +1,4 @@
// Package crypto provides common crypto libraries for V2Ray. // Package crypto provides common crypto libraries for V2Ray.
package crypto package crypto
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg crypto -path Crypto

View File

@ -0,0 +1,5 @@
package crypto
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("Crypto") }

View File

@ -1,4 +1,3 @@
// GENERATED CODE. DO NOT MODIFY!
package internal package internal
import "encoding/binary" import "encoding/binary"

View File

@ -0,0 +1,5 @@
package common
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("Common") }

View File

@ -4,7 +4,6 @@ import (
"net" "net"
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/predicate" "v2ray.com/core/common/predicate"
) )
@ -95,7 +94,7 @@ func IPAddress(ip []byte) Address {
} }
return addr return addr
default: default:
log.Trace(errors.New("Net: Invalid IP format: ", ip).AtError()) log.Trace(newError("Net: Invalid IP format: ", ip).AtError())
return nil return nil
} }
} }

View File

@ -0,0 +1,5 @@
package net
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("Net") }

View File

@ -1,2 +1,4 @@
// Package net contains common network utilities. // Package net contains common network utilities.
package net package net
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg net -path Net

View File

@ -3,7 +3,6 @@ package net
import ( import (
"strconv" "strconv"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/serial" "v2ray.com/core/common/serial"
) )
@ -20,7 +19,7 @@ func PortFromBytes(port []byte) Port {
// @error when the integer is not positive or larger then 65535 // @error when the integer is not positive or larger then 65535
func PortFromInt(val uint32) (Port, error) { func PortFromInt(val uint32) (Port, error) {
if val > 65535 { if val > 65535 {
return Port(0), errors.New("Net: Invalid port range: ", val) return Port(0), newError("Net: Invalid port range: ", val)
} }
return Port(val), nil return Port(val), nil
} }
@ -30,7 +29,7 @@ func PortFromInt(val uint32) (Port, error) {
func PortFromString(s string) (Port, error) { func PortFromString(s string) (Port, error) {
val, err := strconv.ParseUint(s, 10, 32) val, err := strconv.ParseUint(s, 10, 32)
if err != nil { if err != nil {
return Port(0), errors.New("Net: Invalid port range: ", s) return Port(0), newError("Net: Invalid port range: ", s)
} }
return PortFromInt(uint32(val)) return PortFromInt(uint32(val))
} }

View File

@ -0,0 +1,5 @@
package protocol
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("Protocol") }

View File

@ -0,0 +1,3 @@
package protocol
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg protocol -path Protocol

View File

@ -1,15 +1,11 @@
package protocol package protocol
import ( import "time"
"time"
"v2ray.com/core/common/errors"
)
var ( var (
ErrAccountMissing = errors.New("Account is not specified.") ErrAccountMissing = newError("Account is not specified.")
ErrNonMessageType = errors.New("Not a protobuf message.") ErrNonMessageType = newError("Not a protobuf message.")
ErrUnknownAccountType = errors.New("Unknown account type.") ErrUnknownAccountType = newError("Unknown account type.")
) )
func (v *User) GetTypedAccount() (Account, error) { func (v *User) GetTypedAccount() (Account, error) {
@ -27,7 +23,7 @@ func (v *User) GetTypedAccount() (Account, error) {
if account, ok := rawAccount.(Account); ok { if account, ok := rawAccount.(Account); ok {
return account, nil return account, nil
} }
return nil, errors.New("Unknown account type: ", v.Account.Type) return nil, newError("Unknown account type: ", v.Account.Type)
} }
func (v *User) GetSettings() UserSettings { func (v *User) GetSettings() UserSettings {

View File

@ -0,0 +1,5 @@
package retry
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("Retry") }

View File

@ -1,13 +1,13 @@
package retry package retry
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg retry -path Retry
import ( import (
"time" "time"
"v2ray.com/core/common/errors"
) )
var ( var (
ErrRetryFailed = errors.New("Retry: All retry attempts failed.") ErrRetryFailed = newError("Retry: All retry attempts failed.")
) )
// Strategy is a way to retry on a specific function. // Strategy is a way to retry on a specific function.
@ -38,7 +38,7 @@ func (r *retryer) On(method func() error) error {
<-time.After(time.Duration(delay) * time.Millisecond) <-time.After(time.Duration(delay) * time.Millisecond)
attempt++ attempt++
} }
return errors.New(accumulatedError).Base(ErrRetryFailed) return newError(accumulatedError).Base(ErrRetryFailed)
} }
// Timed returns a retry strategy with fixed interval. // Timed returns a retry strategy with fixed interval.

View File

@ -2,7 +2,6 @@ package common
import ( import (
"context" "context"
"errors"
"reflect" "reflect"
) )
@ -17,7 +16,7 @@ var (
func RegisterConfig(config interface{}, configCreator ConfigCreator) error { func RegisterConfig(config interface{}, configCreator ConfigCreator) error {
configType := reflect.TypeOf(config) configType := reflect.TypeOf(config)
if _, found := typeCreatorRegistry[configType]; found { if _, found := typeCreatorRegistry[configType]; found {
return errors.New("Common: " + configType.Name() + " is already registered.") return newError("Common: " + configType.Name() + " is already registered.")
} }
typeCreatorRegistry[configType] = configCreator typeCreatorRegistry[configType] = configCreator
return nil return nil
@ -28,7 +27,7 @@ func CreateObject(ctx context.Context, config interface{}) (interface{}, error)
configType := reflect.TypeOf(config) configType := reflect.TypeOf(config)
creator, found := typeCreatorRegistry[configType] creator, found := typeCreatorRegistry[configType]
if !found { if !found {
return nil, errors.New("Common: " + configType.String() + " is not registered.") return nil, newError("Common: " + configType.String() + " is not registered.")
} }
return creator(ctx, config) return creator(ctx, config)
} }

View File

@ -70,7 +70,7 @@ func New() *UUID {
// ParseBytes converts an UUID in byte form to object. // ParseBytes converts an UUID in byte form to object.
func ParseBytes(b []byte) (*UUID, error) { func ParseBytes(b []byte) (*UUID, error) {
if len(b) != 16 { if len(b) != 16 {
return nil, errors.New("Invalid UUID: ", b) return nil, errors.New("invalid UUID: ", b)
} }
uuid := new(UUID) uuid := new(UUID)
copy(uuid[:], b) copy(uuid[:], b)
@ -81,7 +81,7 @@ func ParseBytes(b []byte) (*UUID, error) {
func ParseString(str string) (*UUID, error) { func ParseString(str string) (*UUID, error) {
text := []byte(str) text := []byte(str)
if len(text) < 32 { if len(text) < 32 {
return nil, errors.New("Invalid UUID: ", str) return nil, errors.New("invalid UUID: ", str)
} }
uuid := new(UUID) uuid := new(UUID)

View File

@ -9,6 +9,8 @@
// connections. // connections.
package core package core
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg core -path Core
import ( import (
"fmt" "fmt"

5
errors.generated.go Normal file
View File

@ -0,0 +1,5 @@
package core
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("Core") }

View File

@ -6,7 +6,6 @@ import (
"github.com/golang/protobuf/proto" "github.com/golang/protobuf/proto"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/errors"
) )
// ConfigLoader is an utility to load V2Ray config from external source. // ConfigLoader is an utility to load V2Ray config from external source.
@ -24,7 +23,7 @@ func RegisterConfigLoader(format ConfigFormat, loader ConfigLoader) error {
func LoadConfig(format ConfigFormat, input io.Reader) (*Config, error) { func LoadConfig(format ConfigFormat, input io.Reader) (*Config, error) {
loader, found := configLoaderCache[format] loader, found := configLoaderCache[format]
if !found { if !found {
return nil, errors.New("Core: ", ConfigFormat_name[int32(format)], " is not loadable.") return nil, newError("Core: ", ConfigFormat_name[int32(format)], " is not loadable.")
} }
return loader(input) return loader(input)
} }

5
main/errors.generated.go Normal file
View File

@ -0,0 +1,5 @@
package main
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("Main") }

View File

@ -1,5 +1,7 @@
package main package main
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg main -path Main
import ( import (
"flag" "flag"
"fmt" "fmt"
@ -11,7 +13,6 @@ import (
"syscall" "syscall"
"v2ray.com/core" "v2ray.com/core"
"v2ray.com/core/common/errors"
_ "v2ray.com/core/main/distro/all" _ "v2ray.com/core/main/distro/all"
) )
@ -45,7 +46,7 @@ func GetConfigFormat() core.ConfigFormat {
func startV2Ray() (core.Server, error) { func startV2Ray() (core.Server, error) {
if len(configFile) == 0 { if len(configFile) == 0 {
return nil, errors.New("config file is not set").Path("Core") return nil, newError("config file is not set")
} }
var configInput io.Reader var configInput io.Reader
if configFile == "stdin:" { if configFile == "stdin:" {
@ -54,19 +55,19 @@ func startV2Ray() (core.Server, error) {
fixedFile := os.ExpandEnv(configFile) fixedFile := os.ExpandEnv(configFile)
file, err := os.Open(fixedFile) file, err := os.Open(fixedFile)
if err != nil { if err != nil {
return nil, errors.New("config file not readable").Path("Core").Base(err) return nil, newError("config file not readable").Base(err)
} }
defer file.Close() defer file.Close()
configInput = file configInput = file
} }
config, err := core.LoadConfig(GetConfigFormat(), configInput) config, err := core.LoadConfig(GetConfigFormat(), configInput)
if err != nil { if err != nil {
return nil, errors.New("failed to read config file: ", configFile).Base(err).Path("Core") return nil, newError("failed to read config file: ", configFile).Base(err)
} }
server, err := core.New(config) server, err := core.New(config)
if err != nil { if err != nil {
return nil, errors.New("failed to create initialize").Base(err).Path("Core") return nil, newError("failed to create initialize").Base(err)
} }
return server, nil return server, nil

View File

@ -1,6 +1,8 @@
// Package blackhole is an outbound handler that blocks all connections. // Package blackhole is an outbound handler that blocks all connections.
package blackhole package blackhole
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg blackhole -path Proxy,Blackhole
import ( import (
"context" "context"
"time" "time"

View File

@ -0,0 +1,7 @@
package blackhole
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).Path("Proxy", "Blackhole")
}

View File

@ -1,5 +1,7 @@
package dokodemo package dokodemo
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg dokodemo -path Proxy,Dokodemo
import ( import (
"context" "context"
"runtime" "runtime"
@ -10,7 +12,6 @@ import (
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
"v2ray.com/core/common/signal" "v2ray.com/core/common/signal"
"v2ray.com/core/proxy" "v2ray.com/core/proxy"
@ -26,10 +27,10 @@ type DokodemoDoor struct {
func New(ctx context.Context, config *Config) (*DokodemoDoor, error) { func New(ctx context.Context, config *Config) (*DokodemoDoor, error) {
space := app.SpaceFromContext(ctx) space := app.SpaceFromContext(ctx)
if space == nil { if space == nil {
return nil, errors.New("Dokodemo: No space in context.") return nil, newError("Dokodemo: No space in context.")
} }
if config.NetworkList == nil || config.NetworkList.Size() == 0 { if config.NetworkList == nil || config.NetworkList.Size() == 0 {
return nil, errors.New("DokodemoDoor: No network specified.") return nil, newError("DokodemoDoor: No network specified.")
} }
d := &DokodemoDoor{ d := &DokodemoDoor{
config: config, config: config,
@ -44,7 +45,7 @@ func (d *DokodemoDoor) Network() net.NetworkList {
} }
func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher dispatcher.Interface) error { func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn internet.Connection, dispatcher dispatcher.Interface) error {
log.Trace(errors.New("Dokodemo: processing connection from: ", conn.RemoteAddr()).AtDebug()) log.Trace(newError("Dokodemo: processing connection from: ", conn.RemoteAddr()).AtDebug())
dest := net.Destination{ dest := net.Destination{
Network: network, Network: network,
Address: d.address, Address: d.address,
@ -56,7 +57,7 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
} }
} }
if !dest.IsValid() || dest.Address == nil { if !dest.IsValid() || dest.Address == nil {
return errors.New("unable to get destination").Path("Proxy", "Dokodemo") return newError("unable to get destination")
} }
timeout := time.Second * time.Duration(d.config.Timeout) timeout := time.Second * time.Duration(d.config.Timeout)
@ -76,7 +77,7 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
chunkReader := buf.NewReader(conn) chunkReader := buf.NewReader(conn)
if err := buf.PipeUntilEOF(timer, chunkReader, inboundRay.InboundInput()); err != nil { if err := buf.PipeUntilEOF(timer, chunkReader, inboundRay.InboundInput()); err != nil {
return errors.New("failed to transport request").Base(err).Path("Proxy", "Dokodemo") return newError("failed to transport request").Base(err)
} }
return nil return nil
@ -86,7 +87,7 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
v2writer := buf.NewWriter(conn) v2writer := buf.NewWriter(conn)
if err := buf.PipeUntilEOF(timer, inboundRay.InboundOutput(), v2writer); err != nil { if err := buf.PipeUntilEOF(timer, inboundRay.InboundOutput(), v2writer); err != nil {
return errors.New("failed to transport response").Base(err).Path("Proxy", "Dokodemo") return newError("failed to transport response").Base(err)
} }
return nil return nil
}) })
@ -94,7 +95,7 @@ func (d *DokodemoDoor) Process(ctx context.Context, network net.Network, conn in
if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil { if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil {
inboundRay.InboundInput().CloseError() inboundRay.InboundInput().CloseError()
inboundRay.InboundOutput().CloseError() inboundRay.InboundOutput().CloseError()
return errors.New("connection ends").Base(err).Path("Proxy", "Dokodemo") return newError("connection ends").Base(err)
} }
runtime.KeepAlive(timer) runtime.KeepAlive(timer)

View File

@ -0,0 +1,7 @@
package dokodemo
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).Path("Proxy", "Dokodemo")
}

View File

@ -0,0 +1,5 @@
package proxy
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("Proxy") }

View File

@ -0,0 +1,7 @@
package freedom
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).Path("Proxy", "Freedom")
}

View File

@ -1,10 +1,11 @@
package freedom package freedom
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg freedom -path Proxy,Freedom
import ( import (
"context" "context"
"time"
"runtime" "runtime"
"time"
"v2ray.com/core/app" "v2ray.com/core/app"
"v2ray.com/core/app/dns" "v2ray.com/core/app/dns"
@ -12,7 +13,6 @@ import (
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/dice" "v2ray.com/core/common/dice"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
"v2ray.com/core/common/retry" "v2ray.com/core/common/retry"
"v2ray.com/core/common/signal" "v2ray.com/core/common/signal"
@ -31,7 +31,7 @@ type Handler struct {
func New(ctx context.Context, config *Config) (*Handler, error) { func New(ctx context.Context, config *Config) (*Handler, error) {
space := app.SpaceFromContext(ctx) space := app.SpaceFromContext(ctx)
if space == nil { if space == nil {
return nil, errors.New("no space in context").Path("Proxy", "Freedom") return nil, newError("no space in context")
} }
f := &Handler{ f := &Handler{
domainStrategy: config.DomainStrategy, domainStrategy: config.DomainStrategy,
@ -42,7 +42,7 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
if config.DomainStrategy == Config_USE_IP { if config.DomainStrategy == Config_USE_IP {
f.dns = dns.FromSpace(space) f.dns = dns.FromSpace(space)
if f.dns == nil { if f.dns == nil {
return errors.New("DNS server is not found in the space").Path("Proxy", "Freedom") return newError("DNS server is not found in the space")
} }
} }
return nil return nil
@ -57,7 +57,7 @@ func (v *Handler) ResolveIP(destination net.Destination) net.Destination {
ips := v.dns.Get(destination.Address.Domain()) ips := v.dns.Get(destination.Address.Domain())
if len(ips) == 0 { if len(ips) == 0 {
log.Trace(errors.New("DNS returns nil answer. Keep domain as is.").Path("Proxy", "Freedom")) log.Trace(newError("DNS returns nil answer. Keep domain as is."))
return destination return destination
} }
@ -68,7 +68,7 @@ func (v *Handler) ResolveIP(destination net.Destination) net.Destination {
} else { } else {
newDest = net.UDPDestination(net.IPAddress(ip), destination.Port) newDest = net.UDPDestination(net.IPAddress(ip), destination.Port)
} }
log.Trace(errors.New("changing destination from ", destination, " to ", newDest).Path("Proxy", "Freedom")) log.Trace(newError("changing destination from ", destination, " to ", newDest))
return newDest return newDest
} }
@ -82,7 +82,7 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
Port: net.Port(server.Port), Port: net.Port(server.Port),
} }
} }
log.Trace(errors.New("opening connection to ", destination).Path("Proxy", "Freedom")) log.Trace(newError("opening connection to ", destination))
input := outboundRay.OutboundInput() input := outboundRay.OutboundInput()
output := outboundRay.OutboundOutput() output := outboundRay.OutboundOutput()
@ -101,7 +101,7 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
return nil return nil
}) })
if err != nil { if err != nil {
return errors.New("failed to open connection to ", destination).Base(err).Path("Proxy", "Freedom") return newError("failed to open connection to ", destination).Base(err)
} }
defer conn.Close() defer conn.Close()
@ -132,7 +132,7 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil { if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil {
input.CloseError() input.CloseError()
output.CloseError() output.CloseError()
return errors.New("connection ends").Base(err).Path("Proxy", "Freedom") return newError("connection ends").Base(err)
} }
runtime.KeepAlive(timer) runtime.KeepAlive(timer)

View File

@ -4,7 +4,6 @@ import (
"context" "context"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/errors"
) )
func CreateInboundHandler(ctx context.Context, config interface{}) (Inbound, error) { func CreateInboundHandler(ctx context.Context, config interface{}) (Inbound, error) {
@ -16,7 +15,7 @@ func CreateInboundHandler(ctx context.Context, config interface{}) (Inbound, err
case Inbound: case Inbound:
return h, nil return h, nil
default: default:
return nil, errors.New("Proxy: Not a InboundHandler.") return nil, newError("Proxy: Not a InboundHandler.")
} }
} }
@ -29,6 +28,6 @@ func CreateOutboundHandler(ctx context.Context, config interface{}) (Outbound, e
case Outbound: case Outbound:
return h, nil return h, nil
default: default:
return nil, errors.New("Proxy: Not a OutboundHandler.") return nil, newError("Proxy: Not a OutboundHandler.")
} }
} }

View File

@ -0,0 +1,5 @@
package http
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("Proxy", "HTTP") }

3
proxy/http/http.go Normal file
View File

@ -0,0 +1,3 @@
package http
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg http -path Proxy,HTTP

View File

@ -31,7 +31,7 @@ type Server struct {
func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) { func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
space := app.SpaceFromContext(ctx) space := app.SpaceFromContext(ctx)
if space == nil { if space == nil {
return nil, errors.New("no space in context.").Path("Proxy", "HTTP", "Server") return nil, newError("no space in context.")
} }
s := &Server{ s := &Server{
config: config, config: config,
@ -75,11 +75,11 @@ func (s *Server) Process(ctx context.Context, network v2net.Network, conn intern
request, err := http.ReadRequest(reader) request, err := http.ReadRequest(reader)
if err != nil { if err != nil {
if errors.Cause(err) != io.EOF { if errors.Cause(err) != io.EOF {
log.Trace(errors.New("failed to read http request").Base(err).AtWarning().Path("Proxy", "HTTP", "Server")) log.Trace(newError("failed to read http request").Base(err).AtWarning())
} }
return err return err
} }
log.Trace(errors.New("request to Method [", request.Method, "] Host [", request.Host, "] with URL [", request.URL, "]").Path("Proxy", "HTTP", "Server")) log.Trace(newError("request to Method [", request.Method, "] Host [", request.Host, "] with URL [", request.URL, "]"))
conn.SetReadDeadline(time.Time{}) conn.SetReadDeadline(time.Time{})
defaultPort := v2net.Port(80) defaultPort := v2net.Port(80)
@ -92,7 +92,7 @@ func (s *Server) Process(ctx context.Context, network v2net.Network, conn intern
} }
dest, err := parseHost(host, defaultPort) dest, err := parseHost(host, defaultPort)
if err != nil { if err != nil {
return errors.New("malformed proxy host: ", host).AtWarning().Base(err).Path("Proxy", "HTTP", "Server") return newError("malformed proxy host: ", host).AtWarning().Base(err)
} }
log.Access(conn.RemoteAddr(), request.URL, log.AccessAccepted, "") log.Access(conn.RemoteAddr(), request.URL, log.AccessAccepted, "")
@ -116,7 +116,7 @@ func (s *Server) handleConnect(ctx context.Context, request *http.Request, reade
Close: false, Close: false,
} }
if err := response.Write(writer); err != nil { if err := response.Write(writer); err != nil {
return errors.New("failed to write back OK response").Base(err).Path("Proxy", "HTTP", "Server") return newError("failed to write back OK response").Base(err)
} }
timeout := time.Second * time.Duration(s.config.Timeout) timeout := time.Second * time.Duration(s.config.Timeout)
@ -150,7 +150,7 @@ func (s *Server) handleConnect(ctx context.Context, request *http.Request, reade
if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil { if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil {
ray.InboundInput().CloseError() ray.InboundInput().CloseError()
ray.InboundOutput().CloseError() ray.InboundOutput().CloseError()
return errors.New("connection ends").Base(err).Path("Proxy", "HTTP", "Server") return newError("connection ends").Base(err)
} }
runtime.KeepAlive(timer) runtime.KeepAlive(timer)
@ -232,7 +232,7 @@ func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, rea
responseReader := bufio.NewReader(buf.ToBytesReader(ray.InboundOutput())) responseReader := bufio.NewReader(buf.ToBytesReader(ray.InboundOutput()))
response, err := http.ReadResponse(responseReader, request) response, err := http.ReadResponse(responseReader, request)
if err != nil { if err != nil {
log.Trace(errors.New("failed to read response").Base(err).AtWarning().Path("Proxy", "HTTP", "Server")) log.Trace(newError("failed to read response").Base(err).AtWarning())
response = generateResponse(503, "Service Unavailable") response = generateResponse(503, "Service Unavailable")
} }
responseWriter := buf.NewBufferedWriter(writer) responseWriter := buf.NewBufferedWriter(writer)
@ -249,7 +249,7 @@ func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, rea
if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil { if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil {
input.CloseError() input.CloseError()
output.CloseError() output.CloseError()
return errors.New("connection ends").Base(err).Path("Proxy", "HTTP", "Server") return newError("connection ends").Base(err)
} }
return nil return nil

View File

@ -5,6 +5,8 @@
// 2. Register a config creator through common.RegisterConfig. // 2. Register a config creator through common.RegisterConfig.
package proxy package proxy
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg proxy -path Proxy
import ( import (
"context" "context"

View File

@ -6,7 +6,6 @@ import (
"crypto/md5" "crypto/md5"
"v2ray.com/core/common/crypto" "v2ray.com/core/common/crypto"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/protocol" "v2ray.com/core/common/protocol"
) )
@ -34,14 +33,14 @@ func (v *Account) GetCipher() (Cipher, error) {
case CipherType_CHACHA20_IETF: case CipherType_CHACHA20_IETF:
return &ChaCha20{IVBytes: 12}, nil return &ChaCha20{IVBytes: 12}, nil
default: default:
return nil, errors.New("Unsupported cipher.") return nil, newError("Unsupported cipher.")
} }
} }
func (v *Account) AsAccount() (protocol.Account, error) { func (v *Account) AsAccount() (protocol.Account, error) {
cipher, err := v.GetCipher() cipher, err := v.GetCipher()
if err != nil { if err != nil {
return nil, errors.New("failed to get cipher").Base(err).Path("Shadowsocks", "Account") return nil, newError("failed to get cipher").Base(err)
} }
return &ShadowsocksAccount{ return &ShadowsocksAccount{
Cipher: cipher, Cipher: cipher,

View File

@ -7,7 +7,6 @@ import (
"io" "io"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/serial" "v2ray.com/core/common/serial"
) )
@ -97,7 +96,7 @@ func (v *ChunkReader) Read() (*buf.Buffer, error) {
v.auth.Authenticate(payload)(actualAuthBytes) v.auth.Authenticate(payload)(actualAuthBytes)
if !bytes.Equal(authBytes, actualAuthBytes) { if !bytes.Equal(authBytes, actualAuthBytes) {
buffer.Release() buffer.Release()
return nil, errors.New("invalid auth").Path("Proxy", "Shadowsocks", "ChunkReader") return nil, newError("invalid auth")
} }
buffer.SliceFrom(AuthSize) buffer.SliceFrom(AuthSize)

View File

@ -7,7 +7,6 @@ import (
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/crypto" "v2ray.com/core/common/crypto"
"v2ray.com/core/common/errors"
v2net "v2ray.com/core/common/net" v2net "v2ray.com/core/common/net"
"v2ray.com/core/common/protocol" "v2ray.com/core/common/protocol"
"v2ray.com/core/common/serial" "v2ray.com/core/common/serial"
@ -25,7 +24,7 @@ const (
func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHeader, buf.Reader, error) { func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHeader, buf.Reader, error) {
rawAccount, err := user.GetTypedAccount() rawAccount, err := user.GetTypedAccount()
if err != nil { if err != nil {
return nil, nil, errors.New("failed to parse account").Path("Shadowsocks", "TCP").Base(err) return nil, nil, newError("failed to parse account").Base(err)
} }
account := rawAccount.(*ShadowsocksAccount) account := rawAccount.(*ShadowsocksAccount)
@ -35,14 +34,14 @@ func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHea
ivLen := account.Cipher.IVSize() ivLen := account.Cipher.IVSize()
err = buffer.AppendSupplier(buf.ReadFullFrom(reader, ivLen)) err = buffer.AppendSupplier(buf.ReadFullFrom(reader, ivLen))
if err != nil { if err != nil {
return nil, nil, errors.New("failed to read IV").Path("Shadowsocks", "TCP").Base(err) return nil, nil, newError("failed to read IV").Base(err)
} }
iv := append([]byte(nil), buffer.BytesTo(ivLen)...) iv := append([]byte(nil), buffer.BytesTo(ivLen)...)
stream, err := account.Cipher.NewDecodingStream(account.Key, iv) stream, err := account.Cipher.NewDecodingStream(account.Key, iv)
if err != nil { if err != nil {
return nil, nil, errors.New("failed to initialize decoding stream").Path("Shadowsocks", "TCP").Base(err) return nil, nil, newError("failed to initialize decoding stream").Base(err)
} }
reader = crypto.NewCryptionReader(stream, reader) reader = crypto.NewCryptionReader(stream, reader)
@ -56,7 +55,7 @@ func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHea
buffer.Clear() buffer.Clear()
err = buffer.AppendSupplier(buf.ReadFullFrom(reader, 1)) err = buffer.AppendSupplier(buf.ReadFullFrom(reader, 1))
if err != nil { if err != nil {
return nil, nil, errors.New("failed to read address type").Path("Shadowsocks", "TCP").Base(err) return nil, nil, newError("failed to read address type").Base(err)
} }
addrType := (buffer.Byte(0) & 0x0F) addrType := (buffer.Byte(0) & 0x0F)
@ -65,35 +64,35 @@ func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHea
} }
if request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Disabled { if request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Disabled {
return nil, nil, errors.New("rejecting connection with OTA enabled, while server disables OTA").Path("Shadowsocks", "TCP") return nil, nil, newError("rejecting connection with OTA enabled, while server disables OTA")
} }
if !request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Enabled { if !request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Enabled {
return nil, nil, errors.New("rejecting connection with OTA disabled, while server enables OTA").Path("Shadowsocks", "TCP") return nil, nil, newError("rejecting connection with OTA disabled, while server enables OTA")
} }
switch addrType { switch addrType {
case AddrTypeIPv4: case AddrTypeIPv4:
err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 4)) err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 4))
if err != nil { if err != nil {
return nil, nil, errors.New("failed to read IPv4 address").Path("Shadowsocks", "TCP").Base(err) return nil, nil, newError("failed to read IPv4 address").Base(err)
} }
request.Address = v2net.IPAddress(buffer.BytesFrom(-4)) request.Address = v2net.IPAddress(buffer.BytesFrom(-4))
case AddrTypeIPv6: case AddrTypeIPv6:
err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 16)) err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 16))
if err != nil { if err != nil {
return nil, nil, errors.New("failed to read IPv6 address").Path("Shadowsocks", "TCP").Base(err) return nil, nil, newError("failed to read IPv6 address").Base(err)
} }
request.Address = v2net.IPAddress(buffer.BytesFrom(-16)) request.Address = v2net.IPAddress(buffer.BytesFrom(-16))
case AddrTypeDomain: case AddrTypeDomain:
err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 1)) err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 1))
if err != nil { if err != nil {
return nil, nil, errors.New("failed to read domain lenth.").Path("Shadowsocks", "TCP").Base(err) return nil, nil, newError("failed to read domain lenth.").Base(err)
} }
domainLength := int(buffer.BytesFrom(-1)[0]) domainLength := int(buffer.BytesFrom(-1)[0])
err = buffer.AppendSupplier(buf.ReadFullFrom(reader, domainLength)) err = buffer.AppendSupplier(buf.ReadFullFrom(reader, domainLength))
if err != nil { if err != nil {
return nil, nil, errors.New("failed to read domain").Path("Shadowsocks", "TCP").Base(err) return nil, nil, newError("failed to read domain").Base(err)
} }
request.Address = v2net.DomainAddress(string(buffer.BytesFrom(-domainLength))) request.Address = v2net.DomainAddress(string(buffer.BytesFrom(-domainLength)))
default: default:
@ -102,7 +101,7 @@ func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHea
err = buffer.AppendSupplier(buf.ReadFullFrom(reader, 2)) err = buffer.AppendSupplier(buf.ReadFullFrom(reader, 2))
if err != nil { if err != nil {
return nil, nil, errors.New("failed to read port").Path("Shadowsocks", "TCP").Base(err) return nil, nil, newError("failed to read port").Base(err)
} }
request.Port = v2net.PortFromBytes(buffer.BytesFrom(-2)) request.Port = v2net.PortFromBytes(buffer.BytesFrom(-2))
@ -112,16 +111,16 @@ func ReadTCPSession(user *protocol.User, reader io.Reader) (*protocol.RequestHea
err := buffer.AppendSupplier(buf.ReadFullFrom(reader, AuthSize)) err := buffer.AppendSupplier(buf.ReadFullFrom(reader, AuthSize))
if err != nil { if err != nil {
return nil, nil, errors.New("Failed to read OTA").Path("Shadowsocks", "TCP").Base(err) return nil, nil, newError("Failed to read OTA").Base(err)
} }
if !bytes.Equal(actualAuth, buffer.BytesFrom(-AuthSize)) { if !bytes.Equal(actualAuth, buffer.BytesFrom(-AuthSize)) {
return nil, nil, errors.New("invalid OTA").Path("Shadowsocks", "TCP") return nil, nil, newError("invalid OTA")
} }
} }
if request.Address == nil { if request.Address == nil {
return nil, nil, errors.New("invalid remote address.").Path("Shadowsocks", "TCP") return nil, nil, newError("invalid remote address.")
} }
var chunkReader buf.Reader var chunkReader buf.Reader
@ -138,7 +137,7 @@ func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Wri
user := request.User user := request.User
rawAccount, err := user.GetTypedAccount() rawAccount, err := user.GetTypedAccount()
if err != nil { if err != nil {
return nil, errors.New("failed to parse account").Path("Shadowsocks", "TCP").Base(err) return nil, newError("failed to parse account").Base(err)
} }
account := rawAccount.(*ShadowsocksAccount) account := rawAccount.(*ShadowsocksAccount)
@ -146,12 +145,12 @@ func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Wri
rand.Read(iv) rand.Read(iv)
_, err = writer.Write(iv) _, err = writer.Write(iv)
if err != nil { if err != nil {
return nil, errors.New("failed to write IV").Path("Shadowsocks", "TCP") return nil, newError("failed to write IV")
} }
stream, err := account.Cipher.NewEncodingStream(account.Key, iv) stream, err := account.Cipher.NewEncodingStream(account.Key, iv)
if err != nil { if err != nil {
return nil, errors.New("failed to create encoding stream").Path("Shadowsocks", "TCP").Base(err) return nil, newError("failed to create encoding stream").Base(err)
} }
writer = crypto.NewCryptionWriter(stream, writer) writer = crypto.NewCryptionWriter(stream, writer)
@ -169,7 +168,7 @@ func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Wri
header.AppendBytes(AddrTypeDomain, byte(len(request.Address.Domain()))) header.AppendBytes(AddrTypeDomain, byte(len(request.Address.Domain())))
header.Append([]byte(request.Address.Domain())) header.Append([]byte(request.Address.Domain()))
default: default:
return nil, errors.New("Shadowsocks|TCP: Unsupported address type: ", request.Address.Family()) return nil, newError("Shadowsocks|TCP: Unsupported address type: ", request.Address.Family())
} }
header.AppendSupplier(serial.WriteUint16(uint16(request.Port))) header.AppendSupplier(serial.WriteUint16(uint16(request.Port)))
@ -183,7 +182,7 @@ func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Wri
_, err = writer.Write(header.Bytes()) _, err = writer.Write(header.Bytes())
if err != nil { if err != nil {
return nil, errors.New("Shadowsocks|TCP: Failed to write header.").Base(err) return nil, newError("Shadowsocks|TCP: Failed to write header.").Base(err)
} }
var chunkWriter buf.Writer var chunkWriter buf.Writer
@ -199,19 +198,19 @@ func WriteTCPRequest(request *protocol.RequestHeader, writer io.Writer) (buf.Wri
func ReadTCPResponse(user *protocol.User, reader io.Reader) (buf.Reader, error) { func ReadTCPResponse(user *protocol.User, reader io.Reader) (buf.Reader, error) {
rawAccount, err := user.GetTypedAccount() rawAccount, err := user.GetTypedAccount()
if err != nil { if err != nil {
return nil, errors.New("Shadowsocks|TCP: Failed to parse account.").Base(err) return nil, newError("Shadowsocks|TCP: Failed to parse account.").Base(err)
} }
account := rawAccount.(*ShadowsocksAccount) account := rawAccount.(*ShadowsocksAccount)
iv := make([]byte, account.Cipher.IVSize()) iv := make([]byte, account.Cipher.IVSize())
_, err = io.ReadFull(reader, iv) _, err = io.ReadFull(reader, iv)
if err != nil { if err != nil {
return nil, errors.New("Shadowsocks|TCP: Failed to read IV.").Base(err) return nil, newError("Shadowsocks|TCP: Failed to read IV.").Base(err)
} }
stream, err := account.Cipher.NewDecodingStream(account.Key, iv) stream, err := account.Cipher.NewDecodingStream(account.Key, iv)
if err != nil { if err != nil {
return nil, errors.New("Shadowsocks|TCP: Failed to initialize decoding stream.").Base(err) return nil, newError("Shadowsocks|TCP: Failed to initialize decoding stream.").Base(err)
} }
return buf.NewReader(crypto.NewCryptionReader(stream, reader)), nil return buf.NewReader(crypto.NewCryptionReader(stream, reader)), nil
} }
@ -220,7 +219,7 @@ func WriteTCPResponse(request *protocol.RequestHeader, writer io.Writer) (buf.Wr
user := request.User user := request.User
rawAccount, err := user.GetTypedAccount() rawAccount, err := user.GetTypedAccount()
if err != nil { if err != nil {
return nil, errors.New("Shadowsocks|TCP: Failed to parse account.").Base(err) return nil, newError("Shadowsocks|TCP: Failed to parse account.").Base(err)
} }
account := rawAccount.(*ShadowsocksAccount) account := rawAccount.(*ShadowsocksAccount)
@ -228,12 +227,12 @@ func WriteTCPResponse(request *protocol.RequestHeader, writer io.Writer) (buf.Wr
rand.Read(iv) rand.Read(iv)
_, err = writer.Write(iv) _, err = writer.Write(iv)
if err != nil { if err != nil {
return nil, errors.New("Shadowsocks|TCP: Failed to write IV.").Base(err) return nil, newError("Shadowsocks|TCP: Failed to write IV.").Base(err)
} }
stream, err := account.Cipher.NewEncodingStream(account.Key, iv) stream, err := account.Cipher.NewEncodingStream(account.Key, iv)
if err != nil { if err != nil {
return nil, errors.New("Shadowsocks|TCP: Failed to create encoding stream.").Base(err) return nil, newError("Shadowsocks|TCP: Failed to create encoding stream.").Base(err)
} }
return buf.NewWriter(crypto.NewCryptionWriter(stream, writer)), nil return buf.NewWriter(crypto.NewCryptionWriter(stream, writer)), nil
@ -243,7 +242,7 @@ func EncodeUDPPacket(request *protocol.RequestHeader, payload *buf.Buffer) (*buf
user := request.User user := request.User
rawAccount, err := user.GetTypedAccount() rawAccount, err := user.GetTypedAccount()
if err != nil { if err != nil {
return nil, errors.New("Shadowsocks|UDP: Failed to parse account.").Base(err) return nil, newError("Shadowsocks|UDP: Failed to parse account.").Base(err)
} }
account := rawAccount.(*ShadowsocksAccount) account := rawAccount.(*ShadowsocksAccount)
@ -263,7 +262,7 @@ func EncodeUDPPacket(request *protocol.RequestHeader, payload *buf.Buffer) (*buf
buffer.AppendBytes(AddrTypeDomain, byte(len(request.Address.Domain()))) buffer.AppendBytes(AddrTypeDomain, byte(len(request.Address.Domain())))
buffer.Append([]byte(request.Address.Domain())) buffer.Append([]byte(request.Address.Domain()))
default: default:
return nil, errors.New("Shadowsocks|UDP: Unsupported address type: ", request.Address.Family()) return nil, newError("Shadowsocks|UDP: Unsupported address type: ", request.Address.Family())
} }
buffer.AppendSupplier(serial.WriteUint16(uint16(request.Port))) buffer.AppendSupplier(serial.WriteUint16(uint16(request.Port)))
@ -278,7 +277,7 @@ func EncodeUDPPacket(request *protocol.RequestHeader, payload *buf.Buffer) (*buf
stream, err := account.Cipher.NewEncodingStream(account.Key, iv) stream, err := account.Cipher.NewEncodingStream(account.Key, iv)
if err != nil { if err != nil {
return nil, errors.New("Shadowsocks|TCP: Failed to create encoding stream.").Base(err) return nil, newError("Shadowsocks|TCP: Failed to create encoding stream.").Base(err)
} }
stream.XORKeyStream(buffer.BytesFrom(ivLen), buffer.BytesFrom(ivLen)) stream.XORKeyStream(buffer.BytesFrom(ivLen), buffer.BytesFrom(ivLen))
@ -288,7 +287,7 @@ func EncodeUDPPacket(request *protocol.RequestHeader, payload *buf.Buffer) (*buf
func DecodeUDPPacket(user *protocol.User, payload *buf.Buffer) (*protocol.RequestHeader, *buf.Buffer, error) { func DecodeUDPPacket(user *protocol.User, payload *buf.Buffer) (*protocol.RequestHeader, *buf.Buffer, error) {
rawAccount, err := user.GetTypedAccount() rawAccount, err := user.GetTypedAccount()
if err != nil { if err != nil {
return nil, nil, errors.New("Shadowsocks|UDP: Failed to parse account.").Base(err) return nil, nil, newError("Shadowsocks|UDP: Failed to parse account.").Base(err)
} }
account := rawAccount.(*ShadowsocksAccount) account := rawAccount.(*ShadowsocksAccount)
@ -298,7 +297,7 @@ func DecodeUDPPacket(user *protocol.User, payload *buf.Buffer) (*protocol.Reques
stream, err := account.Cipher.NewDecodingStream(account.Key, iv) stream, err := account.Cipher.NewDecodingStream(account.Key, iv)
if err != nil { if err != nil {
return nil, nil, errors.New("Shadowsocks|UDP: Failed to initialize decoding stream.").Base(err) return nil, nil, newError("Shadowsocks|UDP: Failed to initialize decoding stream.").Base(err)
} }
stream.XORKeyStream(payload.Bytes(), payload.Bytes()) stream.XORKeyStream(payload.Bytes(), payload.Bytes())
@ -315,11 +314,11 @@ func DecodeUDPPacket(user *protocol.User, payload *buf.Buffer) (*protocol.Reques
} }
if request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Disabled { if request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Disabled {
return nil, nil, errors.New("Shadowsocks|UDP: Rejecting packet with OTA enabled, while server disables OTA.") return nil, nil, newError("Shadowsocks|UDP: Rejecting packet with OTA enabled, while server disables OTA.")
} }
if !request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Enabled { if !request.Option.Has(RequestOptionOneTimeAuth) && account.OneTimeAuth == Account_Enabled {
return nil, nil, errors.New("Shadowsocks|UDP: Rejecting packet with OTA disabled, while server enables OTA.") return nil, nil, newError("Shadowsocks|UDP: Rejecting packet with OTA disabled, while server enables OTA.")
} }
if request.Option.Has(RequestOptionOneTimeAuth) { if request.Option.Has(RequestOptionOneTimeAuth) {
@ -329,7 +328,7 @@ func DecodeUDPPacket(user *protocol.User, payload *buf.Buffer) (*protocol.Reques
actualAuth := make([]byte, AuthSize) actualAuth := make([]byte, AuthSize)
authenticator.Authenticate(payload.BytesTo(payloadLen))(actualAuth) authenticator.Authenticate(payload.BytesTo(payloadLen))(actualAuth)
if !bytes.Equal(actualAuth, authBytes) { if !bytes.Equal(actualAuth, authBytes) {
return nil, nil, errors.New("Shadowsocks|UDP: Invalid OTA.") return nil, nil, newError("Shadowsocks|UDP: Invalid OTA.")
} }
payload.Slice(0, payloadLen) payload.Slice(0, payloadLen)
@ -349,7 +348,7 @@ func DecodeUDPPacket(user *protocol.User, payload *buf.Buffer) (*protocol.Reques
request.Address = v2net.DomainAddress(string(payload.BytesRange(1, 1+domainLength))) request.Address = v2net.DomainAddress(string(payload.BytesRange(1, 1+domainLength)))
payload.SliceFrom(1 + domainLength) payload.SliceFrom(1 + domainLength)
default: default:
return nil, nil, errors.New("Shadowsocks|UDP: Unknown address type: ", addrType) return nil, nil, newError("Shadowsocks|UDP: Unknown address type: ", addrType)
} }
request.Port = v2net.PortFromBytes(payload.BytesTo(2)) request.Port = v2net.PortFromBytes(payload.BytesTo(2))

View File

@ -10,7 +10,6 @@ import (
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
"v2ray.com/core/common/protocol" "v2ray.com/core/common/protocol"
"v2ray.com/core/common/signal" "v2ray.com/core/common/signal"
@ -29,15 +28,15 @@ type Server struct {
func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) { func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
space := app.SpaceFromContext(ctx) space := app.SpaceFromContext(ctx)
if space == nil { if space == nil {
return nil, errors.New("no space in context").Path("Proxy", "Shadowsocks", "Server") return nil, newError("no space in context")
} }
if config.GetUser() == nil { if config.GetUser() == nil {
return nil, errors.New("user is not specified").Path("Proxy", "Shadowsocks", "Server") return nil, newError("user is not specified")
} }
rawAccount, err := config.User.GetTypedAccount() rawAccount, err := config.User.GetTypedAccount()
if err != nil { if err != nil {
return nil, errors.New("failed to get user account").Base(err).Path("Proxy", "Shadowsocks", "Server") return nil, newError("failed to get user account").Base(err)
} }
account := rawAccount.(*ShadowsocksAccount) account := rawAccount.(*ShadowsocksAccount)
@ -67,7 +66,7 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet
case net.Network_UDP: case net.Network_UDP:
return s.handlerUDPPayload(ctx, conn, dispatcher) return s.handlerUDPPayload(ctx, conn, dispatcher)
default: default:
return errors.New("unknown network: ", network).Path("Proxy", "Shadowsocks", "Server") return newError("unknown network: ", network)
} }
} }
@ -84,7 +83,7 @@ func (v *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
request, data, err := DecodeUDPPacket(v.user, payload) request, data, err := DecodeUDPPacket(v.user, payload)
if err != nil { if err != nil {
if source, ok := proxy.SourceFromContext(ctx); ok { if source, ok := proxy.SourceFromContext(ctx); ok {
log.Trace(errors.New("dropping invalid UDP packet from: ", source).Base(err).Path("Proxy", "Shadowsocks", "Server")) log.Trace(newError("dropping invalid UDP packet from: ", source).Base(err))
log.Access(source, "", log.AccessRejected, err) log.Access(source, "", log.AccessRejected, err)
} }
payload.Release() payload.Release()
@ -92,13 +91,13 @@ func (v *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
} }
if request.Option.Has(RequestOptionOneTimeAuth) && v.account.OneTimeAuth == Account_Disabled { if request.Option.Has(RequestOptionOneTimeAuth) && v.account.OneTimeAuth == Account_Disabled {
log.Trace(errors.New("client payload enables OTA but server doesn't allow it").Path("Proxy", "Shadowsocks", "Server")) log.Trace(newError("client payload enables OTA but server doesn't allow it"))
payload.Release() payload.Release()
continue continue
} }
if !request.Option.Has(RequestOptionOneTimeAuth) && v.account.OneTimeAuth == Account_Enabled { if !request.Option.Has(RequestOptionOneTimeAuth) && v.account.OneTimeAuth == Account_Enabled {
log.Trace(errors.New("client payload disables OTA but server forces it").Path("Proxy", "Shadowsocks", "Server")) log.Trace(newError("client payload disables OTA but server forces it"))
payload.Release() payload.Release()
continue continue
} }
@ -107,7 +106,7 @@ func (v *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
if source, ok := proxy.SourceFromContext(ctx); ok { if source, ok := proxy.SourceFromContext(ctx); ok {
log.Access(source, dest, log.AccessAccepted, "") log.Access(source, dest, log.AccessAccepted, "")
} }
log.Trace(errors.New("tunnelling request to ", dest).Path("Proxy", "Shadowsocks", "Server")) log.Trace(newError("tunnelling request to ", dest))
ctx = protocol.ContextWithUser(ctx, request.User) ctx = protocol.ContextWithUser(ctx, request.User)
udpServer.Dispatch(ctx, dest, data, func(payload *buf.Buffer) { udpServer.Dispatch(ctx, dest, data, func(payload *buf.Buffer) {
@ -115,7 +114,7 @@ func (v *Server) handlerUDPPayload(ctx context.Context, conn internet.Connection
data, err := EncodeUDPPacket(request, payload) data, err := EncodeUDPPacket(request, payload)
if err != nil { if err != nil {
log.Trace(errors.New("failed to encode UDP packet").Base(err).Path("Proxy", "Shadowsocks", "Server").AtWarning()) log.Trace(newError("failed to encode UDP packet").Base(err).AtWarning())
return return
} }
defer data.Release() defer data.Release()
@ -133,7 +132,7 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
request, bodyReader, err := ReadTCPSession(s.user, bufferedReader) request, bodyReader, err := ReadTCPSession(s.user, bufferedReader)
if err != nil { if err != nil {
log.Access(conn.RemoteAddr(), "", log.AccessRejected, err) log.Access(conn.RemoteAddr(), "", log.AccessRejected, err)
return errors.New("failed to create request from: ", conn.RemoteAddr()).Base(err).Path("Proxy", "Shadowsocks", "Server") return newError("failed to create request from: ", conn.RemoteAddr()).Base(err)
} }
conn.SetReadDeadline(time.Time{}) conn.SetReadDeadline(time.Time{})
@ -141,7 +140,7 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
dest := request.Destination() dest := request.Destination()
log.Access(conn.RemoteAddr(), dest, log.AccessAccepted, "") log.Access(conn.RemoteAddr(), dest, log.AccessAccepted, "")
log.Trace(errors.New("tunnelling request to ", dest).Path("Proxy", "Shadowsocks", "Server")) log.Trace(newError("tunnelling request to ", dest))
ctx = protocol.ContextWithUser(ctx, request.User) ctx = protocol.ContextWithUser(ctx, request.User)
@ -156,7 +155,7 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
bufferedWriter := buf.NewBufferedWriter(conn) bufferedWriter := buf.NewBufferedWriter(conn)
responseWriter, err := WriteTCPResponse(request, bufferedWriter) responseWriter, err := WriteTCPResponse(request, bufferedWriter)
if err != nil { if err != nil {
return errors.New("failed to write response").Base(err).Path("Proxy", "Shadowsocks", "Server") return newError("failed to write response").Base(err)
} }
mergeReader := buf.NewMergingReader(ray.InboundOutput()) mergeReader := buf.NewMergingReader(ray.InboundOutput())
@ -174,7 +173,7 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
} }
if err := buf.PipeUntilEOF(timer, mergeReader, responseWriter); err != nil { if err := buf.PipeUntilEOF(timer, mergeReader, responseWriter); err != nil {
return errors.New("failed to transport all TCP response").Base(err).Path("Proxy", "Shadowsocks", "Server") return newError("failed to transport all TCP response").Base(err)
} }
return nil return nil
@ -184,7 +183,7 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
defer ray.InboundInput().Close() defer ray.InboundInput().Close()
if err := buf.PipeUntilEOF(timer, bodyReader, ray.InboundInput()); err != nil { if err := buf.PipeUntilEOF(timer, bodyReader, ray.InboundInput()); err != nil {
return errors.New("failed to transport all TCP request").Base(err).Path("Proxy", "Shadowsocks", "Server") return newError("failed to transport all TCP request").Base(err)
} }
return nil return nil
}) })
@ -192,7 +191,7 @@ func (s *Server) handleConnection(ctx context.Context, conn internet.Connection,
if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil { if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil {
ray.InboundInput().CloseError() ray.InboundInput().CloseError()
ray.InboundOutput().CloseError() ray.InboundOutput().CloseError()
return errors.New("connection ends").Base(err).Path("Proxy", "Shadowsocks", "Server") return newError("connection ends").Base(err)
} }
runtime.KeepAlive(timer) runtime.KeepAlive(timer)

View File

@ -7,7 +7,6 @@ import (
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
"v2ray.com/core/common/protocol" "v2ray.com/core/common/protocol"
"v2ray.com/core/common/retry" "v2ray.com/core/common/retry"
@ -36,7 +35,7 @@ func NewClient(ctx context.Context, config *ClientConfig) (*Client, error) {
func (c *Client) Process(ctx context.Context, ray ray.OutboundRay, dialer proxy.Dialer) error { func (c *Client) Process(ctx context.Context, ray ray.OutboundRay, dialer proxy.Dialer) error {
destination, ok := proxy.TargetFromContext(ctx) destination, ok := proxy.TargetFromContext(ctx)
if !ok { if !ok {
return errors.New("target not specified.").Path("Proxy", "Socks", "Client") return newError("target not specified.")
} }
var server *protocol.ServerSpec var server *protocol.ServerSpec
@ -55,7 +54,7 @@ func (c *Client) Process(ctx context.Context, ray ray.OutboundRay, dialer proxy.
}) })
if err != nil { if err != nil {
return errors.New("failed to find an available destination").Base(err).Path("Proxy", "Socks", "Client") return newError("failed to find an available destination").Base(err)
} }
defer conn.Close() defer conn.Close()
@ -77,7 +76,7 @@ func (c *Client) Process(ctx context.Context, ray ray.OutboundRay, dialer proxy.
udpRequest, err := ClientHandshake(request, conn, conn) udpRequest, err := ClientHandshake(request, conn, conn)
if err != nil { if err != nil {
return errors.New("failed to establish connection to server").AtWarning().Base(err).Path("Proxy", "Socks", "Client") return newError("failed to establish connection to server").AtWarning().Base(err)
} }
ctx, timer := signal.CancelAfterInactivity(ctx, time.Minute*2) ctx, timer := signal.CancelAfterInactivity(ctx, time.Minute*2)
@ -95,7 +94,7 @@ func (c *Client) Process(ctx context.Context, ray ray.OutboundRay, dialer proxy.
} else if request.Command == protocol.RequestCommandUDP { } else if request.Command == protocol.RequestCommandUDP {
udpConn, err := dialer.Dial(ctx, udpRequest.Destination()) udpConn, err := dialer.Dial(ctx, udpRequest.Destination())
if err != nil { if err != nil {
return errors.New("failed to create UDP connection").Base(err).Path("Proxy", "Socks", "Client") return newError("failed to create UDP connection").Base(err)
} }
defer udpConn.Close() defer udpConn.Close()
requestFunc = func() error { requestFunc = func() error {
@ -111,7 +110,7 @@ func (c *Client) Process(ctx context.Context, ray ray.OutboundRay, dialer proxy.
requestDone := signal.ExecuteAsync(requestFunc) requestDone := signal.ExecuteAsync(requestFunc)
responseDone := signal.ExecuteAsync(responseFunc) responseDone := signal.ExecuteAsync(responseFunc)
if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil { if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil {
return errors.New("connection ends").Base(err).Path("Proxy", "Socks", "Client") return newError("connection ends").Base(err)
} }
runtime.KeepAlive(timer) runtime.KeepAlive(timer)

View File

@ -0,0 +1,7 @@
package socks
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).Path("Proxy", "Socks")
}

View File

@ -4,7 +4,6 @@ import (
"io" "io"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/errors"
v2net "v2ray.com/core/common/net" v2net "v2ray.com/core/common/net"
"v2ray.com/core/common/protocol" "v2ray.com/core/common/protocol"
"v2ray.com/core/common/serial" "v2ray.com/core/common/serial"
@ -44,13 +43,13 @@ func (s *ServerSession) Handshake(reader io.Reader, writer io.Writer) (*protocol
request := new(protocol.RequestHeader) request := new(protocol.RequestHeader)
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil { if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil {
return nil, errors.New("insufficient header").Base(err).Path("Socks", "Server") return nil, newError("insufficient header").Base(err)
} }
version := buffer.Byte(0) version := buffer.Byte(0)
if version == socks4Version { if version == socks4Version {
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 6)); err != nil { if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 6)); err != nil {
return nil, errors.New("insufficient header").Base(err).Path("Socks", "Server") return nil, newError("insufficient header").Base(err)
} }
port := v2net.PortFromBytes(buffer.BytesRange(2, 4)) port := v2net.PortFromBytes(buffer.BytesRange(2, 4))
address := v2net.IPAddress(buffer.BytesRange(4, 8)) address := v2net.IPAddress(buffer.BytesRange(4, 8))
@ -61,7 +60,7 @@ func (s *ServerSession) Handshake(reader io.Reader, writer io.Writer) (*protocol
if address.IP()[0] == 0x00 { if address.IP()[0] == 0x00 {
domain, err := readUntilNull(reader) domain, err := readUntilNull(reader)
if err != nil { if err != nil {
return nil, errors.New("failed to read domain for socks 4a").Base(err).Path("Socks", "Server") return nil, newError("failed to read domain for socks 4a").Base(err)
} }
address = v2net.DomainAddress(domain) address = v2net.DomainAddress(domain)
} }
@ -78,14 +77,14 @@ func (s *ServerSession) Handshake(reader io.Reader, writer io.Writer) (*protocol
return request, nil return request, nil
default: default:
writeSocks4Response(writer, socks4RequestRejected, v2net.AnyIP, v2net.Port(0)) writeSocks4Response(writer, socks4RequestRejected, v2net.AnyIP, v2net.Port(0))
return nil, errors.New("Socks|Server: Unsupported command: ", buffer.Byte(1)) return nil, newError("Socks|Server: Unsupported command: ", buffer.Byte(1))
} }
} }
if version == socks5Version { if version == socks5Version {
nMethod := int(buffer.Byte(1)) nMethod := int(buffer.Byte(1))
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, nMethod)); err != nil { if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, nMethod)); err != nil {
return nil, errors.New("failed to read auth methods").Base(err).Path("Socks", "Server") return nil, newError("failed to read auth methods").Base(err)
} }
var expectedAuth byte = authNotRequired var expectedAuth byte = authNotRequired
@ -95,37 +94,37 @@ func (s *ServerSession) Handshake(reader io.Reader, writer io.Writer) (*protocol
if !hasAuthMethod(expectedAuth, buffer.BytesRange(2, 2+nMethod)) { if !hasAuthMethod(expectedAuth, buffer.BytesRange(2, 2+nMethod)) {
writeSocks5AuthenticationResponse(writer, socks5Version, authNoMatchingMethod) writeSocks5AuthenticationResponse(writer, socks5Version, authNoMatchingMethod)
return nil, errors.New("no matching auth method").Path("Socks", "Server") return nil, newError("no matching auth method")
} }
if err := writeSocks5AuthenticationResponse(writer, socks5Version, expectedAuth); err != nil { if err := writeSocks5AuthenticationResponse(writer, socks5Version, expectedAuth); err != nil {
return nil, errors.New("failed to write auth response").Base(err).Path("Socks", "Server") return nil, newError("failed to write auth response").Base(err)
} }
if expectedAuth == authPassword { if expectedAuth == authPassword {
username, password, err := readUsernamePassword(reader) username, password, err := readUsernamePassword(reader)
if err != nil { if err != nil {
return nil, errors.New("failed to read username and password for authentication").Base(err).Path("Socks", "Server") return nil, newError("failed to read username and password for authentication").Base(err)
} }
if !s.config.HasAccount(username, password) { if !s.config.HasAccount(username, password) {
writeSocks5AuthenticationResponse(writer, 0x01, 0xFF) writeSocks5AuthenticationResponse(writer, 0x01, 0xFF)
return nil, errors.New("invalid username or password").Path("Socks", "Server") return nil, newError("invalid username or password")
} }
if err := writeSocks5AuthenticationResponse(writer, 0x01, 0x00); err != nil { if err := writeSocks5AuthenticationResponse(writer, 0x01, 0x00); err != nil {
return nil, errors.New("failed to write auth response").Base(err).Path("Socks", "Server") return nil, newError("failed to write auth response").Base(err)
} }
} }
buffer.Clear() buffer.Clear()
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 4)); err != nil { if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 4)); err != nil {
return nil, errors.New("failed to read request").Base(err).Path("Socks", "Server") return nil, newError("failed to read request").Base(err)
} }
cmd := buffer.Byte(1) cmd := buffer.Byte(1)
if cmd == cmdTCPBind || (cmd == cmdUDPPort && !s.config.UdpEnabled) { if cmd == cmdTCPBind || (cmd == cmdUDPPort && !s.config.UdpEnabled) {
writeSocks5Response(writer, statusCmdNotSupport, v2net.AnyIP, v2net.Port(0)) writeSocks5Response(writer, statusCmdNotSupport, v2net.AnyIP, v2net.Port(0))
return nil, errors.New("unsupported command: ", cmd).Path("Socks", "Server") return nil, newError("unsupported command: ", cmd)
} }
switch cmd { switch cmd {
@ -161,7 +160,7 @@ func (s *ServerSession) Handshake(reader io.Reader, writer io.Writer) (*protocol
} }
request.Address = v2net.ParseAddress(string(buffer.BytesFrom(-domainLength))) request.Address = v2net.ParseAddress(string(buffer.BytesFrom(-domainLength)))
default: default:
return nil, errors.New("Unknown address type: ", addrType).Path("Socks", "Server") return nil, newError("Unknown address type: ", addrType)
} }
if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil { if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil {
@ -186,7 +185,7 @@ func (s *ServerSession) Handshake(reader io.Reader, writer io.Writer) (*protocol
return request, nil return request, nil
} }
return nil, errors.New("unknown Socks version: ", version).Path("Socks", "Server") return nil, newError("unknown Socks version: ", version)
} }
func readUsernamePassword(reader io.Reader) (string, string, error) { func readUsernamePassword(reader io.Reader) (string, string, error) {
@ -230,7 +229,7 @@ func readUntilNull(reader io.Reader) (string, error) {
} }
size++ size++
if size == 256 { if size == 256 {
return "", errors.New("buffer overrun").Path("Socks", "Server") return "", newError("buffer overrun")
} }
} }
} }
@ -284,7 +283,7 @@ func writeSocks4Response(writer io.Writer, errCode byte, address v2net.Address,
func DecodeUDPPacket(packet []byte) (*protocol.RequestHeader, []byte, error) { func DecodeUDPPacket(packet []byte) (*protocol.RequestHeader, []byte, error) {
if len(packet) < 5 { if len(packet) < 5 {
return nil, nil, errors.New("Socks|UDP: Insufficient length of packet.") return nil, nil, newError("Socks|UDP: Insufficient length of packet.")
} }
request := &protocol.RequestHeader{ request := &protocol.RequestHeader{
Version: socks5Version, Version: socks5Version,
@ -293,7 +292,7 @@ func DecodeUDPPacket(packet []byte) (*protocol.RequestHeader, []byte, error) {
// packet[0] and packet[1] are reserved // packet[0] and packet[1] are reserved
if packet[2] != 0 /* fragments */ { if packet[2] != 0 /* fragments */ {
return nil, nil, errors.New("Socks|UDP: Fragmented payload.") return nil, nil, newError("Socks|UDP: Fragmented payload.")
} }
addrType := packet[3] addrType := packet[3]
@ -302,7 +301,7 @@ func DecodeUDPPacket(packet []byte) (*protocol.RequestHeader, []byte, error) {
switch addrType { switch addrType {
case addrTypeIPv4: case addrTypeIPv4:
if len(packet) < 10 { if len(packet) < 10 {
return nil, nil, errors.New("Socks|UDP: Insufficient length of packet.") return nil, nil, newError("Socks|UDP: Insufficient length of packet.")
} }
ip := packet[4:8] ip := packet[4:8]
request.Port = v2net.PortFromBytes(packet[8:10]) request.Port = v2net.PortFromBytes(packet[8:10])
@ -310,7 +309,7 @@ func DecodeUDPPacket(packet []byte) (*protocol.RequestHeader, []byte, error) {
dataBegin = 10 dataBegin = 10
case addrTypeIPv6: case addrTypeIPv6:
if len(packet) < 22 { if len(packet) < 22 {
return nil, nil, errors.New("Socks|UDP: Insufficient length of packet.") return nil, nil, newError("Socks|UDP: Insufficient length of packet.")
} }
ip := packet[4:20] ip := packet[4:20]
request.Port = v2net.PortFromBytes(packet[20:22]) request.Port = v2net.PortFromBytes(packet[20:22])
@ -319,14 +318,14 @@ func DecodeUDPPacket(packet []byte) (*protocol.RequestHeader, []byte, error) {
case addrTypeDomain: case addrTypeDomain:
domainLength := int(packet[4]) domainLength := int(packet[4])
if len(packet) < 5+domainLength+2 { if len(packet) < 5+domainLength+2 {
return nil, nil, errors.New("Socks|UDP: Insufficient length of packet.") return nil, nil, newError("Socks|UDP: Insufficient length of packet.")
} }
domain := string(packet[5 : 5+domainLength]) domain := string(packet[5 : 5+domainLength])
request.Port = v2net.PortFromBytes(packet[5+domainLength : 5+domainLength+2]) request.Port = v2net.PortFromBytes(packet[5+domainLength : 5+domainLength+2])
request.Address = v2net.ParseAddress(domain) request.Address = v2net.ParseAddress(domain)
dataBegin = 5 + domainLength + 2 dataBegin = 5 + domainLength + 2
default: default:
return nil, nil, errors.New("Socks|UDP: Unknown address type ", addrType) return nil, nil, newError("Socks|UDP: Unknown address type ", addrType)
} }
return request, packet[dataBegin:], nil return request, packet[dataBegin:], nil
@ -400,10 +399,10 @@ func ClientHandshake(request *protocol.RequestHeader, reader io.Reader, writer i
} }
if b.Byte(0) != socks5Version { if b.Byte(0) != socks5Version {
return nil, errors.New("Socks|Client: Unexpected server version: ", b.Byte(0)).AtWarning() return nil, newError("Socks|Client: Unexpected server version: ", b.Byte(0)).AtWarning()
} }
if b.Byte(1) != authByte { if b.Byte(1) != authByte {
return nil, errors.New("Socks|Client: auth method not supported.").AtWarning() return nil, newError("Socks|Client: auth method not supported.").AtWarning()
} }
if authByte == authPassword { if authByte == authPassword {
@ -426,7 +425,7 @@ func ClientHandshake(request *protocol.RequestHeader, reader io.Reader, writer i
return nil, err return nil, err
} }
if b.Byte(1) != 0x00 { if b.Byte(1) != 0x00 {
return nil, errors.New("Socks|Client: Server rejects account: ", b.Byte(1)) return nil, newError("Socks|Client: Server rejects account: ", b.Byte(1))
} }
} }
@ -449,7 +448,7 @@ func ClientHandshake(request *protocol.RequestHeader, reader io.Reader, writer i
resp := b.Byte(1) resp := b.Byte(1)
if resp != 0x00 { if resp != 0x00 {
return nil, errors.New("Socks|Client: Server rejects request: ", resp) return nil, newError("Socks|Client: Server rejects request: ", resp)
} }
addrType := b.Byte(3) addrType := b.Byte(3)
@ -478,7 +477,7 @@ func ClientHandshake(request *protocol.RequestHeader, reader io.Reader, writer i
} }
address = v2net.DomainAddress(string(b.BytesFrom(-domainLength))) address = v2net.DomainAddress(string(b.BytesFrom(-domainLength)))
default: default:
return nil, errors.New("Socks|Server: Unknown address type: ", addrType) return nil, newError("Socks|Server: Unknown address type: ", addrType)
} }
if err := b.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil { if err := b.AppendSupplier(buf.ReadFullFrom(reader, 2)); err != nil {

View File

@ -11,7 +11,6 @@ import (
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
"v2ray.com/core/common/protocol" "v2ray.com/core/common/protocol"
"v2ray.com/core/common/signal" "v2ray.com/core/common/signal"
@ -29,7 +28,7 @@ type Server struct {
func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) { func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) {
space := app.SpaceFromContext(ctx) space := app.SpaceFromContext(ctx)
if space == nil { if space == nil {
return nil, errors.New("no space in context").AtWarning().Path("Proxy", "Socks", "Server") return nil, newError("no space in context").AtWarning()
} }
s := &Server{ s := &Server{
config: config, config: config,
@ -54,7 +53,7 @@ func (s *Server) Process(ctx context.Context, network net.Network, conn internet
case net.Network_UDP: case net.Network_UDP:
return s.handleUDPPayload(ctx, conn, dispatcher) return s.handleUDPPayload(ctx, conn, dispatcher)
default: default:
return errors.New("unknown network: ", network).Path("Proxy", "Socks", "Server") return newError("unknown network: ", network)
} }
} }
@ -64,7 +63,7 @@ func (s *Server) processTCP(ctx context.Context, conn internet.Connection, dispa
inboundDest, ok := proxy.InboundEntryPointFromContext(ctx) inboundDest, ok := proxy.InboundEntryPointFromContext(ctx)
if !ok { if !ok {
return errors.New("inbound entry point not specified").Path("Proxy", "Socks", "Server") return newError("inbound entry point not specified")
} }
session := &ServerSession{ session := &ServerSession{
config: s.config, config: s.config,
@ -76,14 +75,14 @@ func (s *Server) processTCP(ctx context.Context, conn internet.Connection, dispa
if source, ok := proxy.SourceFromContext(ctx); ok { if source, ok := proxy.SourceFromContext(ctx); ok {
log.Access(source, "", log.AccessRejected, err) log.Access(source, "", log.AccessRejected, err)
} }
log.Trace(errors.New("failed to read request").Base(err).Path("Proxy", "Socks", "Server")) log.Trace(newError("failed to read request").Base(err))
return err return err
} }
conn.SetReadDeadline(time.Time{}) conn.SetReadDeadline(time.Time{})
if request.Command == protocol.RequestCommandTCP { if request.Command == protocol.RequestCommandTCP {
dest := request.Destination() dest := request.Destination()
log.Trace(errors.New("TCP Connect request to ", dest).Path("Proxy", "Socks", "Server")) log.Trace(newError("TCP Connect request to ", dest))
if source, ok := proxy.SourceFromContext(ctx); ok { if source, ok := proxy.SourceFromContext(ctx); ok {
log.Access(source, dest, log.AccessAccepted, "") log.Access(source, dest, log.AccessAccepted, "")
} }
@ -127,7 +126,7 @@ func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writ
v2reader := buf.NewReader(reader) v2reader := buf.NewReader(reader)
if err := buf.PipeUntilEOF(timer, v2reader, input); err != nil { if err := buf.PipeUntilEOF(timer, v2reader, input); err != nil {
return errors.New("failed to transport all TCP request").Base(err).Path("Proxy", "Socks", "Server") return newError("failed to transport all TCP request").Base(err)
} }
return nil return nil
}) })
@ -135,7 +134,7 @@ func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writ
responseDone := signal.ExecuteAsync(func() error { responseDone := signal.ExecuteAsync(func() error {
v2writer := buf.NewWriter(writer) v2writer := buf.NewWriter(writer)
if err := buf.PipeUntilEOF(timer, output, v2writer); err != nil { if err := buf.PipeUntilEOF(timer, output, v2writer); err != nil {
return errors.New("failed to transport all TCP response").Base(err).Path("Proxy", "Socks", "Server") return newError("failed to transport all TCP response").Base(err)
} }
return nil return nil
}) })
@ -143,7 +142,7 @@ func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writ
if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil { if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil {
input.CloseError() input.CloseError()
output.CloseError() output.CloseError()
return errors.New("connection ends").Base(err).Path("Proxy", "Socks", "Server") return newError("connection ends").Base(err)
} }
runtime.KeepAlive(timer) runtime.KeepAlive(timer)
@ -155,7 +154,7 @@ func (v *Server) handleUDPPayload(ctx context.Context, conn internet.Connection,
udpServer := udp.NewDispatcher(dispatcher) udpServer := udp.NewDispatcher(dispatcher)
if source, ok := proxy.SourceFromContext(ctx); ok { if source, ok := proxy.SourceFromContext(ctx); ok {
log.Trace(errors.New("client UDP connection from ", source).Path("Proxy", "Socks", "Server")) log.Trace(newError("client UDP connection from ", source))
} }
reader := buf.NewReader(conn) reader := buf.NewReader(conn)
@ -167,7 +166,7 @@ func (v *Server) handleUDPPayload(ctx context.Context, conn internet.Connection,
request, data, err := DecodeUDPPacket(payload.Bytes()) request, data, err := DecodeUDPPacket(payload.Bytes())
if err != nil { if err != nil {
log.Trace(errors.New("failed to parse UDP request").Base(err).Path("Proxy", "Socks", "Server")) log.Trace(newError("failed to parse UDP request").Base(err))
continue continue
} }
@ -175,7 +174,7 @@ func (v *Server) handleUDPPayload(ctx context.Context, conn internet.Connection,
continue continue
} }
log.Trace(errors.New("send packet to ", request.Destination(), " with ", len(data), " bytes").Path("Proxy", "Socks", "Server").AtDebug()) log.Trace(newError("send packet to ", request.Destination(), " with ", len(data), " bytes").AtDebug())
if source, ok := proxy.SourceFromContext(ctx); ok { if source, ok := proxy.SourceFromContext(ctx); ok {
log.Access(source, request.Destination, log.AccessAccepted, "") log.Access(source, request.Destination, log.AccessAccepted, "")
} }
@ -185,7 +184,7 @@ func (v *Server) handleUDPPayload(ctx context.Context, conn internet.Connection,
udpServer.Dispatch(ctx, request.Destination(), dataBuf, func(payload *buf.Buffer) { udpServer.Dispatch(ctx, request.Destination(), dataBuf, func(payload *buf.Buffer) {
defer payload.Release() defer payload.Release()
log.Trace(errors.New("writing back UDP response with ", payload.Len(), " bytes").Path("Proxy", "Socks", "Server").AtDebug()) log.Trace(newError("writing back UDP response with ", payload.Len(), " bytes").AtDebug())
udpMessage := EncodeUDPPacket(request, payload.Bytes()) udpMessage := EncodeUDPPacket(request, payload.Bytes())
defer udpMessage.Release() defer udpMessage.Release()

View File

@ -1,2 +1,4 @@
// Package socks provides implements of Socks protocol 4, 4a and 5. // Package socks provides implements of Socks protocol 4, 4a and 5.
package socks package socks
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg socks -path Proxy,Socks

View File

@ -3,7 +3,6 @@ package vmess
import ( import (
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/common/dice" "v2ray.com/core/common/dice"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/protocol" "v2ray.com/core/common/protocol"
"v2ray.com/core/common/uuid" "v2ray.com/core/common/uuid"
) )
@ -33,7 +32,7 @@ func (v *InternalAccount) Equals(account protocol.Account) bool {
func (v *Account) AsAccount() (protocol.Account, error) { func (v *Account) AsAccount() (protocol.Account, error) {
id, err := uuid.ParseString(v.Id) id, err := uuid.ParseString(v.Id)
if err != nil { if err != nil {
log.Trace(errors.New("failed to parse ID").Path("VMess", "Account").Base(err).AtError()) log.Trace(newError("failed to parse ID").Base(err).AtError())
return nil, err return nil, err
} }
protoID := protocol.NewID(id) protoID := protocol.NewID(id)

View File

@ -4,7 +4,6 @@ import (
"crypto/md5" "crypto/md5"
"hash/fnv" "hash/fnv"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/serial" "v2ray.com/core/common/serial"
) )
@ -58,7 +57,7 @@ func (v *FnvAuthenticator) Seal(dst, nonce, plaintext, additionalData []byte) []
// Open implements AEAD.Open(). // Open implements AEAD.Open().
func (v *FnvAuthenticator) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) { func (v *FnvAuthenticator) Open(dst, nonce, ciphertext, additionalData []byte) ([]byte, error) {
if serial.BytesToUint32(ciphertext[:4]) != Authenticate(ciphertext[4:]) { if serial.BytesToUint32(ciphertext[:4]) != Authenticate(ciphertext[4:]) {
return dst, errors.New("invalid authentication").Path("Proxy", "VMess", "Encoding", "FnvAuthenticator") return dst, newError("invalid authentication")
} }
return append(dst, ciphertext[4:]...), nil return append(dst, ciphertext[4:]...), nil
} }

View File

@ -14,7 +14,6 @@ import (
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/crypto" "v2ray.com/core/common/crypto"
"v2ray.com/core/common/dice" "v2ray.com/core/common/dice"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
"v2ray.com/core/common/protocol" "v2ray.com/core/common/protocol"
"v2ray.com/core/common/serial" "v2ray.com/core/common/serial"
@ -63,7 +62,7 @@ func (v *ClientSession) EncodeRequestHeader(header *protocol.RequestHeader, writ
timestamp := protocol.NewTimestampGenerator(protocol.NowTime(), 30)() timestamp := protocol.NewTimestampGenerator(protocol.NowTime(), 30)()
account, err := header.User.GetTypedAccount() account, err := header.User.GetTypedAccount()
if err != nil { if err != nil {
log.Trace(errors.New("failed to get user account: ", err).AtError().Path("Proxy", "VMess", "Encoding", "ClientSession")) log.Trace(newError("failed to get user account: ", err).AtError())
return return
} }
idHash := v.idHash(account.(*vmess.InternalAccount).AnyValidID().Bytes()) idHash := v.idHash(account.(*vmess.InternalAccount).AnyValidID().Bytes())
@ -186,12 +185,12 @@ func (v *ClientSession) DecodeResponseHeader(reader io.Reader) (*protocol.Respon
_, err := io.ReadFull(v.responseReader, buffer[:4]) _, err := io.ReadFull(v.responseReader, buffer[:4])
if err != nil { if err != nil {
log.Trace(errors.New("failed to read response header").Base(err).Path("Proxy", "VMess", "Encoding", "ClientSession")) log.Trace(newError("failed to read response header").Base(err))
return nil, err return nil, err
} }
if buffer[0] != v.responseHeader { if buffer[0] != v.responseHeader {
return nil, errors.New("unexpected response header. Expecting ", int(v.responseHeader), " but actually ", int(buffer[0])).Path("Proxy", "VMess", "Encoding", "ClientSession") return nil, newError("unexpected response header. Expecting ", int(v.responseHeader), " but actually ", int(buffer[0]))
} }
header := &protocol.ResponseHeader{ header := &protocol.ResponseHeader{
@ -203,7 +202,7 @@ func (v *ClientSession) DecodeResponseHeader(reader io.Reader) (*protocol.Respon
dataLen := int(buffer[3]) dataLen := int(buffer[3])
_, err := io.ReadFull(v.responseReader, buffer[:dataLen]) _, err := io.ReadFull(v.responseReader, buffer[:dataLen])
if err != nil { if err != nil {
log.Trace(errors.New("failed to read response command").Base(err).Path("Proxy", "VMess", "Encoding", "ClientSession")) log.Trace(newError("failed to read response command").Base(err))
return nil, err return nil, err
} }
data := buffer[:dataLen] data := buffer[:dataLen]

View File

@ -4,7 +4,6 @@ import (
"io" "io"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
"v2ray.com/core/common/protocol" "v2ray.com/core/common/protocol"
"v2ray.com/core/common/serial" "v2ray.com/core/common/serial"
@ -12,9 +11,9 @@ import (
) )
var ( var (
ErrCommandTypeMismatch = errors.New("Command type mismatch.") ErrCommandTypeMismatch = newError("Command type mismatch.")
ErrUnknownCommand = errors.New("Unknown command.") ErrUnknownCommand = newError("Unknown command.")
ErrCommandTooLarge = errors.New("Command too large.") ErrCommandTooLarge = newError("Command too large.")
) )
func MarshalCommand(command interface{}, writer io.Writer) error { func MarshalCommand(command interface{}, writer io.Writer) error {
@ -53,12 +52,12 @@ func MarshalCommand(command interface{}, writer io.Writer) error {
func UnmarshalCommand(cmdID byte, data []byte) (protocol.ResponseCommand, error) { func UnmarshalCommand(cmdID byte, data []byte) (protocol.ResponseCommand, error) {
if len(data) <= 4 { if len(data) <= 4 {
return nil, errors.New("insufficient length").Path("Proxy", "VMess", "Encoding", "Command") return nil, newError("insufficient length")
} }
expectedAuth := Authenticate(data[4:]) expectedAuth := Authenticate(data[4:])
actualAuth := serial.BytesToUint32(data[:4]) actualAuth := serial.BytesToUint32(data[:4])
if expectedAuth != actualAuth { if expectedAuth != actualAuth {
return nil, errors.New("invalid auth").Path("Proxy", "VMess", "Encoding", "Command") return nil, newError("invalid auth")
} }
var factory CommandFactory var factory CommandFactory
@ -110,38 +109,38 @@ func (v *CommandSwitchAccountFactory) Marshal(command interface{}, writer io.Wri
func (v *CommandSwitchAccountFactory) Unmarshal(data []byte) (interface{}, error) { func (v *CommandSwitchAccountFactory) Unmarshal(data []byte) (interface{}, error) {
cmd := new(protocol.CommandSwitchAccount) cmd := new(protocol.CommandSwitchAccount)
if len(data) == 0 { if len(data) == 0 {
return nil, errors.New("insufficient length.").Path("Proxy", "VMess", "Encoding", "Command") return nil, newError("insufficient length.")
} }
lenHost := int(data[0]) lenHost := int(data[0])
if len(data) < lenHost+1 { if len(data) < lenHost+1 {
return nil, errors.New("insufficient length.").Path("Proxy", "VMess", "Encoding", "Command") return nil, newError("insufficient length.")
} }
if lenHost > 0 { if lenHost > 0 {
cmd.Host = net.ParseAddress(string(data[1 : 1+lenHost])) cmd.Host = net.ParseAddress(string(data[1 : 1+lenHost]))
} }
portStart := 1 + lenHost portStart := 1 + lenHost
if len(data) < portStart+2 { if len(data) < portStart+2 {
return nil, errors.New("insufficient length.").Path("Proxy", "VMess", "Encoding", "Command") return nil, newError("insufficient length.")
} }
cmd.Port = net.PortFromBytes(data[portStart : portStart+2]) cmd.Port = net.PortFromBytes(data[portStart : portStart+2])
idStart := portStart + 2 idStart := portStart + 2
if len(data) < idStart+16 { if len(data) < idStart+16 {
return nil, errors.New("insufficient length.").Path("Proxy", "VMess", "Encoding", "Command") return nil, newError("insufficient length.")
} }
cmd.ID, _ = uuid.ParseBytes(data[idStart : idStart+16]) cmd.ID, _ = uuid.ParseBytes(data[idStart : idStart+16])
alterIDStart := idStart + 16 alterIDStart := idStart + 16
if len(data) < alterIDStart+2 { if len(data) < alterIDStart+2 {
return nil, errors.New("insufficient length.").Path("Proxy", "VMess", "Encoding", "Command") return nil, newError("insufficient length.")
} }
cmd.AlterIds = serial.BytesToUint16(data[alterIDStart : alterIDStart+2]) cmd.AlterIds = serial.BytesToUint16(data[alterIDStart : alterIDStart+2])
levelStart := alterIDStart + 2 levelStart := alterIDStart + 2
if len(data) < levelStart+1 { if len(data) < levelStart+1 {
return nil, errors.New("insufficient length.").Path("Proxy", "VMess", "Encoding", "Command") return nil, newError("insufficient length.")
} }
cmd.Level = uint32(data[levelStart]) cmd.Level = uint32(data[levelStart])
timeStart := levelStart + 1 timeStart := levelStart + 1
if len(data) < timeStart { if len(data) < timeStart {
return nil, errors.New("insufficient length.").Path("Proxy", "VMess", "Encoding", "Command") return nil, newError("insufficient length.")
} }
cmd.ValidMin = data[timeStart] cmd.ValidMin = data[timeStart]
return cmd, nil return cmd, nil

View File

@ -0,0 +1,3 @@
package encoding
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg encoding -path Proxy,VMess,Encoding

View File

@ -0,0 +1,7 @@
package encoding
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).Path("Proxy", "VMess", "Encoding")
}

View File

@ -13,7 +13,6 @@ import (
"golang.org/x/crypto/chacha20poly1305" "golang.org/x/crypto/chacha20poly1305"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/crypto" "v2ray.com/core/common/crypto"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
"v2ray.com/core/common/protocol" "v2ray.com/core/common/protocol"
"v2ray.com/core/common/serial" "v2ray.com/core/common/serial"
@ -123,12 +122,12 @@ func (v *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Request
_, err := io.ReadFull(reader, buffer[:protocol.IDBytesLen]) _, err := io.ReadFull(reader, buffer[:protocol.IDBytesLen])
if err != nil { if err != nil {
return nil, errors.New("failed to read request header").Base(err).Path("Proxy", "VMess", "Encoding", "ServerSession") return nil, newError("failed to read request header").Base(err)
} }
user, timestamp, valid := v.userValidator.Get(buffer[:protocol.IDBytesLen]) user, timestamp, valid := v.userValidator.Get(buffer[:protocol.IDBytesLen])
if !valid { if !valid {
return nil, errors.New("invalid user").Path("Proxy", "VMess", "Encoding", "ServerSession") return nil, newError("invalid user")
} }
timestampHash := md5.New() timestampHash := md5.New()
@ -136,7 +135,7 @@ func (v *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Request
iv := timestampHash.Sum(nil) iv := timestampHash.Sum(nil)
account, err := user.GetTypedAccount() account, err := user.GetTypedAccount()
if err != nil { if err != nil {
return nil, errors.New("failed to get user account").Base(err).Path("Proxy", "VMess", "Encoding", "ServerSession") return nil, newError("failed to get user account").Base(err)
} }
vmessAccount := account.(*vmess.InternalAccount) vmessAccount := account.(*vmess.InternalAccount)
@ -145,7 +144,7 @@ func (v *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Request
nBytes, err := io.ReadFull(decryptor, buffer[:41]) nBytes, err := io.ReadFull(decryptor, buffer[:41])
if err != nil { if err != nil {
return nil, errors.New("failed to read request header").Base(err).Path("Proxy", "VMess", "Encoding", "ServerSession") return nil, newError("failed to read request header").Base(err)
} }
bufferLen := nBytes bufferLen := nBytes
@ -155,7 +154,7 @@ func (v *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Request
} }
if request.Version != Version { if request.Version != Version {
return nil, errors.New("invalid protocol version ", request.Version).Path("Proxy", "VMess", "Encoding", "ServerSession") return nil, newError("invalid protocol version ", request.Version)
} }
v.requestBodyIV = append([]byte(nil), buffer[1:17]...) // 16 bytes v.requestBodyIV = append([]byte(nil), buffer[1:17]...) // 16 bytes
@ -165,7 +164,7 @@ func (v *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Request
copy(sid.key[:], v.requestBodyKey) copy(sid.key[:], v.requestBodyKey)
copy(sid.nonce[:], v.requestBodyIV) copy(sid.nonce[:], v.requestBodyIV)
if v.sessionHistory.has(sid) { if v.sessionHistory.has(sid) {
return nil, errors.New("duplicated session id, possibly under replay attack").Path("Proxy", "VMess", "Encoding", "ServerSession") return nil, newError("duplicated session id, possibly under replay attack")
} }
v.sessionHistory.add(sid) v.sessionHistory.add(sid)
@ -183,28 +182,28 @@ func (v *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Request
_, err = io.ReadFull(decryptor, buffer[41:45]) // 4 bytes _, err = io.ReadFull(decryptor, buffer[41:45]) // 4 bytes
bufferLen += 4 bufferLen += 4
if err != nil { if err != nil {
return nil, errors.New("failed to read IPv4 address").Base(err).Path("Proxy", "VMess", "Encoding", "ServerSession") return nil, newError("failed to read IPv4 address").Base(err)
} }
request.Address = net.IPAddress(buffer[41:45]) request.Address = net.IPAddress(buffer[41:45])
case AddrTypeIPv6: case AddrTypeIPv6:
_, err = io.ReadFull(decryptor, buffer[41:57]) // 16 bytes _, err = io.ReadFull(decryptor, buffer[41:57]) // 16 bytes
bufferLen += 16 bufferLen += 16
if err != nil { if err != nil {
return nil, errors.New("failed to read IPv6 address").Base(err).Path("Proxy", "VMess", "Encoding", "ServerSession") return nil, newError("failed to read IPv6 address").Base(err)
} }
request.Address = net.IPAddress(buffer[41:57]) request.Address = net.IPAddress(buffer[41:57])
case AddrTypeDomain: case AddrTypeDomain:
_, err = io.ReadFull(decryptor, buffer[41:42]) _, err = io.ReadFull(decryptor, buffer[41:42])
if err != nil { if err != nil {
return nil, errors.New("failed to read domain address").Base(err).Path("Proxy", "VMess", "Encoding", "ServerSession") return nil, newError("failed to read domain address").Base(err)
} }
domainLength := int(buffer[41]) domainLength := int(buffer[41])
if domainLength == 0 { if domainLength == 0 {
return nil, errors.New("zero length domain").Base(err).Path("Proxy", "VMess", "Encoding", "ServerSession") return nil, newError("zero length domain").Base(err)
} }
_, err = io.ReadFull(decryptor, buffer[42:42+domainLength]) _, err = io.ReadFull(decryptor, buffer[42:42+domainLength])
if err != nil { if err != nil {
return nil, errors.New("failed to read domain address").Base(err).Path("Proxy", "VMess", "Encoding", "ServerSession") return nil, newError("failed to read domain address").Base(err)
} }
bufferLen += 1 + domainLength bufferLen += 1 + domainLength
request.Address = net.DomainAddress(string(buffer[42 : 42+domainLength])) request.Address = net.DomainAddress(string(buffer[42 : 42+domainLength]))
@ -213,14 +212,14 @@ func (v *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Request
if padingLen > 0 { if padingLen > 0 {
_, err = io.ReadFull(decryptor, buffer[bufferLen:bufferLen+padingLen]) _, err = io.ReadFull(decryptor, buffer[bufferLen:bufferLen+padingLen])
if err != nil { if err != nil {
return nil, errors.New("failed to read padding").Base(err).Path("Proxy", "VMess", "Encoding", "ServerSession") return nil, newError("failed to read padding").Base(err)
} }
bufferLen += padingLen bufferLen += padingLen
} }
_, err = io.ReadFull(decryptor, buffer[bufferLen:bufferLen+4]) _, err = io.ReadFull(decryptor, buffer[bufferLen:bufferLen+4])
if err != nil { if err != nil {
return nil, errors.New("failed to read checksum").Base(err).Path("Proxy", "VMess", "Encoding", "ServerSession") return nil, newError("failed to read checksum").Base(err)
} }
fnv1a := fnv.New32a() fnv1a := fnv.New32a()
@ -229,11 +228,11 @@ func (v *ServerSession) DecodeRequestHeader(reader io.Reader) (*protocol.Request
expectedHash := serial.BytesToUint32(buffer[bufferLen : bufferLen+4]) expectedHash := serial.BytesToUint32(buffer[bufferLen : bufferLen+4])
if actualHash != expectedHash { if actualHash != expectedHash {
return nil, errors.New("invalid auth").Path("Proxy", "VMess", "Encoding", "ServerSession") return nil, newError("invalid auth")
} }
if request.Address == nil { if request.Address == nil {
return nil, errors.New("invalid remote address").Path("Proxy", "VMess", "Encoding", "ServerSession") return nil, newError("invalid remote address")
} }
return request, nil return request, nil

View File

@ -0,0 +1,7 @@
package vmess
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).Path("Proxy", "VMess")
}

View File

@ -0,0 +1,7 @@
package inbound
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).Path("Proxy", "VMess", "Inbound")
}

View File

@ -1,5 +1,7 @@
package inbound package inbound
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg inbound -path Proxy,VMess,Inbound
import ( import (
"context" "context"
"io" "io"
@ -82,7 +84,7 @@ type Handler struct {
func New(ctx context.Context, config *Config) (*Handler, error) { func New(ctx context.Context, config *Config) (*Handler, error) {
space := app.SpaceFromContext(ctx) space := app.SpaceFromContext(ctx)
if space == nil { if space == nil {
return nil, errors.New("no space in context").Path("Proxy", "VMess", "Inbound") return nil, newError("no space in context")
} }
allowedClients := vmess.NewTimedUserValidator(ctx, protocol.DefaultIDHash) allowedClients := vmess.NewTimedUserValidator(ctx, protocol.DefaultIDHash)
@ -100,7 +102,7 @@ func New(ctx context.Context, config *Config) (*Handler, error) {
space.OnInitialize(func() error { space.OnInitialize(func() error {
handler.inboundHandlerManager = proxyman.InboundHandlerManagerFromSpace(space) handler.inboundHandlerManager = proxyman.InboundHandlerManagerFromSpace(space)
if handler.inboundHandlerManager == nil { if handler.inboundHandlerManager == nil {
return errors.New("InboundHandlerManager is not found is space").Path("Proxy", "VMess", "Inbound") return newError("InboundHandlerManager is not found is space")
} }
return nil return nil
}) })
@ -180,12 +182,12 @@ func (v *Handler) Process(ctx context.Context, network net.Network, connection i
if err != nil { if err != nil {
if errors.Cause(err) != io.EOF { if errors.Cause(err) != io.EOF {
log.Access(connection.RemoteAddr(), "", log.AccessRejected, err) log.Access(connection.RemoteAddr(), "", log.AccessRejected, err)
log.Trace(errors.New("invalid request from ", connection.RemoteAddr(), ": ", err).Path("Proxy", "VMess", "Inbound")) log.Trace(newError("invalid request from ", connection.RemoteAddr(), ": ", err))
} }
return err return err
} }
log.Access(connection.RemoteAddr(), request.Destination(), log.AccessAccepted, "") log.Access(connection.RemoteAddr(), request.Destination(), log.AccessAccepted, "")
log.Trace(errors.New("received request for ", request.Destination()).Path("Proxy", "VMess", "Inbound")) log.Trace(newError("received request for ", request.Destination()))
connection.SetReadDeadline(time.Time{}) connection.SetReadDeadline(time.Time{})
@ -220,11 +222,11 @@ func (v *Handler) Process(ctx context.Context, network net.Network, connection i
if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil { if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil {
input.CloseError() input.CloseError()
output.CloseError() output.CloseError()
return errors.New("error during processing").Base(err).Path("Proxy", "VMess", "Inbound") return newError("error during processing").Base(err)
} }
if err := writer.Flush(); err != nil { if err := writer.Flush(); err != nil {
return errors.New("error during flushing remaining data").Base(err).Path("Proxy", "VMess", "Inbound") return newError("error during flushing remaining data").Base(err)
} }
runtime.KeepAlive(timer) runtime.KeepAlive(timer)
@ -238,7 +240,7 @@ func (v *Handler) generateCommand(ctx context.Context, request *protocol.Request
if v.inboundHandlerManager != nil { if v.inboundHandlerManager != nil {
handler, err := v.inboundHandlerManager.GetHandler(ctx, tag) handler, err := v.inboundHandlerManager.GetHandler(ctx, tag)
if err != nil { if err != nil {
log.Trace(errors.New("failed to get detour handler: ", tag, err).AtWarning().Path("Proxy", "VMess", "Inbound")) log.Trace(newError("failed to get detour handler: ", tag, err).AtWarning())
return nil return nil
} }
proxyHandler, port, availableMin := handler.GetRandomInboundProxy() proxyHandler, port, availableMin := handler.GetRandomInboundProxy()
@ -248,7 +250,7 @@ func (v *Handler) generateCommand(ctx context.Context, request *protocol.Request
availableMin = 255 availableMin = 255
} }
log.Trace(errors.New("pick detour handler for port ", port, " for ", availableMin, " minutes.").Path("Proxy", "VMess", "Inbound").AtDebug()) log.Trace(newError("pick detour handler for port ", port, " for ", availableMin, " minutes.").AtDebug())
user := inboundHandler.GetUser(request.User.Email) user := inboundHandler.GetUser(request.User.Email)
if user == nil { if user == nil {
return nil return nil

View File

@ -0,0 +1,7 @@
package outbound
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error {
return errors.New(values...).Path("Proxy", "VMess", "Outbound")
}

View File

@ -1,5 +1,7 @@
package outbound package outbound
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg outbound -path Proxy,VMess,Outbound
import ( import (
"context" "context"
"runtime" "runtime"
@ -9,7 +11,6 @@ import (
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/buf" "v2ray.com/core/common/buf"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/net" "v2ray.com/core/common/net"
"v2ray.com/core/common/protocol" "v2ray.com/core/common/protocol"
"v2ray.com/core/common/retry" "v2ray.com/core/common/retry"
@ -30,7 +31,7 @@ type Handler struct {
func New(ctx context.Context, config *Config) (*Handler, error) { func New(ctx context.Context, config *Config) (*Handler, error) {
space := app.SpaceFromContext(ctx) space := app.SpaceFromContext(ctx)
if space == nil { if space == nil {
return nil, errors.New("no space in context.").Path("Proxy", "VMess", "Outbound") return nil, newError("no space in context.")
} }
serverList := protocol.NewServerList() serverList := protocol.NewServerList()
@ -61,15 +62,15 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
return nil return nil
}) })
if err != nil { if err != nil {
return errors.New("failed to find an available destination").Base(err).AtWarning().Path("Proxy", "VMess", "Outbound") return newError("failed to find an available destination").Base(err).AtWarning()
} }
defer conn.Close() defer conn.Close()
target, ok := proxy.TargetFromContext(ctx) target, ok := proxy.TargetFromContext(ctx)
if !ok { if !ok {
return errors.New("target not specified").Path("Proxy", "VMess", "Outbound").AtError() return newError("target not specified").AtError()
} }
log.Trace(errors.New("tunneling request to ", target, " via ", rec.Destination()).Path("Proxy", "VMess", "Outbound")) log.Trace(newError("tunneling request to ", target, " via ", rec.Destination()))
command := protocol.RequestCommandTCP command := protocol.RequestCommandTCP
if target.Network == net.Network_UDP { if target.Network == net.Network_UDP {
@ -86,7 +87,7 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
rawAccount, err := request.User.GetTypedAccount() rawAccount, err := request.User.GetTypedAccount()
if err != nil { if err != nil {
return errors.New("failed to get user account").Base(err).AtWarning().Path("Proxy", "VMess", "Outbound") return newError("failed to get user account").Base(err).AtWarning()
} }
account := rawAccount.(*vmess.InternalAccount) account := rawAccount.(*vmess.InternalAccount)
request.Security = account.Security request.Security = account.Security
@ -109,11 +110,11 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
bodyWriter := session.EncodeRequestBody(request, writer) bodyWriter := session.EncodeRequestBody(request, writer)
firstPayload, err := input.ReadTimeout(time.Millisecond * 500) firstPayload, err := input.ReadTimeout(time.Millisecond * 500)
if err != nil && err != buf.ErrReadTimeout { if err != nil && err != buf.ErrReadTimeout {
return errors.New("failed to get first payload").Base(err).Path("Proxy", "VMess", "Outbound") return newError("failed to get first payload").Base(err)
} }
if !firstPayload.IsEmpty() { if !firstPayload.IsEmpty() {
if err := bodyWriter.Write(firstPayload); err != nil { if err := bodyWriter.Write(firstPayload); err != nil {
return errors.New("failed to write first payload").Base(err).Path("Proxy", "VMess", "Outbound") return newError("failed to write first payload").Base(err)
} }
firstPayload.Release() firstPayload.Release()
} }
@ -159,7 +160,7 @@ func (v *Handler) Process(ctx context.Context, outboundRay ray.OutboundRay, dial
}) })
if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil { if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil {
return errors.New("connection ends").Base(err).Path("Proxy", "VMess", "Outbound") return newError("connection ends").Base(err)
} }
runtime.KeepAlive(timer) runtime.KeepAlive(timer)

View File

@ -5,6 +5,8 @@
// clients with 'socks' for proxying. // clients with 'socks' for proxying.
package vmess package vmess
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg vmess -path Proxy,VMess
import ( import (
"context" "context"
"sync" "sync"

View File

@ -1,6 +1,7 @@
package scenarios package scenarios
import ( import (
"errors"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
@ -16,7 +17,6 @@ import (
"v2ray.com/core" "v2ray.com/core"
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/common" "v2ray.com/core/common"
"v2ray.com/core/common/errors"
v2net "v2ray.com/core/common/net" v2net "v2ray.com/core/common/net"
"v2ray.com/core/common/retry" "v2ray.com/core/common/retry"
) )

View File

@ -3,7 +3,6 @@ package conf
import ( import (
"encoding/json" "encoding/json"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/serial" "v2ray.com/core/common/serial"
"v2ray.com/core/proxy/blackhole" "v2ray.com/core/proxy/blackhole"
) )
@ -29,7 +28,7 @@ func (v *BlackholeConfig) Build() (*serial.TypedMessage, error) {
if v.Response != nil { if v.Response != nil {
response, _, err := configLoader.Load(v.Response) response, _, err := configLoader.Load(v.Response)
if err != nil { if err != nil {
return nil, errors.New("Config: Failed to parse Blackhole response config.").Base(err) return nil, newError("Config: Failed to parse Blackhole response config.").Base(err)
} }
responseSettings, err := response.(Buildable).Build() responseSettings, err := response.(Buildable).Build()
if err != nil { if err != nil {

View File

@ -4,7 +4,6 @@ import (
"encoding/json" "encoding/json"
"strings" "strings"
"v2ray.com/core/common/errors"
v2net "v2ray.com/core/common/net" v2net "v2ray.com/core/common/net"
"v2ray.com/core/common/protocol" "v2ray.com/core/common/protocol"
) )
@ -33,7 +32,7 @@ func (v *StringList) UnmarshalJSON(data []byte) error {
*v = *NewStringList(strlist) *v = *NewStringList(strlist)
return nil return nil
} }
return errors.New("Config: Unknown format of a string list: " + string(data)) return newError("Config: Unknown format of a string list: " + string(data))
} }
type Address struct { type Address struct {
@ -80,7 +79,7 @@ func (v *NetworkList) UnmarshalJSON(data []byte) error {
*v = nl *v = nl
return nil return nil
} }
return errors.New("Config: Unknown format of a string list: " + string(data)) return newError("Config: Unknown format of a string list: " + string(data))
} }
func (v *NetworkList) Build() *v2net.NetworkList { func (v *NetworkList) Build() *v2net.NetworkList {
@ -114,7 +113,7 @@ func parseStringPort(data []byte) (v2net.Port, v2net.Port, error) {
} }
pair := strings.SplitN(s, "-", 2) pair := strings.SplitN(s, "-", 2)
if len(pair) == 0 { if len(pair) == 0 {
return v2net.Port(0), v2net.Port(0), errors.New("Config: Invalid port range: ", s) return v2net.Port(0), v2net.Port(0), newError("Config: Invalid port range: ", s)
} }
if len(pair) == 1 { if len(pair) == 1 {
port, err := v2net.PortFromString(pair[0]) port, err := v2net.PortFromString(pair[0])
@ -158,12 +157,12 @@ func (v *PortRange) UnmarshalJSON(data []byte) error {
v.From = uint32(from) v.From = uint32(from)
v.To = uint32(to) v.To = uint32(to)
if v.From > v.To { if v.From > v.To {
return errors.New("Config: Invalid port range ", v.From, " -> ", v.To) return newError("Config: Invalid port range ", v.From, " -> ", v.To)
} }
return nil return nil
} }
return errors.New("Config: Invalid port range: ", string(data)) return newError("Config: Invalid port range: ", string(data))
} }
type User struct { type User struct {

3
tools/conf/conf.go Normal file
View File

@ -0,0 +1,3 @@
package conf
//go:generate go run $GOPATH/src/v2ray.com/core/tools/generrorgen/main.go -pkg conf -path Tools,Conf

View File

@ -0,0 +1,5 @@
package conf
import "v2ray.com/core/common/errors"
func newError(values ...interface{}) *errors.Error { return errors.New(values...).Path("Tools", "Conf") }

View File

@ -4,7 +4,6 @@ import (
"net" "net"
"strings" "strings"
"v2ray.com/core/common/errors"
v2net "v2ray.com/core/common/net" v2net "v2ray.com/core/common/net"
"v2ray.com/core/common/protocol" "v2ray.com/core/common/protocol"
"v2ray.com/core/common/serial" "v2ray.com/core/common/serial"
@ -31,11 +30,11 @@ func (v *FreedomConfig) Build() (*serial.TypedMessage, error) {
if len(v.Redirect) > 0 { if len(v.Redirect) > 0 {
host, portStr, err := net.SplitHostPort(v.Redirect) host, portStr, err := net.SplitHostPort(v.Redirect)
if err != nil { if err != nil {
return nil, errors.New("Config: Invalid redirect address: ", v.Redirect, ": ", err).Base(err) return nil, newError("Config: Invalid redirect address: ", v.Redirect, ": ", err).Base(err)
} }
port, err := v2net.PortFromString(portStr) port, err := v2net.PortFromString(portStr)
if err != nil { if err != nil {
return nil, errors.New("Config: Invalid redirect port: ", v.Redirect, ": ", err).Base(err) return nil, newError("Config: Invalid redirect port: ", v.Redirect, ": ", err).Base(err)
} }
if len(host) == 0 { if len(host) == 0 {
host = "127.0.0.1" host = "127.0.0.1"

View File

@ -1,10 +1,6 @@
package conf package conf
import ( import "encoding/json"
"encoding/json"
"v2ray.com/core/common/errors"
)
type ConfigCreator func() interface{} type ConfigCreator func() interface{}
@ -12,7 +8,7 @@ type ConfigCreatorCache map[string]ConfigCreator
func (v ConfigCreatorCache) RegisterCreator(id string, creator ConfigCreator) error { func (v ConfigCreatorCache) RegisterCreator(id string, creator ConfigCreator) error {
if _, found := v[id]; found { if _, found := v[id]; found {
return errors.New("Config: ", id, " already registered.") return newError("Config: ", id, " already registered.")
} }
v[id] = creator v[id] = creator
@ -22,7 +18,7 @@ func (v ConfigCreatorCache) RegisterCreator(id string, creator ConfigCreator) er
func (v ConfigCreatorCache) CreateConfig(id string) (interface{}, error) { func (v ConfigCreatorCache) CreateConfig(id string) (interface{}, error) {
creator, found := v[id] creator, found := v[id]
if !found { if !found {
return nil, errors.New("Config: Unknown config id: ", id) return nil, newError("Config: Unknown config id: ", id)
} }
return creator(), nil return creator(), nil
} }
@ -44,7 +40,7 @@ func NewJSONConfigLoader(cache ConfigCreatorCache, idKey string, configKey strin
func (v *JSONConfigLoader) LoadWithID(raw []byte, id string) (interface{}, error) { func (v *JSONConfigLoader) LoadWithID(raw []byte, id string) (interface{}, error) {
creator, found := v.cache[id] creator, found := v.cache[id]
if !found { if !found {
return nil, errors.New("Config: Unknown config id: ", id) return nil, newError("Config: Unknown config id: ", id)
} }
config := creator() config := creator()
@ -61,7 +57,7 @@ func (v *JSONConfigLoader) Load(raw []byte) (interface{}, string, error) {
} }
rawID, found := obj[v.idKey] rawID, found := obj[v.idKey]
if !found { if !found {
return nil, "", errors.New("Config: ", v.idKey, " not found in JSON context.") return nil, "", newError("Config: ", v.idKey, " not found in JSON context.")
} }
var id string var id string
if err := json.Unmarshal(rawID, &id); err != nil { if err := json.Unmarshal(rawID, &id); err != nil {
@ -71,7 +67,7 @@ func (v *JSONConfigLoader) Load(raw []byte) (interface{}, string, error) {
if len(v.configKey) > 0 { if len(v.configKey) > 0 {
configValue, found := obj[v.configKey] configValue, found := obj[v.configKey]
if !found { if !found {
return nil, "", errors.New("Config: ", v.configKey, " not found in JSON content.") return nil, "", newError("Config: ", v.configKey, " not found in JSON content.")
} }
rawConfig = configValue rawConfig = configValue
} }

View File

@ -7,7 +7,6 @@ import (
"v2ray.com/core/app/log" "v2ray.com/core/app/log"
"v2ray.com/core/app/router" "v2ray.com/core/app/router"
"v2ray.com/core/common/errors"
v2net "v2ray.com/core/common/net" v2net "v2ray.com/core/common/net"
"v2ray.com/core/tools/geoip" "v2ray.com/core/tools/geoip"
@ -25,7 +24,7 @@ type RouterConfig struct {
func (v *RouterConfig) Build() (*router.Config, error) { func (v *RouterConfig) Build() (*router.Config, error) {
if v.Settings == nil { if v.Settings == nil {
return nil, errors.New("Config: Router settings is not specified.") return nil, newError("Config: Router settings is not specified.")
} }
config := new(router.Config) config := new(router.Config)
@ -69,12 +68,12 @@ func parseIP(s string) (*router.CIDR, error) {
if len(mask) > 0 { if len(mask) > 0 {
bits64, err := strconv.ParseUint(mask, 10, 32) bits64, err := strconv.ParseUint(mask, 10, 32)
if err != nil { if err != nil {
return nil, errors.New("Config: invalid network mask for router: ", mask).Base(err) return nil, newError("Config: invalid network mask for router: ", mask).Base(err)
} }
bits = uint32(bits64) bits = uint32(bits64)
} }
if bits > 32 { if bits > 32 {
return nil, errors.New("Config: invalid network mask for router: ", bits) return nil, newError("Config: invalid network mask for router: ", bits)
} }
return &router.CIDR{ return &router.CIDR{
Ip: []byte(ip.IP()), Ip: []byte(ip.IP()),
@ -85,19 +84,19 @@ func parseIP(s string) (*router.CIDR, error) {
if len(mask) > 0 { if len(mask) > 0 {
bits64, err := strconv.ParseUint(mask, 10, 32) bits64, err := strconv.ParseUint(mask, 10, 32)
if err != nil { if err != nil {
return nil, errors.New("Config: invalid network mask for router: ", mask).Base(err) return nil, newError("Config: invalid network mask for router: ", mask).Base(err)
} }
bits = uint32(bits64) bits = uint32(bits64)
} }
if bits > 128 { if bits > 128 {
return nil, errors.New("Config: invalid network mask for router: ", bits) return nil, newError("Config: invalid network mask for router: ", bits)
} }
return &router.CIDR{ return &router.CIDR{
Ip: []byte(ip.IP()), Ip: []byte(ip.IP()),
Prefix: bits, Prefix: bits,
}, nil }, nil
default: default:
return nil, errors.New("Config: unsupported address for router: ", s) return nil, newError("Config: unsupported address for router: ", s)
} }
} }
@ -139,7 +138,7 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) {
for _, ip := range *rawFieldRule.IP { for _, ip := range *rawFieldRule.IP {
ipRule, err := parseIP(ip) ipRule, err := parseIP(ip)
if err != nil { if err != nil {
return nil, errors.New("Config: invalid IP: ", ip).Base(err) return nil, newError("Config: invalid IP: ", ip).Base(err)
} }
rule.Cidr = append(rule.Cidr, ipRule) rule.Cidr = append(rule.Cidr, ipRule)
} }
@ -157,7 +156,7 @@ func parseFieldRule(msg json.RawMessage) (*router.RoutingRule, error) {
for _, ip := range *rawFieldRule.SourceIP { for _, ip := range *rawFieldRule.SourceIP {
ipRule, err := parseIP(ip) ipRule, err := parseIP(ip)
if err != nil { if err != nil {
return nil, errors.New("Config: invalid IP: ", ip).Base(err) return nil, newError("Config: invalid IP: ", ip).Base(err)
} }
rule.SourceCidr = append(rule.SourceCidr, ipRule) rule.SourceCidr = append(rule.SourceCidr, ipRule)
} }
@ -182,41 +181,41 @@ func ParseRule(msg json.RawMessage) (*router.RoutingRule, error) {
rawRule := new(RouterRule) rawRule := new(RouterRule)
err := json.Unmarshal(msg, rawRule) err := json.Unmarshal(msg, rawRule)
if err != nil { if err != nil {
return nil, errors.New("Config: Invalid router rule.").Base(err) return nil, newError("Config: Invalid router rule.").Base(err)
} }
if rawRule.Type == "field" { if rawRule.Type == "field" {
fieldrule, err := parseFieldRule(msg) fieldrule, err := parseFieldRule(msg)
if err != nil { if err != nil {
return nil, errors.New("Config: Invalid field rule.").Base(err) return nil, newError("Config: Invalid field rule.").Base(err)
} }
return fieldrule, nil return fieldrule, nil
} }
if rawRule.Type == "chinaip" { if rawRule.Type == "chinaip" {
chinaiprule, err := parseChinaIPRule(msg) chinaiprule, err := parseChinaIPRule(msg)
if err != nil { if err != nil {
return nil, errors.New("Config: Invalid chinaip rule.").Base(err) return nil, newError("Config: Invalid chinaip rule.").Base(err)
} }
return chinaiprule, nil return chinaiprule, nil
} }
if rawRule.Type == "chinasites" { if rawRule.Type == "chinasites" {
chinasitesrule, err := parseChinaSitesRule(msg) chinasitesrule, err := parseChinaSitesRule(msg)
if err != nil { if err != nil {
return nil, errors.New("Config: Invalid chinasites rule.").Base(err) return nil, newError("Config: Invalid chinasites rule.").Base(err)
} }
return chinasitesrule, nil return chinasitesrule, nil
} }
return nil, errors.New("Config: Unknown router rule type: ", rawRule.Type) return nil, newError("Config: Unknown router rule type: ", rawRule.Type)
} }
func parseChinaIPRule(data []byte) (*router.RoutingRule, error) { func parseChinaIPRule(data []byte) (*router.RoutingRule, error) {
rawRule := new(RouterRule) rawRule := new(RouterRule)
err := json.Unmarshal(data, rawRule) err := json.Unmarshal(data, rawRule)
if err != nil { if err != nil {
return nil, errors.New("Config: Invalid router rule.").Base(err) return nil, newError("Config: Invalid router rule.").Base(err)
} }
var chinaIPs geoip.CountryIPRange var chinaIPs geoip.CountryIPRange
if err := proto.Unmarshal(geoip.ChinaIPs, &chinaIPs); err != nil { if err := proto.Unmarshal(geoip.ChinaIPs, &chinaIPs); err != nil {
return nil, errors.New("Config: Invalid china ips.").Base(err) return nil, newError("Config: Invalid china ips.").Base(err)
} }
return &router.RoutingRule{ return &router.RoutingRule{
Tag: rawRule.OutboundTag, Tag: rawRule.OutboundTag,
@ -228,7 +227,7 @@ func parseChinaSitesRule(data []byte) (*router.RoutingRule, error) {
rawRule := new(RouterRule) rawRule := new(RouterRule)
err := json.Unmarshal(data, rawRule) err := json.Unmarshal(data, rawRule)
if err != nil { if err != nil {
log.Trace(errors.New("Router: Invalid router rule: ", err).AtError()) log.Trace(newError("Router: Invalid router rule: ", err).AtError())
return nil, err return nil, err
} }
return &router.RoutingRule{ return &router.RoutingRule{

View File

@ -3,7 +3,6 @@ package conf
import ( import (
"strings" "strings"
"v2ray.com/core/common/errors"
"v2ray.com/core/common/protocol" "v2ray.com/core/common/protocol"
"v2ray.com/core/common/serial" "v2ray.com/core/common/serial"
"v2ray.com/core/proxy/shadowsocks" "v2ray.com/core/proxy/shadowsocks"
@ -23,7 +22,7 @@ func (v *ShadowsocksServerConfig) Build() (*serial.TypedMessage, error) {
config.UdpEnabled = v.UDP config.UdpEnabled = v.UDP
if len(v.Password) == 0 { if len(v.Password) == 0 {
return nil, errors.New("Shadowsocks password is not specified.") return nil, newError("Shadowsocks password is not specified.")
} }
account := &shadowsocks.Account{ account := &shadowsocks.Account{
Password: v.Password, Password: v.Password,
@ -47,7 +46,7 @@ func (v *ShadowsocksServerConfig) Build() (*serial.TypedMessage, error) {
case "chacha20-ietf": case "chacha20-ietf":
account.CipherType = shadowsocks.CipherType_CHACHA20_IETF account.CipherType = shadowsocks.CipherType_CHACHA20_IETF
default: default:
return nil, errors.New("Unknown cipher method: " + cipher) return nil, newError("Unknown cipher method: " + cipher)
} }
config.User = &protocol.User{ config.User = &protocol.User{
@ -76,19 +75,19 @@ func (v *ShadowsocksClientConfig) Build() (*serial.TypedMessage, error) {
config := new(shadowsocks.ClientConfig) config := new(shadowsocks.ClientConfig)
if len(v.Servers) == 0 { if len(v.Servers) == 0 {
return nil, errors.New("0 Shadowsocks server configured.") return nil, newError("0 Shadowsocks server configured.")
} }
serverSpecs := make([]*protocol.ServerEndpoint, len(v.Servers)) serverSpecs := make([]*protocol.ServerEndpoint, len(v.Servers))
for idx, server := range v.Servers { for idx, server := range v.Servers {
if server.Address == nil { if server.Address == nil {
return nil, errors.New("Shadowsocks server address is not set.") return nil, newError("Shadowsocks server address is not set.")
} }
if server.Port == 0 { if server.Port == 0 {
return nil, errors.New("Invalid Shadowsocks port.") return nil, newError("Invalid Shadowsocks port.")
} }
if len(server.Password) == 0 { if len(server.Password) == 0 {
return nil, errors.New("Shadowsocks password is not specified.") return nil, newError("Shadowsocks password is not specified.")
} }
account := &shadowsocks.Account{ account := &shadowsocks.Account{
Password: server.Password, Password: server.Password,
@ -108,7 +107,7 @@ func (v *ShadowsocksClientConfig) Build() (*serial.TypedMessage, error) {
case "chacha20-ietf": case "chacha20-ietf":
account.CipherType = shadowsocks.CipherType_CHACHA20_IETF account.CipherType = shadowsocks.CipherType_CHACHA20_IETF
default: default:
return nil, errors.New("Unknown cipher method: " + cipher) return nil, newError("Unknown cipher method: " + cipher)
} }
ss := &protocol.ServerEndpoint{ ss := &protocol.ServerEndpoint{

Some files were not shown because too many files have changed in this diff Show More