From 6363c3379098d35f32034f7870c41f63abb87144 Mon Sep 17 00:00:00 2001 From: Darien Raymond Date: Wed, 22 Feb 2017 10:24:04 +0100 Subject: [PATCH 1/5] detect actual address type for domain address type --- common/errors/errors.go | 69 +++++++++++++++-------------------------- proxy/socks/protocol.go | 6 ++-- proxy/socks/server.go | 11 +++---- 3 files changed, 32 insertions(+), 54 deletions(-) diff --git a/common/errors/errors.go b/common/errors/errors.go index 37e05c3c..daef9973 100644 --- a/common/errors/errors.go +++ b/common/errors/errors.go @@ -24,33 +24,49 @@ type Error struct { } // Error implements error.Error(). -func (v *Error) Error() string { +func (v Error) Error() string { return v.message } // Inner implements hasInnerError.Inner() -func (v *Error) Inner() error { +func (v Error) Inner() error { if v.inner == nil { return nil } return v.inner } -func (v *Error) ActionRequired() bool { +func (v Error) ActionRequired() bool { return v.actionRequired } +func (v Error) RequireUserAction() Error { + v.actionRequired = true + return v +} + +func (v Error) Message(msg ...interface{}) Error { + return Error{ + inner: v, + message: serial.Concat(msg...), + } +} + +func (v Error) Format(format string, values ...interface{}) Error { + return v.Message(fmt.Sprintf(format, values...)) +} + // New returns a new error object with message formed from given arguments. -func New(msg ...interface{}) error { - return &Error{ +func New(msg ...interface{}) Error { + return Error{ message: serial.Concat(msg...), } } -// Base returns an ErrorBuilder based on the given error. -func Base(err error) ErrorBuilder { - return ErrorBuilder{ - error: err, +// Base returns an Error based on the given error. +func Base(err error) Error { + return Error{ + inner: err, } } @@ -86,38 +102,3 @@ func IsActionRequired(err error) bool { } return false } - -type ErrorBuilder struct { - error - actionRequired bool -} - -func (v ErrorBuilder) RequireUserAction() ErrorBuilder { - v.actionRequired = true - return v -} - -// Message returns an error object with given message and base error. -func (v ErrorBuilder) Message(msg ...interface{}) error { - if v.error == nil { - return nil - } - - return &Error{ - message: serial.Concat(msg...) + " > " + v.error.Error(), - inner: v.error, - actionRequired: v.actionRequired, - } -} - -// Format returns an errors object with given message format and base error. -func (v ErrorBuilder) Format(format string, values ...interface{}) error { - if v.error == nil { - return nil - } - return &Error{ - message: fmt.Sprintf(format, values...) + " > " + v.error.Error(), - inner: v.error, - actionRequired: v.actionRequired, - } -} diff --git a/proxy/socks/protocol.go b/proxy/socks/protocol.go index fce43a1b..65e33ff9 100644 --- a/proxy/socks/protocol.go +++ b/proxy/socks/protocol.go @@ -159,7 +159,7 @@ func (s *ServerSession) Handshake(reader io.Reader, writer io.Writer) (*protocol if err := buffer.AppendSupplier(buf.ReadFullFrom(reader, domainLength)); err != nil { return nil, err } - request.Address = v2net.DomainAddress(string(buffer.BytesFrom(-domainLength))) + request.Address = v2net.ParseAddress(string(buffer.BytesFrom(-domainLength))) default: return nil, errors.New("Socks|Server: Unknown address type: ", addrType) } @@ -400,10 +400,10 @@ func ClientHandshake(request *protocol.RequestHeader, reader io.Reader, writer i } if b.Byte(0) != socks5Version { - return nil, errors.New("Socks|Client: Unexpected server version: ", b.Byte(0)) + return nil, errors.New("Socks|Client: Unexpected server version: ", b.Byte(0)).RequireUserAction() } if b.Byte(1) != authByte { - return nil, errors.New("Socks|Client: auth method not supported.") + return nil, errors.New("Socks|Client: auth method not supported.").RequireUserAction() } if authByte == authPassword { diff --git a/proxy/socks/server.go b/proxy/socks/server.go index ca196083..a4ab03d8 100644 --- a/proxy/socks/server.go +++ b/proxy/socks/server.go @@ -29,7 +29,7 @@ type Server struct { func NewServer(ctx context.Context, config *ServerConfig) (*Server, error) { space := app.SpaceFromContext(ctx) if space == nil { - return nil, errors.New("Socks|Server: No space in context.") + return nil, errors.New("Socks|Server: No space in context.").RequireUserAction() } s := &Server{ config: config, @@ -130,8 +130,7 @@ func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writ v2reader := buf.NewReader(reader) if err := buf.PipeUntilEOF(timer, v2reader, input); err != nil { - log.Info("Socks|Server: Failed to transport all TCP request: ", err) - return err + return errors.Base(err).Message("Socks|Server: Failed to transport all TCP request.") } return nil }) @@ -139,17 +138,15 @@ func (v *Server) transport(ctx context.Context, reader io.Reader, writer io.Writ responseDone := signal.ExecuteAsync(func() error { v2writer := buf.NewWriter(writer) if err := buf.PipeUntilEOF(timer, output, v2writer); err != nil { - log.Info("Socks|Server: Failed to transport all TCP response: ", err) - return err + return errors.Base(err).Message("Socks|Server: Failed to transport all TCP response.") } return nil }) if err := signal.ErrorOrFinish2(ctx, requestDone, responseDone); err != nil { - log.Info("Socks|Server: Connection ends with ", err) input.CloseError() output.CloseError() - return err + return errors.Base(err).Message("Socks|Server: Connection ends.") } runtime.KeepAlive(timer) From 722594cb79a0078c5814e35bf34866228ab32698 Mon Sep 17 00:00:00 2001 From: Darien Raymond Date: Wed, 22 Feb 2017 11:30:52 +0100 Subject: [PATCH 2/5] hide server implementation detail --- main/main.go | 10 +++++----- v2ray.go | 32 ++++++++++++++++---------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/main/main.go b/main/main.go index 5c0fb671..192e58b7 100644 --- a/main/main.go +++ b/main/main.go @@ -43,7 +43,7 @@ func GetConfigFormat() core.ConfigFormat { } } -func startV2Ray() (*core.Point, error) { +func startV2Ray() (core.Server, error) { if len(configFile) == 0 { return nil, errors.New("V2Ray: Config file is not set.") } @@ -64,7 +64,7 @@ func startV2Ray() (*core.Point, error) { return nil, errors.Base(err).Message("V2Ray: Failed to read config file: ", configFile) } - vPoint, err := core.NewPoint(config) + vPoint, err := core.New(config) if err != nil { return nil, errors.Base(err).Message("V2Ray: Failed to create initialize.") } @@ -81,7 +81,7 @@ func main() { return } - point, err := startV2Ray() + server, err := startV2Ray() if err != nil { fmt.Println(err.Error()) return @@ -92,7 +92,7 @@ func main() { return } - if err := point.Start(); err != nil { + if err := server.Start(); err != nil { fmt.Println("V2Ray: Failed to start. ", err) } @@ -100,5 +100,5 @@ func main() { signal.Notify(osSignals, os.Interrupt, os.Kill, syscall.SIGTERM) <-osSignals - point.Close() + server.Close() } diff --git a/v2ray.go b/v2ray.go index 74ac10a8..ad13f399 100644 --- a/v2ray.go +++ b/v2ray.go @@ -23,20 +23,20 @@ type Server interface { Close() } -// Point shell of V2Ray. -type Point struct { - space app.Space -} - // New creates a new V2Ray server with given config. func New(config *Config) (Server, error) { - return NewPoint(config) + return newSimpleServer(config) +} + +// simpleServer shell of V2Ray. +type simpleServer struct { + space app.Space } -// NewPoint returns a new Point server based on given configuration. +// newSimpleServer returns a new Point server based on given configuration. // The server is not started at this point. -func NewPoint(config *Config) (*Point, error) { - var pt = new(Point) +func newSimpleServer(config *Config) (*simpleServer, error) { + var server = new(simpleServer) if err := config.Transport.Apply(); err != nil { return nil, err @@ -45,7 +45,7 @@ func NewPoint(config *Config) (*Point, error) { space := app.NewSpace() ctx := app.ContextWithSpace(context.Background(), space) - pt.space = space + server.space = space for _, appSettings := range config.App { settings, err := appSettings.GetInstance() @@ -132,19 +132,19 @@ func NewPoint(config *Config) (*Point, error) { } } - if err := pt.space.Initialize(); err != nil { + if err := server.space.Initialize(); err != nil { return nil, err } - return pt, nil + return server, nil } -func (v *Point) Close() { - v.space.Close() +func (s *simpleServer) Close() { + s.space.Close() } -func (v *Point) Start() error { - if err := v.space.Start(); err != nil { +func (s *simpleServer) Start() error { + if err := s.space.Start(); err != nil { return err } log.Warning("V2Ray started.") From 55186c1917dd5ba3022061f71c909b6e58c98d11 Mon Sep 17 00:00:00 2001 From: Darien Raymond Date: Wed, 22 Feb 2017 11:58:55 +0100 Subject: [PATCH 3/5] check error --- loader.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/loader.go b/loader.go index eb811830..db62707b 100644 --- a/loader.go +++ b/loader.go @@ -5,6 +5,7 @@ import ( "io/ioutil" "github.com/golang/protobuf/proto" + "v2ray.com/core/common" "v2ray.com/core/common/errors" ) @@ -38,5 +39,5 @@ func loadProtobufConfig(input io.Reader) (*Config, error) { } func init() { - RegisterConfigLoader(ConfigFormat_Protobuf, loadProtobufConfig) + common.Must(RegisterConfigLoader(ConfigFormat_Protobuf, loadProtobufConfig)) } From 31a21bef089c4d5547daed8a8f7b2931061067d5 Mon Sep 17 00:00:00 2001 From: Darien Raymond Date: Wed, 22 Feb 2017 11:59:01 +0100 Subject: [PATCH 4/5] refactor uuid --- common/uuid/uuid.go | 46 ++++++++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/common/uuid/uuid.go b/common/uuid/uuid.go index 17f0bd27..736955b4 100644 --- a/common/uuid/uuid.go +++ b/common/uuid/uuid.go @@ -5,6 +5,7 @@ import ( "crypto/md5" "crypto/rand" "encoding/hex" + "v2ray.com/core/common/errors" ) @@ -15,53 +16,50 @@ var ( type UUID [16]byte // String returns the string representation of this UUID. -func (v *UUID) String() string { - return bytesToString(v.Bytes()) +func (u *UUID) String() string { + bytes := u.Bytes() + result := hex.EncodeToString(bytes[0 : byteGroups[0]/2]) + start := byteGroups[0] / 2 + for i := 1; i < len(byteGroups); i++ { + nBytes := byteGroups[i] / 2 + result += "-" + result += hex.EncodeToString(bytes[start : start+nBytes]) + start += nBytes + } + return result } // Bytes returns the bytes representation of this UUID. -func (v *UUID) Bytes() []byte { - return v[:] +func (u *UUID) Bytes() []byte { + return u[:] } // Equals returns true if this UUID equals another UUID by value. -func (v *UUID) Equals(another *UUID) bool { - if v == nil && another == nil { +func (u *UUID) Equals(another *UUID) bool { + if u == nil && another == nil { return true } - if v == nil || another == nil { + if u == nil || another == nil { return false } - return bytes.Equal(v.Bytes(), another.Bytes()) + return bytes.Equal(u.Bytes(), another.Bytes()) } // Next generates a deterministic random UUID based on this UUID. -func (v *UUID) Next() *UUID { +func (u *UUID) Next() *UUID { md5hash := md5.New() - md5hash.Write(v.Bytes()) + md5hash.Write(u.Bytes()) md5hash.Write([]byte("16167dc8-16b6-4e6d-b8bb-65dd68113a81")) newid := new(UUID) for { md5hash.Sum(newid[:0]) - if !newid.Equals(v) { + if !newid.Equals(u) { return newid } md5hash.Write([]byte("533eff8a-4113-4b10-b5ce-0f5d76b98cd2")) } } -func bytesToString(bytes []byte) string { - result := hex.EncodeToString(bytes[0 : byteGroups[0]/2]) - start := byteGroups[0] / 2 - for i := 1; i < len(byteGroups); i++ { - nBytes := byteGroups[i] / 2 - result += "-" - result += hex.EncodeToString(bytes[start : start+nBytes]) - start += nBytes - } - return result -} - // New creates an UUID with random value. func New() *UUID { uuid := new(UUID) @@ -69,7 +67,7 @@ func New() *UUID { return uuid } -// PraseBytes converts an UUID in byte form to object. +// ParseBytes converts an UUID in byte form to object. func ParseBytes(b []byte) (*UUID, error) { if len(b) != 16 { return nil, errors.New("Invalid UUID: ", b) From 374760ff2465b854dd62c213705d1666c0aea10b Mon Sep 17 00:00:00 2001 From: Darien Raymond Date: Wed, 22 Feb 2017 12:06:10 +0100 Subject: [PATCH 5/5] more comments --- core.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core.go b/core.go index e9787010..98bc5a69 100644 --- a/core.go +++ b/core.go @@ -22,7 +22,8 @@ var ( intro = "An unified platform for anti-censorship." ) -// Version returns V2Ray's version as a string. +// Version returns V2Ray's version as a string, in the form of "x.y.z" where x, y and z are numbers. +// ".z" part may be omitted in regular releases. func Version() string { return version }