diff --git a/testing/scenarios/data/test_1_client.json b/testing/scenarios/data/test_1_client.json index 8ffcef89..e7af5c2d 100644 --- a/testing/scenarios/data/test_1_client.json +++ b/testing/scenarios/data/test_1_client.json @@ -1,4 +1,7 @@ { + "log": { + "loglevel": "debug" + }, "inbound": { "port": 50000, "listen": "127.0.0.1", @@ -9,6 +12,19 @@ "ip": "127.0.0.1" } }, + "inboundDetour": [ + { + "port": 50002, + "listen": "127.0.0.1", + "protocol": "socks", + "allowPassive": true, + "settings": { + "auth": "noauth", + "udp": true, + "ip": "127.0.0.1" + } + } + ], "outbound": { "protocol": "vmess", "settings": { diff --git a/testing/scenarios/data/test_1_server.json b/testing/scenarios/data/test_1_server.json index 1c1eca73..67fedc5e 100644 --- a/testing/scenarios/data/test_1_server.json +++ b/testing/scenarios/data/test_1_server.json @@ -1,11 +1,12 @@ { "port": 50001, "log": { - "loglevel": "none" + "loglevel": "debug" }, "inbound": { "listen": "127.0.0.1", "protocol": "vmess", + "allowPassive": true, "settings": { "clients": [ { @@ -31,6 +32,7 @@ "listen": "127.0.0.1", "port": "50005-50009", "tag": "detour", + "allowPassive": true, "settings": { "clients": [ { diff --git a/testing/scenarios/socks_end_test.go b/testing/scenarios/socks_end_test.go index 96b1bd38..60a1f1cb 100644 --- a/testing/scenarios/socks_end_test.go +++ b/testing/scenarios/socks_end_test.go @@ -83,6 +83,63 @@ func TestTCPConnection(t *testing.T) { CloseAllServers() } +func TestPassiveTCPConnection(t *testing.T) { + assert := assert.On(t) + + tcpServer := &tcp.Server{ + MsgProcessor: func(data []byte) []byte { + buffer := make([]byte, 0, 2048) + buffer = append(buffer, []byte("Processed: ")...) + buffer = append(buffer, data...) + return buffer + }, + SendFirst: []byte("Server sends first."), + } + _, err := tcpServer.Start() + assert.Error(err).IsNil() + defer tcpServer.Close() + + assert.Error(InitializeServerSetOnce("test_1")).IsNil() + + socksPort := v2net.Port(50002) + + conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{ + IP: []byte{127, 0, 0, 1}, + Port: int(socksPort), + }) + 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}) + + connectRequest := socks5Request(byte(1), v2net.TCPDestination(v2net.IPAddress([]byte{127, 0, 0, 1}), tcpServer.Port)) + 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}) + + actualResponse := make([]byte, 1024) + nResponse, err := conn.Read(actualResponse) + assert.Error(err).IsNil() + + assert.String(string(actualResponse[:nResponse])).Equals(string(tcpServer.SendFirst)) + + conn.Close() + + CloseAllServers() +} + func TestTCPBind(t *testing.T) { assert := assert.On(t) diff --git a/testing/servers/tcp/tcp.go b/testing/servers/tcp/tcp.go index 223698d0..9874d1f2 100644 --- a/testing/servers/tcp/tcp.go +++ b/testing/servers/tcp/tcp.go @@ -10,6 +10,7 @@ import ( type Server struct { Port v2net.Port MsgProcessor func(msg []byte) []byte + SendFirst []byte accepting bool listener *net.TCPListener } @@ -44,6 +45,9 @@ func (server *Server) acceptConnections(listener *net.TCPListener) { } func (server *Server) handleConnection(conn net.Conn) { + if len(server.SendFirst) > 0 { + conn.Write(server.SendFirst) + } request := make([]byte, 4096) for true { nBytes, err := conn.Read(request)