From 11220a495253cc49ec1a8d3173289f60024ab0f3 Mon Sep 17 00:00:00 2001 From: Darien Raymond Date: Fri, 4 Dec 2015 11:07:32 +0000 Subject: [PATCH 1/8] split vmess inbound and outbound --- proxy/vmess/{ => inbound}/inbound.go | 0 proxy/vmess/{ => outbound}/outbound.go | 2 +- proxy/vmess/vmess.go | 12 ++++++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) rename proxy/vmess/{ => inbound}/inbound.go (100%) rename proxy/vmess/{ => outbound}/outbound.go (99%) create mode 100644 proxy/vmess/vmess.go diff --git a/proxy/vmess/inbound.go b/proxy/vmess/inbound/inbound.go similarity index 100% rename from proxy/vmess/inbound.go rename to proxy/vmess/inbound/inbound.go diff --git a/proxy/vmess/outbound.go b/proxy/vmess/outbound/outbound.go similarity index 99% rename from proxy/vmess/outbound.go rename to proxy/vmess/outbound/outbound.go index b7277deb..e593431c 100644 --- a/proxy/vmess/outbound.go +++ b/proxy/vmess/outbound/outbound.go @@ -1,4 +1,4 @@ -package vmess +package outbound import ( "crypto/md5" diff --git a/proxy/vmess/vmess.go b/proxy/vmess/vmess.go new file mode 100644 index 00000000..51036d5c --- /dev/null +++ b/proxy/vmess/vmess.go @@ -0,0 +1,12 @@ +// Package vmess contains the implementation of VMess protocol and transportation. +// +// VMess contains both inbound and outbound connections. VMess inbound is usually used on servers +// together with 'freedom' to talk to final destination, while VMess outbound is usually used on +// clients with 'socks' for proxying. +package vmess + +// The actual implementation is in the following packages respectively. +import ( + _ "github.com/v2ray/v2ray-core/proxy/vmess/inbound" + _ "github.com/v2ray/v2ray-core/proxy/vmess/outbound" +) From 6bb53251e99d3968aabf453d2b5968de2bcd9902 Mon Sep 17 00:00:00 2001 From: Darien Raymond Date: Fri, 4 Dec 2015 11:42:56 +0000 Subject: [PATCH 2/8] handle response command in vmess outbound. --- proxy/vmess/inbound/inbound.go | 2 +- proxy/vmess/outbound/command.go | 5 +++++ proxy/vmess/outbound/outbound.go | 16 +++++++++++++++- 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 proxy/vmess/outbound/command.go diff --git a/proxy/vmess/inbound/inbound.go b/proxy/vmess/inbound/inbound.go index eabafcf0..8a29ded1 100644 --- a/proxy/vmess/inbound/inbound.go +++ b/proxy/vmess/inbound/inbound.go @@ -1,4 +1,4 @@ -package vmess +package inbound import ( "crypto/md5" diff --git a/proxy/vmess/outbound/command.go b/proxy/vmess/outbound/command.go new file mode 100644 index 00000000..8f141571 --- /dev/null +++ b/proxy/vmess/outbound/command.go @@ -0,0 +1,5 @@ +package outbound + +func handleCommand(command byte, data []byte) error { + return nil +} diff --git a/proxy/vmess/outbound/outbound.go b/proxy/vmess/outbound/outbound.go index e593431c..01b82e03 100644 --- a/proxy/vmess/outbound/outbound.go +++ b/proxy/vmess/outbound/outbound.go @@ -178,7 +178,21 @@ func handleResponse(conn net.Conn, request *protocol.VMessRequest, output chan<- } log.Info("VMessOut received %d bytes from %s", buffer.Len()-4, conn.RemoteAddr().String()) - buffer.SliceFrom(4) + responseBegin := 4 + if buffer.Value[2] != 0 { + dataLen := int(buffer.Value[3]) + if buffer.Len() < dataLen+4 { // Rare case + diffBuffer := make([]byte, dataLen+4-buffer.Len()) + v2net.ReadAllBytes(decryptResponseReader, diffBuffer) + buffer.Append(diffBuffer) + } + command := buffer.Value[2] + data := buffer.Value[4 : 4+dataLen] + go handleCommand(command, data) + responseBegin = 4 + dataLen + } + + buffer.SliceFrom(responseBegin) output <- buffer if !isUDP { From 394267937149170138661759c86259d9eedd9505 Mon Sep 17 00:00:00 2001 From: Darien Raymond Date: Fri, 4 Dec 2015 12:13:35 +0000 Subject: [PATCH 3/8] doc --- common/collect/timed_queue.go | 1 + 1 file changed, 1 insertion(+) diff --git a/common/collect/timed_queue.go b/common/collect/timed_queue.go index 291d8ad5..c8e16b9c 100644 --- a/common/collect/timed_queue.go +++ b/common/collect/timed_queue.go @@ -39,6 +39,7 @@ func (queue *timedQueueImpl) Pop() interface{} { return v } +// TimedQueue is a priority queue that entries with oldest timestamp get removed first. type TimedQueue struct { queue timedQueueImpl access sync.RWMutex From 223ff7d561d63daf6d5672fecba25d3a14296127 Mon Sep 17 00:00:00 2001 From: Darien Raymond Date: Fri, 4 Dec 2015 14:30:41 +0000 Subject: [PATCH 4/8] add error message --- shell/point/inbound_detour.go | 1 + 1 file changed, 1 insertion(+) diff --git a/shell/point/inbound_detour.go b/shell/point/inbound_detour.go index 4d405728..887a1a2d 100644 --- a/shell/point/inbound_detour.go +++ b/shell/point/inbound_detour.go @@ -50,6 +50,7 @@ func (this *InboundDetourHandler) Start() error { return retry.Timed(100 /* times */, 100 /* ms */).On(func() error { err := ich.handler.Listen(ich.port) if err != nil { + log.Error("Failed to start inbound detour on port %d: %v", ich.port, err) return err } return nil From 1a259319447debd0b8d8082f6112af7f62a6e818 Mon Sep 17 00:00:00 2001 From: Darien Raymond Date: Fri, 4 Dec 2015 15:49:10 +0000 Subject: [PATCH 5/8] advanced end 2 end test --- shell/point/inbound_detour.go | 5 +- testing/scenarios/data/test_1_client.json | 25 +++++ testing/scenarios/data/test_1_server.json | 18 ++++ testing/scenarios/data/test_2_client.json | 37 +++++++ testing/scenarios/data/test_2_server.json | 18 ++++ testing/scenarios/dokodemo_test.go | 56 ++++++++++ testing/scenarios/server_env.go | 51 +++++++++ testing/scenarios/socks5_helper.go | 124 ---------------------- testing/scenarios/socks_end_test.go | 37 ++++--- 9 files changed, 232 insertions(+), 139 deletions(-) create mode 100644 testing/scenarios/data/test_1_client.json create mode 100644 testing/scenarios/data/test_1_server.json create mode 100644 testing/scenarios/data/test_2_client.json create mode 100644 testing/scenarios/data/test_2_server.json create mode 100644 testing/scenarios/dokodemo_test.go create mode 100644 testing/scenarios/server_env.go diff --git a/shell/point/inbound_detour.go b/shell/point/inbound_detour.go index 887a1a2d..e672e07d 100644 --- a/shell/point/inbound_detour.go +++ b/shell/point/inbound_detour.go @@ -47,7 +47,7 @@ func (this *InboundDetourHandler) Initialize() error { // Starts the inbound connection handler. func (this *InboundDetourHandler) Start() error { for _, ich := range this.ich { - return retry.Timed(100 /* times */, 100 /* ms */).On(func() error { + err := retry.Timed(100 /* times */, 100 /* ms */).On(func() error { err := ich.handler.Listen(ich.port) if err != nil { log.Error("Failed to start inbound detour on port %d: %v", ich.port, err) @@ -55,6 +55,9 @@ func (this *InboundDetourHandler) Start() error { } return nil }) + if err != nil { + return err + } } return nil } diff --git a/testing/scenarios/data/test_1_client.json b/testing/scenarios/data/test_1_client.json new file mode 100644 index 00000000..bc96091a --- /dev/null +++ b/testing/scenarios/data/test_1_client.json @@ -0,0 +1,25 @@ +{ + "port": 50000, + "inbound": { + "protocol": "socks", + "settings": { + "auth": "noauth", + "udp": false, + "ip": "127.0.0.1" + } + }, + "outbound": { + "protocol": "vmess", + "settings": { + "vnext": [ + { + "address": "127.0.0.1", + "port": 50001, + "users": [ + {"id": "d17a1af7-efa5-42ca-b7e9-6a35282d737f"} + ] + } + ] + } + } +} diff --git a/testing/scenarios/data/test_1_server.json b/testing/scenarios/data/test_1_server.json new file mode 100644 index 00000000..1e3d1c86 --- /dev/null +++ b/testing/scenarios/data/test_1_server.json @@ -0,0 +1,18 @@ +{ + "port": 50001, + "inbound": { + "protocol": "vmess", + "settings": { + "clients": [ + { + "id": "d17a1af7-efa5-42ca-b7e9-6a35282d737f", + "level": 1 + } + ] + } + }, + "outbound": { + "protocol": "freedom", + "settings": {} + } +} diff --git a/testing/scenarios/data/test_2_client.json b/testing/scenarios/data/test_2_client.json new file mode 100644 index 00000000..84e81a2e --- /dev/null +++ b/testing/scenarios/data/test_2_client.json @@ -0,0 +1,37 @@ +{ + "port": 50010, + "inbound": { + "protocol": "socks", + "settings": { + "auth": "noauth", + "udp": false, + "ip": "127.0.0.1" + } + }, + "outbound": { + "protocol": "vmess", + "settings": { + "vnext": [ + { + "address": "127.0.0.1", + "port": 50017, + "users": [ + {"id": "d17a1af7-efa5-42ca-b7e9-6a35282d737f"} + ] + } + ] + } + }, + "inboundDetour": [ + { + "protocol": "dokodemo-door", + "port": "50011-50015", + "settings": { + "address": "127.0.0.1", + "port": 50016, + "network": "tcp", + "timeout": 0 + } + } + ] +} diff --git a/testing/scenarios/data/test_2_server.json b/testing/scenarios/data/test_2_server.json new file mode 100644 index 00000000..3efc9fb9 --- /dev/null +++ b/testing/scenarios/data/test_2_server.json @@ -0,0 +1,18 @@ +{ + "port": 50017, + "inbound": { + "protocol": "vmess", + "settings": { + "clients": [ + { + "id": "d17a1af7-efa5-42ca-b7e9-6a35282d737f", + "level": 1 + } + ] + } + }, + "outbound": { + "protocol": "freedom", + "settings": {} + } +} diff --git a/testing/scenarios/dokodemo_test.go b/testing/scenarios/dokodemo_test.go new file mode 100644 index 00000000..9c3950e8 --- /dev/null +++ b/testing/scenarios/dokodemo_test.go @@ -0,0 +1,56 @@ +package scenarios + +import ( + "net" + "testing" + + v2net "github.com/v2ray/v2ray-core/common/net" + v2testing "github.com/v2ray/v2ray-core/testing" + "github.com/v2ray/v2ray-core/testing/assert" + "github.com/v2ray/v2ray-core/testing/servers/tcp" +) + +func TestDokodemoTCP(t *testing.T) { + v2testing.Current(t) + + tcpServer := &tcp.Server{ + Port: v2net.Port(50016), + MsgProcessor: func(data []byte) []byte { + buffer := make([]byte, 0, 2048) + buffer = append(buffer, []byte("Processed: ")...) + buffer = append(buffer, data...) + return buffer + }, + } + _, err := tcpServer.Start() + assert.Error(err).IsNil() + + err = InitializeServer(TestFile("test_2_client.json")) + assert.Error(err).IsNil() + + err = InitializeServer(TestFile("test_2_server.json")) + assert.Error(err).IsNil() + + dokodemoPortStart := v2net.Port(50011) + dokodemoPortEnd := v2net.Port(50015) + + for port := dokodemoPortStart; port <= dokodemoPortEnd; port++ { + conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{ + IP: []byte{127, 0, 0, 1}, + Port: int(port), + }) + + payload := "dokodemo request." + nBytes, err := conn.Write([]byte(payload)) + assert.Error(err).IsNil() + assert.Int(nBytes).Equals(len(payload)) + + conn.CloseWrite() + + response := make([]byte, 1024) + nBytes, err = conn.Read(response) + assert.Error(err).IsNil() + assert.StringLiteral("Processed: " + payload).Equals(string(response[:nBytes])) + conn.Close() + } +} \ No newline at end of file diff --git a/testing/scenarios/server_env.go b/testing/scenarios/server_env.go new file mode 100644 index 00000000..2caff550 --- /dev/null +++ b/testing/scenarios/server_env.go @@ -0,0 +1,51 @@ +package scenarios + +import ( + "os" + "path/filepath" + + _ "github.com/v2ray/v2ray-core/app/router/config/json" + _ "github.com/v2ray/v2ray-core/app/router/rules" + _ "github.com/v2ray/v2ray-core/app/router/rules/config/json" + "github.com/v2ray/v2ray-core/common/log" + "github.com/v2ray/v2ray-core/shell/point" + jsonconf "github.com/v2ray/v2ray-core/shell/point/config/json" + + // The following are neccesary as they register handlers in their init functions. + _ "github.com/v2ray/v2ray-core/proxy/blackhole" + _ "github.com/v2ray/v2ray-core/proxy/blackhole/config/json" + _ "github.com/v2ray/v2ray-core/proxy/dokodemo" + _ "github.com/v2ray/v2ray-core/proxy/dokodemo/config/json" + _ "github.com/v2ray/v2ray-core/proxy/freedom" + _ "github.com/v2ray/v2ray-core/proxy/freedom/config/json" + _ "github.com/v2ray/v2ray-core/proxy/socks" + _ "github.com/v2ray/v2ray-core/proxy/socks/config/json" + _ "github.com/v2ray/v2ray-core/proxy/vmess" + _ "github.com/v2ray/v2ray-core/proxy/vmess/config/json" +) + +func TestFile(filename string) string { + return filepath.Join(os.Getenv("GOPATH"), "src", "github.com", "v2ray", "v2ray-core", "testing", "scenarios", "data", filename) +} + +func InitializeServer(configFile string) error { + config, err := jsonconf.LoadConfig(configFile) + if err != nil { + log.Error("Failed to read config file (%s): %v", configFile, err) + return err + } + + vPoint, err := point.NewPoint(config) + if err != nil { + log.Error("Failed to create Point server: %v", err) + return err + } + + err = vPoint.Start() + if err != nil { + log.Error("Error starting Point server: %v", err) + return err + } + + return nil +} diff --git a/testing/scenarios/socks5_helper.go b/testing/scenarios/socks5_helper.go index 54c4cf85..0faceb70 100644 --- a/testing/scenarios/socks5_helper.go +++ b/testing/scenarios/socks5_helper.go @@ -1,21 +1,7 @@ package scenarios import ( - "net" - - routerconfig "github.com/v2ray/v2ray-core/app/router/config/testing" - _ "github.com/v2ray/v2ray-core/app/router/rules" - rulesconfig "github.com/v2ray/v2ray-core/app/router/rules/config/testing" v2net "github.com/v2ray/v2ray-core/common/net" - v2nettesting "github.com/v2ray/v2ray-core/common/net/testing" - _ "github.com/v2ray/v2ray-core/proxy/freedom" - _ "github.com/v2ray/v2ray-core/proxy/socks" - socksjson "github.com/v2ray/v2ray-core/proxy/socks/config/json" - _ "github.com/v2ray/v2ray-core/proxy/vmess" - "github.com/v2ray/v2ray-core/proxy/vmess/config" - vmessjson "github.com/v2ray/v2ray-core/proxy/vmess/config/json" - "github.com/v2ray/v2ray-core/shell/point" - "github.com/v2ray/v2ray-core/shell/point/config/testing/mocks" ) const ( @@ -60,113 +46,3 @@ func socks5UDPRequest(address v2net.Address, payload []byte) []byte { request = append(request, payload...) return request } - -func setUpV2Ray(routing func(v2net.Destination) bool) (v2net.Port, v2net.Port, error) { - id1, err := config.NewID("ad937d9d-6e23-4a5a-ba23-bce5092a7c51") - if err != nil { - return 0, 0, err - } - id2, err := config.NewID("93ccfc71-b136-4015-ac85-e037bd1ead9e") - if err != nil { - return 0, 0, err - } - users := []*vmessjson.ConfigUser{ - &vmessjson.ConfigUser{Id: id1}, - &vmessjson.ConfigUser{Id: id2}, - } - - portB := v2nettesting.PickPort() - configB := mocks.Config{ - PortValue: portB, - InboundConfigValue: &mocks.ConnectionConfig{ - ProtocolValue: "vmess", - SettingsValue: &vmessjson.Inbound{ - AllowedClients: users, - }, - }, - OutboundConfigValue: &mocks.ConnectionConfig{ - ProtocolValue: "freedom", - SettingsValue: nil, - }, - } - pointB, err := point.NewPoint(&configB) - if err != nil { - return 0, 0, err - } - err = pointB.Start() - if err != nil { - return 0, 0, err - } - - portA := v2nettesting.PickPort() - portA2 := v2nettesting.PickPort() - configA := mocks.Config{ - PortValue: portA, - InboundConfigValue: &mocks.ConnectionConfig{ - ProtocolValue: "socks", - SettingsValue: &socksjson.SocksConfig{ - AuthMethod: "noauth", - UDP: true, - HostIP: socksjson.IPAddress(net.IPv4(127, 0, 0, 1)), - }, - }, - OutboundConfigValue: &mocks.ConnectionConfig{ - ProtocolValue: "vmess", - SettingsValue: &vmessjson.Outbound{ - []*vmessjson.ConfigTarget{ - &vmessjson.ConfigTarget{ - Address: v2net.IPAddress([]byte{127, 0, 0, 1}, portB), - Users: users, - }, - }, - }, - }, - InboundDetoursValue: []*mocks.InboundDetourConfig{ - &mocks.InboundDetourConfig{ - PortRangeValue: &mocks.PortRange{ - FromValue: portA2, - ToValue: portA2, - }, - ConnectionConfig: &mocks.ConnectionConfig{ - ProtocolValue: "socks", - SettingsValue: &socksjson.SocksConfig{ - AuthMethod: "noauth", - UDP: false, - HostIP: socksjson.IPAddress(net.IPv4(127, 0, 0, 1)), - }, - }, - }, - }, - OutboundDetoursValue: []*mocks.OutboundDetourConfig{ - &mocks.OutboundDetourConfig{ - TagValue: "direct", - ConnectionConfig: &mocks.ConnectionConfig{ - ProtocolValue: "freedom", - SettingsValue: nil, - }, - }, - }, - RouterConfigValue: &routerconfig.RouterConfig{ - StrategyValue: "rules", - SettingsValue: &rulesconfig.RouterRuleConfig{ - RuleList: []*rulesconfig.TestRule{ - &rulesconfig.TestRule{ - TagValue: "direct", - Function: routing, - }, - }, - }, - }, - } - - pointA, err := point.NewPoint(&configA) - if err != nil { - return 0, 0, err - } - err = pointA.Start() - if err != nil { - return 0, 0, err - } - - return portA, portA2, nil -} diff --git a/testing/scenarios/socks_end_test.go b/testing/scenarios/socks_end_test.go index 3553d5b3..97e7d43a 100644 --- a/testing/scenarios/socks_end_test.go +++ b/testing/scenarios/socks_end_test.go @@ -12,12 +12,6 @@ import ( "github.com/v2ray/v2ray-core/testing/servers/udp" ) -var ( - EmptyRouting = func(v2net.Destination) bool { - return false - } -) - func TestTCPConnection(t *testing.T) { v2testing.Current(t) @@ -34,13 +28,18 @@ func TestTCPConnection(t *testing.T) { _, err := tcpServer.Start() assert.Error(err).IsNil() - v2rayPort, _, err := setUpV2Ray(EmptyRouting) + err = InitializeServer(TestFile("test_1_client.json")) assert.Error(err).IsNil() + err = InitializeServer(TestFile("test_1_server.json")) + assert.Error(err).IsNil() + + socksPort := v2net.Port(50000) + for i := 0; i < 100; i++ { conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{ IP: []byte{127, 0, 0, 1}, - Port: int(v2rayPort), + Port: int(socksPort), }) authRequest := socks5AuthMethodRequest(byte(0)) @@ -100,12 +99,17 @@ func TestTCPBind(t *testing.T) { _, err := tcpServer.Start() assert.Error(err).IsNil() - v2rayPort, _, err := setUpV2Ray(EmptyRouting) + err = InitializeServer(TestFile("test_1_client.json")) assert.Error(err).IsNil() + err = InitializeServer(TestFile("test_1_server.json")) + assert.Error(err).IsNil() + + socksPort := v2net.Port(50000) + conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{ IP: []byte{127, 0, 0, 1}, - Port: int(v2rayPort), + Port: int(socksPort), }) authRequest := socks5AuthMethodRequest(byte(0)) @@ -147,12 +151,17 @@ func TestUDPAssociate(t *testing.T) { _, err := udpServer.Start() assert.Error(err).IsNil() - v2rayPort, _, err := setUpV2Ray(EmptyRouting) + err = InitializeServer(TestFile("test_1_client.json")) assert.Error(err).IsNil() + err = InitializeServer(TestFile("test_1_server.json")) + assert.Error(err).IsNil() + + socksPort := v2net.Port(50000) + conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{ IP: []byte{127, 0, 0, 1}, - Port: int(v2rayPort), + Port: int(socksPort), }) authRequest := socks5AuthMethodRequest(byte(0)) @@ -173,11 +182,11 @@ func TestUDPAssociate(t *testing.T) { connectResponse := make([]byte, 1024) nBytes, err = conn.Read(connectResponse) assert.Error(err).IsNil() - assert.Bytes(connectResponse[:nBytes]).Equals([]byte{socks5Version, 0, 0, 1, 127, 0, 0, 1, byte(v2rayPort >> 8), byte(v2rayPort)}) + assert.Bytes(connectResponse[:nBytes]).Equals([]byte{socks5Version, 0, 0, 1, 127, 0, 0, 1, byte(socksPort >> 8), byte(socksPort)}) udpConn, err := net.DialUDP("udp", nil, &net.UDPAddr{ IP: []byte{127, 0, 0, 1}, - Port: int(v2rayPort), + Port: int(socksPort), }) assert.Error(err).IsNil() From 3327cb0b8030528745a15b380f4eef3f02ac1ac3 Mon Sep 17 00:00:00 2001 From: Darien Raymond Date: Fri, 4 Dec 2015 15:49:45 +0000 Subject: [PATCH 6/8] format code --- shell/point/inbound_detour.go | 2 +- testing/scenarios/dokodemo_test.go | 2 +- testing/scenarios/server_env.go | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/shell/point/inbound_detour.go b/shell/point/inbound_detour.go index e672e07d..27b752f7 100644 --- a/shell/point/inbound_detour.go +++ b/shell/point/inbound_detour.go @@ -56,7 +56,7 @@ func (this *InboundDetourHandler) Start() error { return nil }) if err != nil { - return err + return err } } return nil diff --git a/testing/scenarios/dokodemo_test.go b/testing/scenarios/dokodemo_test.go index 9c3950e8..7d4f6fe1 100644 --- a/testing/scenarios/dokodemo_test.go +++ b/testing/scenarios/dokodemo_test.go @@ -53,4 +53,4 @@ func TestDokodemoTCP(t *testing.T) { assert.StringLiteral("Processed: " + payload).Equals(string(response[:nBytes])) conn.Close() } -} \ No newline at end of file +} diff --git a/testing/scenarios/server_env.go b/testing/scenarios/server_env.go index 2caff550..7333d751 100644 --- a/testing/scenarios/server_env.go +++ b/testing/scenarios/server_env.go @@ -1,8 +1,8 @@ package scenarios import ( - "os" - "path/filepath" + "os" + "path/filepath" _ "github.com/v2ray/v2ray-core/app/router/config/json" _ "github.com/v2ray/v2ray-core/app/router/rules" @@ -25,11 +25,11 @@ import ( ) func TestFile(filename string) string { - return filepath.Join(os.Getenv("GOPATH"), "src", "github.com", "v2ray", "v2ray-core", "testing", "scenarios", "data", filename) + return filepath.Join(os.Getenv("GOPATH"), "src", "github.com", "v2ray", "v2ray-core", "testing", "scenarios", "data", filename) } func InitializeServer(configFile string) error { - config, err := jsonconf.LoadConfig(configFile) + config, err := jsonconf.LoadConfig(configFile) if err != nil { log.Error("Failed to read config file (%s): %v", configFile, err) return err From 30be218c62eef5b598bba252bf5553f4d5fbda23 Mon Sep 17 00:00:00 2001 From: Darien Raymond Date: Fri, 4 Dec 2015 16:01:39 +0000 Subject: [PATCH 7/8] fix test break --- testing/scenarios/data/test_1_client.json | 2 +- testing/scenarios/socks_end_test.go | 40 ++++++++++++++--------- 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/testing/scenarios/data/test_1_client.json b/testing/scenarios/data/test_1_client.json index bc96091a..c833e891 100644 --- a/testing/scenarios/data/test_1_client.json +++ b/testing/scenarios/data/test_1_client.json @@ -4,7 +4,7 @@ "protocol": "socks", "settings": { "auth": "noauth", - "udp": false, + "udp": true, "ip": "127.0.0.1" } }, diff --git a/testing/scenarios/socks_end_test.go b/testing/scenarios/socks_end_test.go index 97e7d43a..66108681 100644 --- a/testing/scenarios/socks_end_test.go +++ b/testing/scenarios/socks_end_test.go @@ -12,6 +12,28 @@ import ( "github.com/v2ray/v2ray-core/testing/servers/udp" ) +var ( + serverUp = false +) + +func setupServer() error { + if serverUp { + return nil + } + err := InitializeServer(TestFile("test_1_client.json")) + if err != nil { + return err + } + + err = InitializeServer(TestFile("test_1_server.json")) + if err != nil { + return err + } + + serverUp = true + return nil +} + func TestTCPConnection(t *testing.T) { v2testing.Current(t) @@ -28,11 +50,7 @@ func TestTCPConnection(t *testing.T) { _, err := tcpServer.Start() assert.Error(err).IsNil() - err = InitializeServer(TestFile("test_1_client.json")) - assert.Error(err).IsNil() - - err = InitializeServer(TestFile("test_1_server.json")) - assert.Error(err).IsNil() + assert.Error(setupServer()).IsNil() socksPort := v2net.Port(50000) @@ -99,11 +117,7 @@ func TestTCPBind(t *testing.T) { _, err := tcpServer.Start() assert.Error(err).IsNil() - err = InitializeServer(TestFile("test_1_client.json")) - assert.Error(err).IsNil() - - err = InitializeServer(TestFile("test_1_server.json")) - assert.Error(err).IsNil() + assert.Error(setupServer()).IsNil() socksPort := v2net.Port(50000) @@ -151,11 +165,7 @@ func TestUDPAssociate(t *testing.T) { _, err := udpServer.Start() assert.Error(err).IsNil() - err = InitializeServer(TestFile("test_1_client.json")) - assert.Error(err).IsNil() - - err = InitializeServer(TestFile("test_1_server.json")) - assert.Error(err).IsNil() + assert.Error(setupServer()).IsNil() socksPort := v2net.Port(50000) From 5ec30c3ad03d88f56747b0064e3d4c1b6bfa35b4 Mon Sep 17 00:00:00 2001 From: Darien Raymond Date: Fri, 4 Dec 2015 16:32:42 +0000 Subject: [PATCH 8/8] more test cases --- testing/scenarios/data/test_1_client.json | 74 +++++++++++++++++++++- testing/scenarios/data/test_1_server.json | 16 ++++- testing/scenarios/data/test_3_client.json | 57 +++++++++++++++++ testing/scenarios/data/test_3_server.json | 18 ++++++ testing/scenarios/dokodemo_test.go | 6 +- testing/scenarios/router_test.go | 77 +++++++++++++++++++++++ testing/scenarios/server_env.go | 20 ++++++ testing/scenarios/socks_end_test.go | 24 +------ 8 files changed, 264 insertions(+), 28 deletions(-) create mode 100644 testing/scenarios/data/test_3_client.json create mode 100644 testing/scenarios/data/test_3_server.json create mode 100644 testing/scenarios/router_test.go diff --git a/testing/scenarios/data/test_1_client.json b/testing/scenarios/data/test_1_client.json index c833e891..6c26e904 100644 --- a/testing/scenarios/data/test_1_client.json +++ b/testing/scenarios/data/test_1_client.json @@ -21,5 +21,77 @@ } ] } - } + }, + "outboundDetour": [ + { + "protocol": "vmess", + "settings": { + "vnext": [ + { + "address": "127.0.0.1", + "port": 50005, + "users": [ + {"id": "d17a1af7-efa5-42ca-b7e9-6a35282d737f"} + ] + } + ] + } + }, + { + "protocol": "vmess", + "settings": { + "vnext": [ + { + "address": "127.0.0.1", + "port": 50006, + "users": [ + {"id": "d17a1af7-efa5-42ca-b7e9-6a35282d737f"} + ] + } + ] + } + }, + { + "protocol": "vmess", + "settings": { + "vnext": [ + { + "address": "127.0.0.1", + "port": 50007, + "users": [ + {"id": "d17a1af7-efa5-42ca-b7e9-6a35282d737f"} + ] + } + ] + } + }, + { + "protocol": "vmess", + "settings": { + "vnext": [ + { + "address": "127.0.0.1", + "port": 50008, + "users": [ + {"id": "d17a1af7-efa5-42ca-b7e9-6a35282d737f"} + ] + } + ] + } + }, + { + "protocol": "vmess", + "settings": { + "vnext": [ + { + "address": "127.0.0.1", + "port": 50009, + "users": [ + {"id": "d17a1af7-efa5-42ca-b7e9-6a35282d737f"} + ] + } + ] + } + } + ] } diff --git a/testing/scenarios/data/test_1_server.json b/testing/scenarios/data/test_1_server.json index 1e3d1c86..36841edc 100644 --- a/testing/scenarios/data/test_1_server.json +++ b/testing/scenarios/data/test_1_server.json @@ -14,5 +14,19 @@ "outbound": { "protocol": "freedom", "settings": {} - } + }, + "inboundDetour": [ + { + "protocol": "vmess", + "port": "50005-50009", + "settings": { + "clients": [ + { + "id": "d17a1af7-efa5-42ca-b7e9-6a35282d737f", + "level": 1 + } + ] + } + } + ] } diff --git a/testing/scenarios/data/test_3_client.json b/testing/scenarios/data/test_3_client.json new file mode 100644 index 00000000..60f3d8f2 --- /dev/null +++ b/testing/scenarios/data/test_3_client.json @@ -0,0 +1,57 @@ +{ + "port": 50020, + "inbound": { + "protocol": "dokodemo-door", + "settings": { + "address": "127.0.0.1", + "port": 50024, + "network": "tcp", + "timeout": 0 + } + }, + "outbound": { + "protocol": "vmess", + "settings": { + "vnext": [ + { + "address": "127.0.0.1", + "port": 50021, + "users": [ + {"id": "d17a1af7-efa5-42ca-b7e9-6a35282d737f"} + ] + } + ] + } + }, + "inboundDetour": [ + { + "protocol": "dokodemo-door", + "port": 50022, + "settings": { + "address": "127.0.0.1", + "port": 50025, + "network": "tcp", + "timeout": 0 + } + } + ], + "outboundDetour": [ + { + "protocol": "blackhole", + "tag": "blocked", + "settings": {} + } + ], + "routing": { + "strategy": "rules", + "settings": { + "rules": [ + { + "type": "field", + "port": "50025-50029", + "outboundTag": "blocked" + } + ] + } + } +} diff --git a/testing/scenarios/data/test_3_server.json b/testing/scenarios/data/test_3_server.json new file mode 100644 index 00000000..d3f21ea6 --- /dev/null +++ b/testing/scenarios/data/test_3_server.json @@ -0,0 +1,18 @@ +{ + "port": 50021, + "inbound": { + "protocol": "vmess", + "settings": { + "clients": [ + { + "id": "d17a1af7-efa5-42ca-b7e9-6a35282d737f", + "level": 1 + } + ] + } + }, + "outbound": { + "protocol": "freedom", + "settings": {} + } +} diff --git a/testing/scenarios/dokodemo_test.go b/testing/scenarios/dokodemo_test.go index 7d4f6fe1..26eaf938 100644 --- a/testing/scenarios/dokodemo_test.go +++ b/testing/scenarios/dokodemo_test.go @@ -25,11 +25,7 @@ func TestDokodemoTCP(t *testing.T) { _, err := tcpServer.Start() assert.Error(err).IsNil() - err = InitializeServer(TestFile("test_2_client.json")) - assert.Error(err).IsNil() - - err = InitializeServer(TestFile("test_2_server.json")) - assert.Error(err).IsNil() + assert.Error(InitializeServerSetOnce("test_2")).IsNil() dokodemoPortStart := v2net.Port(50011) dokodemoPortEnd := v2net.Port(50015) diff --git a/testing/scenarios/router_test.go b/testing/scenarios/router_test.go new file mode 100644 index 00000000..831fb2e8 --- /dev/null +++ b/testing/scenarios/router_test.go @@ -0,0 +1,77 @@ +package scenarios + +import ( + "net" + "testing" + + v2net "github.com/v2ray/v2ray-core/common/net" + v2testing "github.com/v2ray/v2ray-core/testing" + "github.com/v2ray/v2ray-core/testing/assert" + "github.com/v2ray/v2ray-core/testing/servers/tcp" +) + +func TestRouter(t *testing.T) { + v2testing.Current(t) + + tcpServer := &tcp.Server{ + Port: v2net.Port(50024), + MsgProcessor: func(data []byte) []byte { + buffer := make([]byte, 0, 2048) + buffer = append(buffer, []byte("Processed: ")...) + buffer = append(buffer, data...) + return buffer + }, + } + _, err := tcpServer.Start() + assert.Error(err).IsNil() + + tcpServer2Accessed := false + tcpServer2 := &tcp.Server{ + Port: v2net.Port(50025), + MsgProcessor: func(data []byte) []byte { + tcpServer2Accessed = true + return data + }, + } + _, err = tcpServer2.Start() + assert.Error(err).IsNil() + + assert.Error(InitializeServerSetOnce("test_3")).IsNil() + + conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{ + IP: []byte{127, 0, 0, 1}, + Port: int(50020), + }) + + payload := "direct dokodemo request." + nBytes, err := conn.Write([]byte(payload)) + assert.Error(err).IsNil() + assert.Int(nBytes).Equals(len(payload)) + + conn.CloseWrite() + + response := make([]byte, 1024) + nBytes, err = conn.Read(response) + assert.Error(err).IsNil() + assert.StringLiteral("Processed: " + payload).Equals(string(response[:nBytes])) + conn.Close() + + conn, err = net.DialTCP("tcp", nil, &net.TCPAddr{ + IP: []byte{127, 0, 0, 1}, + Port: int(50022), + }) + + payload = "blocked dokodemo request." + nBytes, err = conn.Write([]byte(payload)) + assert.Error(err).IsNil() + assert.Int(nBytes).Equals(len(payload)) + + conn.CloseWrite() + + response = make([]byte, 1024) + nBytes, err = conn.Read(response) + assert.Error(err).IsNotNil() + assert.Int(nBytes).Equals(0) + assert.Bool(tcpServer2Accessed).IsFalse() + conn.Close() +} diff --git a/testing/scenarios/server_env.go b/testing/scenarios/server_env.go index 7333d751..2d8489f4 100644 --- a/testing/scenarios/server_env.go +++ b/testing/scenarios/server_env.go @@ -24,10 +24,30 @@ import ( _ "github.com/v2ray/v2ray-core/proxy/vmess/config/json" ) +var ( + serverup = make(map[string]bool) +) + func TestFile(filename string) string { return filepath.Join(os.Getenv("GOPATH"), "src", "github.com", "v2ray", "v2ray-core", "testing", "scenarios", "data", filename) } +func InitializeServerSetOnce(testcase string) error { + if up, found := serverup[testcase]; found && up { + return nil + } + err := InitializeServer(TestFile(testcase + "_server.json")) + if err != nil { + return err + } + err = InitializeServer(TestFile(testcase + "_client.json")) + if err != nil { + return err + } + serverup[testcase] = true + return nil +} + func InitializeServer(configFile string) error { config, err := jsonconf.LoadConfig(configFile) if err != nil { diff --git a/testing/scenarios/socks_end_test.go b/testing/scenarios/socks_end_test.go index 66108681..c8b58e02 100644 --- a/testing/scenarios/socks_end_test.go +++ b/testing/scenarios/socks_end_test.go @@ -16,24 +16,6 @@ var ( serverUp = false ) -func setupServer() error { - if serverUp { - return nil - } - err := InitializeServer(TestFile("test_1_client.json")) - if err != nil { - return err - } - - err = InitializeServer(TestFile("test_1_server.json")) - if err != nil { - return err - } - - serverUp = true - return nil -} - func TestTCPConnection(t *testing.T) { v2testing.Current(t) @@ -50,7 +32,7 @@ func TestTCPConnection(t *testing.T) { _, err := tcpServer.Start() assert.Error(err).IsNil() - assert.Error(setupServer()).IsNil() + assert.Error(InitializeServerSetOnce("test_1")).IsNil() socksPort := v2net.Port(50000) @@ -117,7 +99,7 @@ func TestTCPBind(t *testing.T) { _, err := tcpServer.Start() assert.Error(err).IsNil() - assert.Error(setupServer()).IsNil() + assert.Error(InitializeServerSetOnce("test_1")).IsNil() socksPort := v2net.Port(50000) @@ -165,7 +147,7 @@ func TestUDPAssociate(t *testing.T) { _, err := udpServer.Start() assert.Error(err).IsNil() - assert.Error(setupServer()).IsNil() + assert.Error(InitializeServerSetOnce("test_1")).IsNil() socksPort := v2net.Port(50000)