From 5347673e007a55e3dcdeda3f77d6fd4226f5ea18 Mon Sep 17 00:00:00 2001 From: V2Ray Date: Fri, 6 Nov 2015 13:45:41 +0100 Subject: [PATCH] test case for socks udp --- testing/coverage/coverall | 3 +- testing/scenarios/socks5_helper.go | 101 ++++++++++++- testing/scenarios/socks_end_test.go | 219 +++++++++++++--------------- 3 files changed, 204 insertions(+), 119 deletions(-) diff --git a/testing/coverage/coverall b/testing/coverage/coverall index 1e98c2634..54d6b44f0 100755 --- a/testing/coverage/coverall +++ b/testing/coverage/coverall @@ -5,8 +5,7 @@ FAIL=0 function test_package { DIR="github.com/v2ray/v2ray-core/$1" DEP=$(go list -f '{{ join .Deps "\n" }}' $DIR | grep v2ray | tr '\n' ',') - DEPTEST=$(go list -f '{{ join .TestImports "\n" }}' $DIR | grep v2ray | tr '\n' ',') - DEP=${DEP}${DEPTEST}$DIR + DEP=${DEP}$DIR go test -coverprofile=coversingle.out -coverpkg=$DEP $DIR || FAIL=1 if [ -f coversingle.out ]; then cat coversingle.out | grep -v "mode: set" >> coverall.out diff --git a/testing/scenarios/socks5_helper.go b/testing/scenarios/socks5_helper.go index ca18bc51c..357e133ec 100644 --- a/testing/scenarios/socks5_helper.go +++ b/testing/scenarios/socks5_helper.go @@ -1,7 +1,18 @@ package scenarios import ( + "net" + + "github.com/v2ray/v2ray-core/app/point" + "github.com/v2ray/v2ray-core/app/point/config/testing/mocks" 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" ) const ( @@ -14,8 +25,7 @@ func socks5AuthMethodRequest(methods ...byte) []byte { return request } -func socks5Request(command byte, address v2net.Address) []byte { - request := []byte{socks5Version, command, 0} +func appendAddress(request []byte, address v2net.Address) []byte { switch { case address.IsIPv4(): request = append(request, byte(0x01)) @@ -33,3 +43,90 @@ func socks5Request(command byte, address v2net.Address) []byte { request = append(request, address.PortBytes()...) return request } + +func socks5Request(command byte, address v2net.Address) []byte { + request := []byte{socks5Version, command, 0} + request = appendAddress(request, address) + return request +} + +func socks5UDPRequest(address v2net.Address, payload []byte) []byte { + request := make([]byte, 0, 1024) + request = append(request, 0, 0, 0) + request = appendAddress(request, address) + request = append(request, payload...) + return request +} + +func setUpV2Ray() (uint16, error) { + id1, err := config.NewID("ad937d9d-6e23-4a5a-ba23-bce5092a7c51") + if err != nil { + return 0, err + } + id2, err := config.NewID("93ccfc71-b136-4015-ac85-e037bd1ead9e") + if err != nil { + return 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, err + } + err = pointB.Start() + if err != nil { + return 0, err + } + + portA := v2nettesting.PickPort() + configA := mocks.Config{ + PortValue: portA, + InboundConfigValue: &mocks.ConnectionConfig{ + ProtocolValue: "socks", + SettingsValue: &socksjson.SocksConfig{ + AuthMethod: "noauth", + UDPEnabled: 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, + }, + }, + }, + }, + } + + pointA, err := point.NewPoint(&configA) + if err != nil { + return 0, err + } + err = pointA.Start() + if err != nil { + return 0, err + } + + return portA, nil +} diff --git a/testing/scenarios/socks_end_test.go b/testing/scenarios/socks_end_test.go index e6d0561c4..993ec3e08 100644 --- a/testing/scenarios/socks_end_test.go +++ b/testing/scenarios/socks_end_test.go @@ -4,93 +4,13 @@ import ( "net" "testing" - "github.com/v2ray/v2ray-core/app/point" - "github.com/v2ray/v2ray-core/app/point/config/testing/mocks" 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/testing/servers/tcp" + "github.com/v2ray/v2ray-core/testing/servers/udp" "github.com/v2ray/v2ray-core/testing/unit" ) -func setUpV2Ray() (uint16, error) { - id1, err := config.NewID("ad937d9d-6e23-4a5a-ba23-bce5092a7c51") - if err != nil { - return 0, err - } - id2, err := config.NewID("93ccfc71-b136-4015-ac85-e037bd1ead9e") - if err != nil { - return 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, err - } - err = pointB.Start() - if err != nil { - return 0, err - } - - portA := v2nettesting.PickPort() - configA := mocks.Config{ - PortValue: portA, - InboundConfigValue: &mocks.ConnectionConfig{ - ProtocolValue: "socks", - SettingsValue: &socksjson.SocksConfig{ - AuthMethod: "noauth", - UDPEnabled: 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, - }, - }, - }, - }, - } - - pointA, err := point.NewPoint(&configA) - if err != nil { - return 0, err - } - err = pointA.Start() - if err != nil { - return 0, err - } - - return portA, nil -} - func TestTCPConnection(t *testing.T) { assert := unit.Assert(t) @@ -110,49 +30,51 @@ func TestTCPConnection(t *testing.T) { v2rayPort, err := setUpV2Ray() assert.Error(err).IsNil() - conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{ - IP: []byte{127, 0, 0, 1}, - Port: int(v2rayPort), - }) + for i := 0; i < 100; i++ { + conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{ + IP: []byte{127, 0, 0, 1}, + Port: int(v2rayPort), + }) - authRequest := socks5AuthMethodRequest(byte(0)) - nBytes, err := conn.Write(authRequest) - assert.Int(nBytes).Equals(len(authRequest)) - assert.Error(err).IsNil() + authRequest := socks5AuthMethodRequest(byte(0)) + nBytes, err := conn.Write(authRequest) + assert.Int(nBytes).Equals(len(authRequest)) + assert.Error(err).IsNil() - authResponse := make([]byte, 1024) - nBytes, err = conn.Read(authResponse) - assert.Error(err).IsNil() - assert.Bytes(authResponse[:nBytes]).Equals([]byte{socks5Version, 0}) + authResponse := make([]byte, 1024) + nBytes, err = conn.Read(authResponse) + assert.Error(err).IsNil() + assert.Bytes(authResponse[:nBytes]).Equals([]byte{socks5Version, 0}) - connectRequest := socks5Request(byte(1), v2net.IPAddress([]byte{127, 0, 0, 1}, targetPort)) - nBytes, err = conn.Write(connectRequest) - assert.Int(nBytes).Equals(len(connectRequest)) - assert.Error(err).IsNil() + connectRequest := socks5Request(byte(1), v2net.IPAddress([]byte{127, 0, 0, 1}, targetPort)) + nBytes, err = conn.Write(connectRequest) + assert.Int(nBytes).Equals(len(connectRequest)) + assert.Error(err).IsNil() - connectResponse := make([]byte, 1024) - nBytes, err = conn.Read(connectResponse) - assert.Error(err).IsNil() - assert.Bytes(connectResponse[:nBytes]).Equals([]byte{socks5Version, 0, 0, 1, 0, 0, 0, 0, 6, 181}) + connectResponse := make([]byte, 1024) + nBytes, err = conn.Read(connectResponse) + assert.Error(err).IsNil() + assert.Bytes(connectResponse[:nBytes]).Equals([]byte{socks5Version, 0, 0, 1, 0, 0, 0, 0, 6, 181}) - actualRequest := []byte("Request to target server.") - nBytes, err = conn.Write(actualRequest) - assert.Error(err).IsNil() - assert.Int(nBytes).Equals(len(actualRequest)) + actualRequest := []byte("Request to target server.") + nBytes, err = conn.Write(actualRequest) + assert.Error(err).IsNil() + assert.Int(nBytes).Equals(len(actualRequest)) - actualRequest = []byte("Request to target server again.") - nBytes, err = conn.Write(actualRequest) - assert.Error(err).IsNil() - assert.Int(nBytes).Equals(len(actualRequest)) + actualRequest = []byte("Request to target server again.") + nBytes, err = conn.Write(actualRequest) + assert.Error(err).IsNil() + assert.Int(nBytes).Equals(len(actualRequest)) - conn.CloseWrite() + conn.CloseWrite() - actualResponse := make([]byte, 1024) - nBytes, err = conn.Read(actualResponse) - assert.Error(err).IsNil() - assert.String(string(actualResponse[:nBytes])).Equals("Processed: Request to target server.Request to target server again.") + actualResponse := make([]byte, 1024) + nBytes, err = conn.Read(actualResponse) + assert.Error(err).IsNil() + assert.String(string(actualResponse[:nBytes])).Equals("Processed: Request to target server.Request to target server again.") - conn.Close() + conn.Close() + } } func TestTCPBind(t *testing.T) { @@ -201,3 +123,70 @@ func TestTCPBind(t *testing.T) { conn.Close() } + +func TestUDPAssociate(t *testing.T) { + assert := unit.Assert(t) + + targetPort := v2nettesting.PickPort() + udpServer := &udp.Server{ + Port: targetPort, + MsgProcessor: func(data []byte) []byte { + buffer := make([]byte, 0, 2048) + buffer = append(buffer, []byte("Processed: ")...) + buffer = append(buffer, data...) + return buffer + }, + } + _, err := udpServer.Start() + assert.Error(err).IsNil() + + v2rayPort, err := setUpV2Ray() + assert.Error(err).IsNil() + + conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{ + IP: []byte{127, 0, 0, 1}, + Port: int(v2rayPort), + }) + + authRequest := socks5AuthMethodRequest(byte(0)) + nBytes, err := conn.Write(authRequest) + assert.Int(nBytes).Equals(len(authRequest)) + assert.Error(err).IsNil() + + authResponse := make([]byte, 1024) + nBytes, err = conn.Read(authResponse) + assert.Error(err).IsNil() + assert.Bytes(authResponse[:nBytes]).Equals([]byte{socks5Version, 0}) + + connectRequest := socks5Request(byte(3), v2net.IPAddress([]byte{127, 0, 0, 1}, targetPort)) + nBytes, err = conn.Write(connectRequest) + assert.Int(nBytes).Equals(len(connectRequest)) + assert.Error(err).IsNil() + + 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)}) + + udpConn, err := net.DialUDP("udp", nil, &net.UDPAddr{ + IP: []byte{127, 0, 0, 1}, + Port: int(v2rayPort), + }) + assert.Error(err).IsNil() + + udpPayload := "UDP request to udp server." + udpRequest := socks5UDPRequest(v2net.IPAddress([]byte{127, 0, 0, 1}, targetPort), []byte(udpPayload)) + + nBytes, err = udpConn.Write(udpRequest) + assert.Int(nBytes).Equals(len(udpRequest)) + assert.Error(err).IsNil() + + udpResponse := make([]byte, 1024) + nBytes, err = udpConn.Read(udpResponse) + assert.Error(err).IsNil() + assert.Bytes(udpResponse[:nBytes]).Equals( + socks5UDPRequest(v2net.IPAddress([]byte{127, 0, 0, 1}, targetPort), []byte("Processed: UDP request to udp server."))) + + udpConn.Close() + conn.Close() +}