diff --git a/all.go b/all.go index 28c7c5e7f..09559de6a 100644 --- a/all.go +++ b/all.go @@ -3,6 +3,7 @@ package core import ( // The following are necessary as they register handlers in their init functions. _ "v2ray.com/core/app/dns" + _ "v2ray.com/core/app/proxy" _ "v2ray.com/core/app/router" _ "v2ray.com/core/proxy/blackhole" diff --git a/app/proxy/proxy.go b/app/proxy/proxy.go index 412c18ce2..d1db774fb 100644 --- a/app/proxy/proxy.go +++ b/app/proxy/proxy.go @@ -36,18 +36,20 @@ func NewOutboundProxy(space app.Space) *OutboundProxy { return proxy } +func (this *OutboundProxy) RegisterDialer() { + internet.ProxyDialer = this.Dial +} + func (this *OutboundProxy) Dial(src v2net.Address, dest v2net.Destination, options internet.DialerOptions) (internet.Connection, error) { - handler := this.outboundManager.GetHandler(options.ProxyTag) + handler := this.outboundManager.GetHandler(options.Proxy.Tag) if handler == nil { - log.Warning("Proxy: Failed to get outbound handler with tag: ", options.ProxyTag) + log.Warning("Proxy: Failed to get outbound handler with tag: ", options.Proxy.Tag) return internet.Dial(src, dest, internet.DialerOptions{ Stream: options.Stream, }) } stream := ray.NewRay() - if err := handler.Dispatch(dest, alloc.NewLocalBuffer(32).Clear(), stream); err != nil { - return nil, err - } + go handler.Dispatch(dest, alloc.NewLocalBuffer(32).Clear(), stream) return NewProxyConnection(src, dest, stream), nil } diff --git a/app/proxy/proxy_test.go b/app/proxy/proxy_test.go new file mode 100644 index 000000000..4e71289dd --- /dev/null +++ b/app/proxy/proxy_test.go @@ -0,0 +1,68 @@ +package proxy_test + +import ( + "testing" + + "v2ray.com/core/app" + . "v2ray.com/core/app/proxy" + "v2ray.com/core/app/proxyman" + v2net "v2ray.com/core/common/net" + "v2ray.com/core/proxy" + "v2ray.com/core/proxy/freedom" + "v2ray.com/core/testing/assert" + "v2ray.com/core/testing/servers/tcp" + "v2ray.com/core/transport/internet" +) + +func TestProxyDial(t *testing.T) { + assert := assert.On(t) + + space := app.NewSpace() + outboundManager := proxyman.NewDefaultOutboundHandlerManager() + outboundManager.SetHandler("tag", freedom.NewFreedomConnection(&freedom.Config{}, space, &proxy.OutboundHandlerMeta{ + Tag: "tag", + StreamSettings: &internet.StreamConfig{ + Network: v2net.Network_RawTCP, + }, + })) + space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, outboundManager) + + proxy := NewOutboundProxy(space) + space.BindApp(APP_ID, proxy) + + assert.Error(space.Initialize()).IsNil() + + xor := func(b []byte) []byte { + for idx, x := range b { + b[idx] = x ^ 'c' + } + return b + } + tcpServer := &tcp.Server{ + MsgProcessor: xor, + } + dest, err := tcpServer.Start() + assert.Error(err).IsNil() + + conn, err := proxy.Dial(v2net.LocalHostIP, dest, internet.DialerOptions{ + Stream: &internet.StreamConfig{ + Network: v2net.Network_RawTCP, + }, + Proxy: &internet.ProxyConfig{ + Tag: "tag", + }, + }) + assert.Error(err).IsNil() + + _, err = conn.Write([]byte{'a', 'b', 'c', 'd'}) + assert.Error(err).IsNil() + + b := make([]byte, 10) + nBytes, err := conn.Read(b) + assert.Error(err).IsNil() + + assert.Bytes(xor(b[:nBytes])).Equals([]byte{'a', 'b', 'c', 'd'}) + + conn.Close() + tcpServer.Close() +} diff --git a/common/io/chan_reader.go b/common/io/chan_reader.go index 730793695..af7dde672 100644 --- a/common/io/chan_reader.go +++ b/common/io/chan_reader.go @@ -15,11 +15,9 @@ type ChanReader struct { } func NewChanReader(stream Reader) *ChanReader { - this := &ChanReader{ + return &ChanReader{ stream: stream, } - this.Fill() - return this } // Private: Visible for testing. diff --git a/config.pb.go b/config.pb.go index b7e5cf328..2f1faabbf 100644 --- a/config.pb.go +++ b/config.pb.go @@ -196,6 +196,7 @@ type OutboundConnectionConfig struct { // IP address to send data through. 0.0.0.0 if unset. SendThrough *v2ray_core_common_net1.IPOrDomain `protobuf:"bytes,2,opt,name=send_through,json=sendThrough" json:"send_through,omitempty"` StreamSettings *v2ray_core_transport_internet.StreamConfig `protobuf:"bytes,3,opt,name=stream_settings,json=streamSettings" json:"stream_settings,omitempty"` + ProxySettings *v2ray_core_transport_internet.ProxyConfig `protobuf:"bytes,5,opt,name=proxy_settings,json=proxySettings" json:"proxy_settings,omitempty"` Tag string `protobuf:"bytes,4,opt,name=tag" json:"tag,omitempty"` } @@ -225,6 +226,13 @@ func (m *OutboundConnectionConfig) GetStreamSettings() *v2ray_core_transport_int return nil } +func (m *OutboundConnectionConfig) GetProxySettings() *v2ray_core_transport_internet.ProxyConfig { + if m != nil { + return m.ProxySettings + } + return nil +} + type Config struct { // Inbound handler configurations. Must have at least one item. Inbound []*InboundConnectionConfig `protobuf:"bytes,1,rep,name=inbound" json:"inbound,omitempty"` @@ -290,49 +298,50 @@ func init() { func init() { proto.RegisterFile("v2ray.com/core/config.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 697 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x94, 0xdd, 0x6e, 0xd3, 0x3e, - 0x18, 0xc6, 0x97, 0xb6, 0xeb, 0xda, 0xb7, 0xfb, 0xef, 0x5f, 0x19, 0x04, 0x61, 0x30, 0x54, 0xba, - 0xaf, 0xf2, 0xa1, 0x54, 0x14, 0x21, 0x3e, 0x24, 0x18, 0x5b, 0x07, 0xd2, 0x40, 0xa2, 0x95, 0xbb, - 0x23, 0x4e, 0x2a, 0x2f, 0xf5, 0xb2, 0x48, 0x89, 0x1d, 0x39, 0xee, 0x46, 0x2f, 0x81, 0x03, 0x2e, - 0x86, 0x5b, 0xe1, 0x8a, 0x90, 0x1d, 0x37, 0xcd, 0x68, 0x33, 0x26, 0x21, 0xce, 0x9c, 0xf8, 0xf9, - 0xbd, 0xb6, 0x9f, 0xe7, 0xb5, 0xe1, 0xee, 0x79, 0x47, 0x90, 0x89, 0xe3, 0xf2, 0xb0, 0xed, 0x72, - 0x41, 0xdb, 0x2e, 0x67, 0xa7, 0xbe, 0xe7, 0x44, 0x82, 0x4b, 0x8e, 0x60, 0x3a, 0x29, 0xe8, 0xfa, - 0xee, 0x9c, 0x30, 0x0c, 0x39, 0x6b, 0x07, 0x9c, 0x8c, 0xa8, 0x68, 0xcb, 0x49, 0x44, 0x13, 0x68, - 0x7d, 0x6b, 0xb1, 0x90, 0x51, 0xd9, 0x8e, 0xb8, 0x90, 0x46, 0xb5, 0x9b, 0xaf, 0x22, 0xa3, 0x91, - 0xa0, 0x71, 0x6c, 0x84, 0x3b, 0x79, 0xeb, 0x7a, 0x97, 0xf6, 0xba, 0xee, 0xfc, 0xa6, 0x93, 0x82, - 0xb0, 0x58, 0x2d, 0xd8, 0xf6, 0x99, 0xa4, 0x42, 0x15, 0xbe, 0xa4, 0xdf, 0xce, 0xd5, 0x67, 0x65, - 0xcd, 0xe7, 0xb0, 0xb1, 0x1f, 0x04, 0xdc, 0x25, 0xd2, 0xe7, 0x6c, 0x20, 0x05, 0x91, 0xd4, 0x9b, - 0x74, 0x39, 0x73, 0xc7, 0x42, 0x50, 0xe6, 0x4e, 0xd0, 0x4d, 0x58, 0x3e, 0x27, 0xc1, 0x98, 0xda, - 0x56, 0xc3, 0x6a, 0xfd, 0x87, 0x93, 0x8f, 0xe6, 0x53, 0xb8, 0x33, 0x8f, 0x61, 0x7a, 0x2a, 0x68, - 0x7c, 0x96, 0x83, 0x7c, 0x2b, 0x00, 0x9a, 0x67, 0xd0, 0x0b, 0x28, 0x29, 0x73, 0xb5, 0x76, 0xad, - 0xb3, 0xe9, 0xcc, 0x22, 0x71, 0xe6, 0xd5, 0xce, 0xf1, 0x24, 0xa2, 0x58, 0x03, 0xe8, 0x13, 0xd4, - 0xdc, 0xd9, 0x3e, 0xed, 0x42, 0xc3, 0x6a, 0xd5, 0x3a, 0x0f, 0xaf, 0xe6, 0x33, 0x07, 0xc3, 0x59, - 0x1a, 0xed, 0xc1, 0x8a, 0x48, 0x76, 0x6f, 0x17, 0x75, 0xa1, 0xed, 0xab, 0x0b, 0x99, 0xa3, 0xe2, - 0x29, 0xd5, 0x7c, 0x02, 0x25, 0xb5, 0x37, 0x04, 0x50, 0xde, 0x0f, 0x2e, 0xc8, 0x24, 0xae, 0x2f, - 0xa9, 0x31, 0x26, 0x6c, 0xc4, 0xc3, 0xba, 0x85, 0x56, 0xa1, 0xf2, 0xfe, 0xab, 0xca, 0x89, 0x04, - 0xf5, 0x42, 0xf3, 0x67, 0x11, 0x6e, 0x1f, 0xb1, 0x13, 0x3e, 0x66, 0xa3, 0x2e, 0x67, 0x8c, 0xba, - 0xaa, 0x76, 0x57, 0xe7, 0x82, 0xba, 0x50, 0x89, 0xa9, 0x94, 0x3e, 0xf3, 0x62, 0x6d, 0x4a, 0xad, - 0xb3, 0x9b, 0xdd, 0x4b, 0xd2, 0x1f, 0x4e, 0xd2, 0x97, 0xda, 0x8f, 0xd1, 0xc0, 0xc8, 0x71, 0x0a, - 0xa2, 0x3d, 0x00, 0x95, 0xf5, 0x50, 0x10, 0xe6, 0x51, 0xe3, 0x4d, 0x63, 0x41, 0x19, 0x46, 0xa5, - 0xd3, 0xe7, 0x42, 0x62, 0xa5, 0xc3, 0xd5, 0x68, 0x3a, 0x44, 0x6f, 0xa1, 0x1a, 0xf8, 0xb1, 0xa4, - 0x6c, 0xc8, 0x99, 0xb1, 0xe4, 0x41, 0x0e, 0x7f, 0xd4, 0xef, 0x89, 0x43, 0x1e, 0x12, 0x9f, 0xe1, - 0x4a, 0xc2, 0xf4, 0x18, 0xaa, 0x43, 0x51, 0x12, 0xcf, 0x2e, 0x35, 0xac, 0x56, 0x15, 0xab, 0x21, - 0xea, 0xc1, 0x0d, 0x92, 0xfa, 0x38, 0x8c, 0x8d, 0x91, 0xf6, 0xb2, 0xae, 0x7d, 0xff, 0x0f, 0x76, - 0x23, 0x32, 0xdf, 0x39, 0xc7, 0xf0, 0x7f, 0x2c, 0x05, 0x25, 0xe1, 0x30, 0xf5, 0xab, 0xac, 0x8b, - 0x3d, 0xce, 0x16, 0x4b, 0xfb, 0xde, 0x99, 0xde, 0x13, 0x67, 0xa0, 0xa9, 0xc4, 0x6e, 0xbc, 0x96, - 0xd4, 0x98, 0x7a, 0x88, 0x5e, 0x82, 0xad, 0xd6, 0xba, 0x18, 0x46, 0x24, 0x8e, 0xfd, 0x73, 0x3a, - 0x74, 0xd3, 0x80, 0xec, 0x95, 0x86, 0xd5, 0xaa, 0xe0, 0x5b, 0x7a, 0xbe, 0x9f, 0x4c, 0xcf, 0xe2, - 0x6b, 0x7e, 0x2f, 0x80, 0xdd, 0x1b, 0xcb, 0x7f, 0x98, 0xea, 0x21, 0xac, 0xc6, 0x94, 0x8d, 0x86, - 0xf2, 0x4c, 0xf0, 0xb1, 0x77, 0x66, 0x72, 0xbd, 0x46, 0x2e, 0x35, 0x85, 0x1d, 0x27, 0xd4, 0x22, - 0xdf, 0x8a, 0x7f, 0xef, 0xdb, 0x5c, 0xe0, 0xcd, 0x1f, 0x05, 0x28, 0x9b, 0xd3, 0xbf, 0x81, 0x15, - 0x3f, 0x69, 0x77, 0xdb, 0x6a, 0x14, 0x5b, 0xb5, 0xcb, 0xf7, 0x3c, 0xe7, 0x26, 0xe0, 0x29, 0x83, - 0xde, 0x41, 0x85, 0x1b, 0x63, 0xed, 0x82, 0xe6, 0xb7, 0xb2, 0x7c, 0x9e, 0xe9, 0x38, 0xa5, 0x50, - 0x1b, 0x8a, 0x01, 0xf7, 0xcc, 0x39, 0x37, 0x16, 0x3a, 0xef, 0x39, 0x86, 0x52, 0x4a, 0xf4, 0x0a, - 0x8a, 0x24, 0x8a, 0xec, 0x92, 0x5e, 0xed, 0xda, 0x51, 0x29, 0x06, 0xbd, 0x86, 0x6a, 0x6a, 0x9e, - 0x69, 0xef, 0x7b, 0x8b, 0x9d, 0x35, 0x0b, 0xce, 0xe4, 0x8f, 0x76, 0x60, 0x35, 0xf9, 0xf9, 0x81, - 0x8b, 0x90, 0x48, 0xf5, 0x6c, 0xf4, 0xd5, 0x3b, 0x7d, 0x32, 0x3e, 0xad, 0x2f, 0xa1, 0x0a, 0x94, - 0x3e, 0x0e, 0x7a, 0x9f, 0xeb, 0xd6, 0xc1, 0x26, 0xac, 0xb9, 0x3c, 0xcc, 0x54, 0x3d, 0xa8, 0x25, - 0x9c, 0x56, 0x7f, 0x29, 0xa9, 0x5f, 0x27, 0x65, 0xfd, 0xc4, 0x3f, 0xfb, 0x15, 0x00, 0x00, 0xff, - 0xff, 0x1c, 0xfa, 0xca, 0xe6, 0x04, 0x07, 0x00, 0x00, + // 719 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x95, 0xdd, 0x6e, 0xd3, 0x30, + 0x1c, 0xc5, 0x97, 0xb6, 0xeb, 0xda, 0x7f, 0xb7, 0x52, 0x19, 0x04, 0x61, 0x30, 0x54, 0xba, 0xaf, + 0x32, 0x50, 0x2a, 0x8a, 0x10, 0x1f, 0x12, 0x8c, 0xad, 0x03, 0x69, 0x20, 0xd1, 0xe2, 0xee, 0x8a, + 0x9b, 0xca, 0x4b, 0xbd, 0x2c, 0x52, 0x62, 0x47, 0x8e, 0xbb, 0xad, 0x8f, 0xc0, 0xe3, 0xf0, 0x2a, + 0x3c, 0x01, 0x8f, 0x82, 0xec, 0xb8, 0x69, 0x47, 0xdb, 0x6d, 0x12, 0xe2, 0x2e, 0x8d, 0xcf, 0xef, + 0xd8, 0x39, 0xc7, 0x76, 0xe1, 0xc1, 0x59, 0x53, 0x90, 0xa1, 0xe3, 0xf2, 0xb0, 0xe1, 0x72, 0x41, + 0x1b, 0x2e, 0x67, 0x27, 0xbe, 0xe7, 0x44, 0x82, 0x4b, 0x8e, 0x60, 0x34, 0x28, 0xe8, 0xea, 0xf6, + 0x94, 0x30, 0x0c, 0x39, 0x6b, 0x04, 0x9c, 0xf4, 0xa9, 0x68, 0xc8, 0x61, 0x44, 0x13, 0x68, 0x75, + 0x63, 0xb6, 0x90, 0x51, 0xd9, 0x88, 0xb8, 0x90, 0x46, 0xb5, 0x3d, 0x5f, 0x45, 0xfa, 0x7d, 0x41, + 0xe3, 0xd8, 0x08, 0xb7, 0xe6, 0xcd, 0xeb, 0x5d, 0x5a, 0xeb, 0xaa, 0xf3, 0x97, 0x4e, 0x0a, 0xc2, + 0x62, 0x35, 0x61, 0xc3, 0x67, 0x92, 0x0a, 0x65, 0x7c, 0x49, 0xbf, 0x39, 0x57, 0x3f, 0x29, 0xab, + 0xbd, 0x84, 0xb5, 0xbd, 0x20, 0xe0, 0x2e, 0x91, 0x3e, 0x67, 0x5d, 0x29, 0x88, 0xa4, 0xde, 0xb0, + 0xc5, 0x99, 0x3b, 0x10, 0x82, 0x32, 0x77, 0x88, 0xee, 0xc0, 0xe2, 0x19, 0x09, 0x06, 0xd4, 0xb6, + 0xaa, 0x56, 0x7d, 0x05, 0x27, 0x3f, 0x6a, 0xcf, 0xe1, 0xfe, 0x34, 0x86, 0xe9, 0x89, 0xa0, 0xf1, + 0xe9, 0x1c, 0xe4, 0x47, 0x06, 0xd0, 0x34, 0x83, 0x5e, 0x41, 0x4e, 0x85, 0xab, 0xb5, 0xe5, 0xe6, + 0xba, 0x33, 0xae, 0xc4, 0x99, 0x56, 0x3b, 0x47, 0xc3, 0x88, 0x62, 0x0d, 0xa0, 0x2f, 0x50, 0x72, + 0xc7, 0xeb, 0xb4, 0x33, 0x55, 0xab, 0x5e, 0x6a, 0x3e, 0xb9, 0x9a, 0x9f, 0xf8, 0x30, 0x3c, 0x49, + 0xa3, 0x5d, 0x58, 0x12, 0xc9, 0xea, 0xed, 0xac, 0x36, 0xda, 0xbc, 0xda, 0xc8, 0x7c, 0x2a, 0x1e, + 0x51, 0xb5, 0x67, 0x90, 0x53, 0x6b, 0x43, 0x00, 0xf9, 0xbd, 0xe0, 0x9c, 0x0c, 0xe3, 0xca, 0x82, + 0x7a, 0xc6, 0x84, 0xf5, 0x79, 0x58, 0xb1, 0xd0, 0x32, 0x14, 0x3e, 0x5e, 0xa8, 0x9e, 0x48, 0x50, + 0xc9, 0xd4, 0x7e, 0x65, 0xe1, 0xde, 0x21, 0x3b, 0xe6, 0x03, 0xd6, 0x6f, 0x71, 0xc6, 0xa8, 0xab, + 0xbc, 0x5b, 0xba, 0x17, 0xd4, 0x82, 0x42, 0x4c, 0xa5, 0xf4, 0x99, 0x17, 0xeb, 0x50, 0x4a, 0xcd, + 0xed, 0xc9, 0xb5, 0x24, 0xfb, 0xc3, 0x49, 0xf6, 0xa5, 0xce, 0xa3, 0xdf, 0x35, 0x72, 0x9c, 0x82, + 0x68, 0x17, 0x40, 0x75, 0xdd, 0x13, 0x84, 0x79, 0xd4, 0x64, 0x53, 0x9d, 0x61, 0xc3, 0xa8, 0x74, + 0x3a, 0x5c, 0x48, 0xac, 0x74, 0xb8, 0x18, 0x8d, 0x1e, 0xd1, 0x7b, 0x28, 0x06, 0x7e, 0x2c, 0x29, + 0xeb, 0x71, 0x66, 0x22, 0x79, 0x3c, 0x87, 0x3f, 0xec, 0xb4, 0xc5, 0x01, 0x0f, 0x89, 0xcf, 0x70, + 0x21, 0x61, 0xda, 0x0c, 0x55, 0x20, 0x2b, 0x89, 0x67, 0xe7, 0xaa, 0x56, 0xbd, 0x88, 0xd5, 0x23, + 0x6a, 0xc3, 0x6d, 0x92, 0xe6, 0xd8, 0x8b, 0x4d, 0x90, 0xf6, 0xa2, 0xf6, 0x7e, 0x74, 0x4d, 0xdc, + 0x88, 0x4c, 0xef, 0x9c, 0x23, 0xb8, 0x15, 0x4b, 0x41, 0x49, 0xd8, 0x4b, 0xf3, 0xca, 0x6b, 0xb3, + 0xa7, 0x93, 0x66, 0xe9, 0xbe, 0x77, 0x46, 0xe7, 0xc4, 0xe9, 0x6a, 0x2a, 0x89, 0x1b, 0x97, 0x13, + 0x8f, 0x51, 0x86, 0xe8, 0x35, 0xd8, 0x6a, 0xae, 0xf3, 0x5e, 0x44, 0xe2, 0xd8, 0x3f, 0xa3, 0x3d, + 0x37, 0x2d, 0xc8, 0x5e, 0xaa, 0x5a, 0xf5, 0x02, 0xbe, 0xab, 0xc7, 0x3b, 0xc9, 0xf0, 0xb8, 0xbe, + 0xda, 0xef, 0x0c, 0xd8, 0xed, 0x81, 0xfc, 0x8f, 0xad, 0x1e, 0xc0, 0x72, 0x4c, 0x59, 0xbf, 0x27, + 0x4f, 0x05, 0x1f, 0x78, 0xa7, 0xa6, 0xd7, 0x1b, 0xf4, 0x52, 0x52, 0xd8, 0x51, 0x42, 0xcd, 0xca, + 0x2d, 0xfb, 0xef, 0xb9, 0x7d, 0x83, 0x72, 0x24, 0xf8, 0xc5, 0x70, 0x6c, 0x9a, 0x34, 0xbb, 0x73, + 0x8d, 0x69, 0x47, 0x41, 0xc6, 0x73, 0x45, 0x3b, 0xa4, 0x96, 0x53, 0x7b, 0xa8, 0xf6, 0x33, 0x03, + 0x79, 0x13, 0xe8, 0x3b, 0x58, 0xf2, 0x93, 0x13, 0x64, 0x5b, 0xd5, 0x6c, 0xbd, 0x74, 0xf9, 0xea, + 0x98, 0x73, 0xb8, 0xf0, 0x88, 0x41, 0x1f, 0xa0, 0xc0, 0x4d, 0x57, 0x76, 0x46, 0xf3, 0x1b, 0x93, + 0xfc, 0xbc, 0x1e, 0x71, 0x4a, 0xa1, 0x06, 0x64, 0x03, 0xee, 0x99, 0xe8, 0xd6, 0x66, 0x96, 0xe9, + 0x39, 0x86, 0x52, 0x4a, 0xf4, 0x06, 0xb2, 0x24, 0x8a, 0xec, 0x9c, 0x9e, 0xed, 0xc6, 0xed, 0x2b, + 0x06, 0xbd, 0x85, 0x62, 0x1a, 0x9d, 0xc9, 0xf5, 0xe1, 0xec, 0x5c, 0xcd, 0x84, 0x63, 0xf9, 0xce, + 0x16, 0x2c, 0x27, 0x2f, 0x3f, 0x71, 0x11, 0x12, 0xa9, 0x6e, 0xa2, 0x8e, 0xba, 0xfa, 0x8f, 0x07, + 0x27, 0x95, 0x05, 0x54, 0x80, 0xdc, 0xe7, 0x6e, 0xfb, 0x6b, 0xc5, 0xda, 0x5f, 0x87, 0xb2, 0xcb, + 0xc3, 0x09, 0xd7, 0xfd, 0x52, 0xc2, 0x69, 0xf5, 0xf7, 0x9c, 0x7a, 0x75, 0x9c, 0xd7, 0xff, 0x1a, + 0x2f, 0xfe, 0x04, 0x00, 0x00, 0xff, 0xff, 0xe4, 0x6f, 0x70, 0x9e, 0x57, 0x07, 0x00, 0x00, } diff --git a/config.proto b/config.proto index eb03d4217..36dde67ea 100644 --- a/config.proto +++ b/config.proto @@ -77,6 +77,7 @@ message OutboundConnectionConfig { // IP address to send data through. 0.0.0.0 if unset. v2ray.core.common.net.IPOrDomain send_through = 2; v2ray.core.transport.internet.StreamConfig stream_settings = 3; + v2ray.core.transport.internet.ProxyConfig proxy_settings = 5; string tag = 4; } diff --git a/proxy/freedom/freedom.go b/proxy/freedom/freedom.go index 0bb42166f..1baacc23a 100644 --- a/proxy/freedom/freedom.go +++ b/proxy/freedom/freedom.go @@ -80,9 +80,7 @@ func (this *FreedomConnection) Dispatch(destination v2net.Destination, payload * destination = this.ResolveIP(destination) } err := retry.Timed(5, 100).On(func() error { - rawConn, err := internet.Dial(this.meta.Address, destination, internet.DialerOptions{ - Stream: this.meta.StreamSettings, - }) + rawConn, err := internet.Dial(this.meta.Address, destination, this.meta.GetDialerOptions()) if err != nil { return err } diff --git a/proxy/proxy.go b/proxy/proxy.go index 026fbea7c..cb399fd26 100644 --- a/proxy/proxy.go +++ b/proxy/proxy.go @@ -34,6 +34,14 @@ type OutboundHandlerMeta struct { Tag string Address v2net.Address StreamSettings *internet.StreamConfig + ProxySettings *internet.ProxyConfig +} + +func (this *OutboundHandlerMeta) GetDialerOptions() internet.DialerOptions { + return internet.DialerOptions{ + Stream: this.StreamSettings, + Proxy: this.ProxySettings, + } } // An InboundHandler handles inbound network connections to V2Ray. diff --git a/proxy/shadowsocks/client.go b/proxy/shadowsocks/client.go index 8cdb3096a..dc32fface 100644 --- a/proxy/shadowsocks/client.go +++ b/proxy/shadowsocks/client.go @@ -48,9 +48,7 @@ func (this *Client) Dispatch(destination v2net.Destination, payload *alloc.Buffe server = this.serverPicker.PickServer() dest := server.Destination() dest.Network = network - rawConn, err := internet.Dial(this.meta.Address, dest, internet.DialerOptions{ - Stream: this.meta.StreamSettings, - }) + rawConn, err := internet.Dial(this.meta.Address, dest, this.meta.GetDialerOptions()) if err != nil { return err } diff --git a/testing/servers/tcp/tcp.go b/testing/servers/tcp/tcp.go index 7b1b69a77..2aabf9975 100644 --- a/testing/servers/tcp/tcp.go +++ b/testing/servers/tcp/tcp.go @@ -36,7 +36,7 @@ func (server *Server) acceptConnections(listener *net.TCPListener) { for server.accepting { conn, err := listener.Accept() if err != nil { - fmt.Printf("Failed accept TCP connection: %v", err) + fmt.Printf("Failed accept TCP connection: %v\n", err) continue } diff --git a/tools/conf/transport_internet.go b/tools/conf/transport_internet.go index 24e4cd81c..a3bf509ca 100644 --- a/tools/conf/transport_internet.go +++ b/tools/conf/transport_internet.go @@ -230,3 +230,16 @@ func (this *StreamConfig) Build() (*internet.StreamConfig, error) { } return config, nil } + +type ProxyConfig struct { + Tag string `json:"tag"` +} + +func (this *ProxyConfig) Build() (*internet.ProxyConfig, error) { + if len(this.Tag) == 0 { + return nil, errors.New("Proxy tag is not set.") + } + return &internet.ProxyConfig{ + Tag: this.Tag, + }, nil +} diff --git a/tools/conf/v2ray.go b/tools/conf/v2ray.go index cc07bcee2..313e5aecf 100644 --- a/tools/conf/v2ray.go +++ b/tools/conf/v2ray.go @@ -74,6 +74,7 @@ type OutboundConnectionConfig struct { Protocol string `json:"protocol"` SendThrough *Address `json:"sendThrough"` StreamSetting *StreamConfig `json:"streamSettings"` + ProxySettings *ProxyConfig `json:"proxySettings"` Settings json.RawMessage `json:"settings"` } @@ -103,6 +104,13 @@ func (this *OutboundConnectionConfig) Build() (*core.OutboundConnectionConfig, e } config.StreamSettings = ss } + if this.ProxySettings != nil { + ps, err := this.ProxySettings.Build() + if err != nil { + return nil, errors.New("Outbound: invalid proxy settings: " + err.Error()) + } + config.ProxySettings = ps + } return config, nil } @@ -198,6 +206,7 @@ type OutboundDetourConfig struct { Tag string `json:"tag"` Settings json.RawMessage `json:"settings"` StreamSetting *StreamConfig `json:"streamSettings"` + ProxySettings *ProxyConfig `json:"proxySettings"` } func (this *OutboundDetourConfig) Build() (*core.OutboundConnectionConfig, error) { @@ -228,6 +237,14 @@ func (this *OutboundDetourConfig) Build() (*core.OutboundConnectionConfig, error if err != nil { return nil, err } + + if this.ProxySettings != nil { + ps, err := this.ProxySettings.Build() + if err != nil { + return nil, errors.New("OutboundDetour: invalid proxy settings: " + err.Error()) + } + config.ProxySettings = ps + } config.Settings = ts return config, nil } diff --git a/transport/internet/config.go b/transport/internet/config.go index b17ea8037..8ca30de31 100644 --- a/transport/internet/config.go +++ b/transport/internet/config.go @@ -68,3 +68,7 @@ func ApplyGlobalNetworkSettings(settings []*NetworkSettings) error { globalNetworkSettings = settings return nil } + +func (this *ProxyConfig) HasTag() bool { + return this != nil && len(this.Tag) > 0 +} diff --git a/transport/internet/config.pb.go b/transport/internet/config.pb.go index a3a8bbca6..b314042c7 100644 --- a/transport/internet/config.pb.go +++ b/transport/internet/config.pb.go @@ -11,6 +11,7 @@ It is generated from these files: It has these top-level messages: NetworkSettings StreamConfig + ProxyConfig */ package internet @@ -78,32 +79,43 @@ func (m *StreamConfig) GetSecuritySettings() []*v2ray_core_common_loader.TypedSe return nil } +type ProxyConfig struct { + Tag string `protobuf:"bytes,1,opt,name=tag" json:"tag,omitempty"` +} + +func (m *ProxyConfig) Reset() { *m = ProxyConfig{} } +func (m *ProxyConfig) String() string { return proto.CompactTextString(m) } +func (*ProxyConfig) ProtoMessage() {} +func (*ProxyConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + func init() { proto.RegisterType((*NetworkSettings)(nil), "v2ray.core.transport.internet.NetworkSettings") proto.RegisterType((*StreamConfig)(nil), "v2ray.core.transport.internet.StreamConfig") + proto.RegisterType((*ProxyConfig)(nil), "v2ray.core.transport.internet.ProxyConfig") } func init() { proto.RegisterFile("v2ray.com/core/transport/internet/config.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 296 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xa4, 0x91, 0x4f, 0x4b, 0xc3, 0x40, - 0x10, 0xc5, 0x49, 0x2b, 0x5a, 0xb7, 0xd5, 0xd6, 0x9c, 0x82, 0xa0, 0xc4, 0x7a, 0x68, 0x2e, 0xce, - 0x42, 0xbc, 0x78, 0xb6, 0x77, 0x0f, 0x69, 0x2f, 0x7a, 0x29, 0x71, 0x3b, 0x96, 0xa0, 0xd9, 0x0d, - 0x93, 0x51, 0xc9, 0xb7, 0xf0, 0x13, 0xf8, 0x59, 0x25, 0x7f, 0x36, 0x94, 0xa0, 0x45, 0xe8, 0x6d, - 0x18, 0xde, 0xfb, 0xed, 0x9b, 0xb7, 0x02, 0x3e, 0x42, 0x8a, 0x0b, 0x50, 0x26, 0x95, 0xca, 0x10, - 0x4a, 0xa6, 0x58, 0xe7, 0x99, 0x21, 0x96, 0x89, 0x66, 0x24, 0x8d, 0x2c, 0x95, 0xd1, 0x2f, 0xc9, - 0x06, 0x32, 0x32, 0x6c, 0xdc, 0x0b, 0xab, 0x27, 0x84, 0x56, 0x0b, 0x56, 0x7b, 0x3e, 0xeb, 0xe0, - 0x94, 0x49, 0x53, 0xa3, 0x65, 0x89, 0xd1, 0xc8, 0x9f, 0x86, 0x5e, 0x6b, 0xce, 0x5f, 0xc2, 0x37, - 0x13, 0xaf, 0x91, 0x24, 0x17, 0x19, 0xd6, 0xc2, 0xe9, 0x97, 0x23, 0xc6, 0x0f, 0xb5, 0x75, 0x81, - 0xcc, 0x89, 0xde, 0xe4, 0xee, 0x9d, 0x38, 0x6a, 0x68, 0x9e, 0xe3, 0x3b, 0xc1, 0x69, 0x78, 0x09, - 0x5b, 0xb1, 0x6a, 0x14, 0x68, 0x64, 0x68, 0x8c, 0x91, 0x95, 0xbb, 0x73, 0x31, 0xc8, 0x1b, 0x8a, - 0xd7, 0xf3, 0x9d, 0x60, 0x18, 0xce, 0x7e, 0xb1, 0xd6, 0x29, 0x60, 0x59, 0x64, 0xb8, 0xb6, 0x8f, - 0x46, 0xad, 0x71, 0xfa, 0xdd, 0x13, 0xa3, 0x05, 0x13, 0xc6, 0xe9, 0xbc, 0xaa, 0x66, 0x8f, 0x3c, - 0x8f, 0x62, 0xd2, 0x8c, 0xab, 0xad, 0x5c, 0xfd, 0x60, 0x18, 0x02, 0xec, 0x6c, 0x1a, 0x3a, 0x9d, - 0x44, 0x63, 0xdd, 0x29, 0xe9, 0x5a, 0x9c, 0xe4, 0xa8, 0xde, 0x29, 0xe1, 0x62, 0x55, 0xf6, 0xe9, - 0xf5, 0x7d, 0x27, 0x38, 0x8e, 0x46, 0x76, 0x59, 0x5e, 0xe7, 0x2e, 0xc5, 0x59, 0x2b, 0x6a, 0x03, - 0x1c, 0x54, 0x01, 0xfe, 0x5d, 0xcc, 0xc4, 0x12, 0xec, 0xe6, 0xfe, 0x46, 0x5c, 0x29, 0x93, 0xee, - 0x3e, 0xe0, 0x69, 0x60, 0xa7, 0xe7, 0xc3, 0xea, 0xa7, 0x6f, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, - 0xf6, 0x3d, 0x07, 0x73, 0x8c, 0x02, 0x00, 0x00, + // 317 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xa4, 0x92, 0xcd, 0x4a, 0xfb, 0x50, + 0x10, 0xc5, 0x49, 0xfb, 0xe7, 0x6f, 0x7b, 0x5b, 0x6d, 0xcd, 0xaa, 0x08, 0x6a, 0xad, 0x8b, 0x66, + 0xe3, 0x04, 0xe2, 0xc6, 0xb5, 0xdd, 0x8b, 0xa4, 0xdd, 0xe8, 0xa6, 0xc4, 0xdb, 0xb1, 0x04, 0xcd, + 0x9d, 0x30, 0x19, 0x3f, 0xf2, 0x16, 0x3e, 0x81, 0xcf, 0x2a, 0xf9, 0xb8, 0xa1, 0x14, 0x2d, 0x82, + 0xbb, 0x61, 0x38, 0xe7, 0xdc, 0x33, 0x3f, 0xae, 0x82, 0xd7, 0x80, 0xa3, 0x1c, 0x34, 0x25, 0xbe, + 0x26, 0x46, 0x5f, 0x38, 0x32, 0x59, 0x4a, 0x2c, 0x7e, 0x6c, 0x04, 0xd9, 0xa0, 0xf8, 0x9a, 0xcc, + 0x63, 0xbc, 0x86, 0x94, 0x49, 0xc8, 0x3d, 0xb6, 0x7a, 0x46, 0x68, 0xb4, 0x60, 0xb5, 0x47, 0xd3, + 0xad, 0x38, 0x4d, 0x49, 0x42, 0xc6, 0x2f, 0x62, 0x0c, 0xca, 0x1b, 0xf1, 0x53, 0x95, 0xf3, 0x93, + 0xf0, 0x99, 0xa2, 0x15, 0xb2, 0x2f, 0x79, 0x8a, 0x95, 0x70, 0xf2, 0xe1, 0xa8, 0xc1, 0x4d, 0x65, + 0x9d, 0xa3, 0x48, 0x6c, 0xd6, 0x99, 0x7b, 0xa5, 0xf6, 0xea, 0xb4, 0x91, 0x33, 0x76, 0xbc, 0x83, + 0xe0, 0x04, 0x36, 0x6a, 0x55, 0x51, 0x60, 0x50, 0xa0, 0x36, 0x86, 0x56, 0xee, 0xce, 0x54, 0x27, + 0xab, 0x53, 0x46, 0xad, 0xb1, 0xe3, 0xf5, 0x82, 0xe9, 0x37, 0xd6, 0xaa, 0x05, 0x2c, 0xf2, 0x14, + 0x57, 0xf6, 0xd1, 0xb0, 0x31, 0x4e, 0x3e, 0x5b, 0xaa, 0x3f, 0x17, 0xc6, 0x28, 0x99, 0x95, 0x68, + 0xfe, 0xd0, 0xe7, 0x4e, 0x0d, 0xeb, 0x71, 0xb9, 0xd1, 0xab, 0xed, 0xf5, 0x02, 0x80, 0x9d, 0xa4, + 0x61, 0x8b, 0x49, 0x38, 0x30, 0x5b, 0x90, 0xce, 0xd5, 0x7e, 0x86, 0xfa, 0x85, 0x63, 0xc9, 0x97, + 0x05, 0xcf, 0x51, 0x7b, 0xec, 0x78, 0xdd, 0xb0, 0x6f, 0x97, 0xc5, 0x75, 0xee, 0x42, 0x1d, 0x36, + 0xa2, 0xa6, 0xc0, 0xbf, 0xb2, 0xc0, 0xaf, 0xc1, 0x0c, 0x6d, 0x82, 0xdd, 0x4c, 0x4e, 0x55, 0xef, + 0x96, 0xe9, 0x3d, 0xaf, 0xf1, 0x0c, 0x55, 0x5b, 0xa2, 0x75, 0x89, 0xa6, 0x1b, 0x16, 0xe3, 0xf5, + 0x85, 0x3a, 0xd3, 0x94, 0xec, 0xbe, 0xf0, 0xbe, 0x63, 0xa7, 0x87, 0xff, 0xe5, 0x57, 0xb8, 0xfc, + 0x0a, 0x00, 0x00, 0xff, 0xff, 0xa6, 0xb6, 0x2f, 0xcf, 0xad, 0x02, 0x00, 0x00, } diff --git a/transport/internet/config.proto b/transport/internet/config.proto index b5cc8a6ea..d44a6b8af 100644 --- a/transport/internet/config.proto +++ b/transport/internet/config.proto @@ -25,4 +25,8 @@ message StreamConfig { string security_type = 3; repeated v2ray.core.common.loader.TypedSettings security_settings = 4; +} + +message ProxyConfig { + string tag = 1; } \ No newline at end of file diff --git a/transport/internet/dialer.go b/transport/internet/dialer.go index 45413b88c..be251db52 100644 --- a/transport/internet/dialer.go +++ b/transport/internet/dialer.go @@ -12,8 +12,8 @@ var ( ) type DialerOptions struct { - Stream *StreamConfig - ProxyTag string + Stream *StreamConfig + Proxy *ProxyConfig } type Dialer func(src v2net.Address, dest v2net.Destination, options DialerOptions) (Connection, error) @@ -28,7 +28,7 @@ var ( ) func Dial(src v2net.Address, dest v2net.Destination, options DialerOptions) (Connection, error) { - if len(options.ProxyTag) > 0 && ProxyDialer != nil { + if options.Proxy.HasTag() && ProxyDialer != nil { return ProxyDialer(src, dest, options) } diff --git a/v2ray.go b/v2ray.go index eb15977e5..d9651f3e5 100644 --- a/v2ray.go +++ b/v2ray.go @@ -5,6 +5,7 @@ import ( "v2ray.com/core/app/dispatcher" dispatchers "v2ray.com/core/app/dispatcher/impl" "v2ray.com/core/app/dns" + proxydialer "v2ray.com/core/app/proxy" "v2ray.com/core/app/proxyman" "v2ray.com/core/common" "v2ray.com/core/common/log" @@ -44,6 +45,10 @@ func NewPoint(pConfig *Config) (*Point, error) { outboundHandlerManager := proxyman.NewDefaultOutboundHandlerManager() vpoint.space.BindApp(proxyman.APP_ID_OUTBOUND_MANAGER, outboundHandlerManager) + proxyDialer := proxydialer.NewOutboundProxy(space) + proxyDialer.RegisterDialer() + space.BindApp(proxydialer.APP_ID, proxyDialer) + for _, app := range pConfig.App { settings, err := app.GetInstance() if err != nil { @@ -113,6 +118,7 @@ func NewPoint(pConfig *Config) (*Point, error) { Tag: outbound.Tag, Address: outbound.GetSendThroughValue(), StreamSettings: outbound.StreamSettings, + ProxySettings: outbound.ProxySettings, }) if err != nil { log.Error("Point: Failed to create detour outbound connection handler: ", err)