Browse Source

Add Testing for meek, grpc, httpUpgrade Transport (#3160)

* Add instance management based testing

* Add testing for meek transport

* Add testing for grpc, httpupgrade transport
Xiaokang Wang (Shelikhoo) 1 year ago
parent
commit
d9181ad84a

+ 11 - 0
testing/scenarios/cert/self-signed_cert.pem

@@ -0,0 +1,11 @@
+-----BEGIN CERTIFICATE-----
+MIIBhDCCASmgAwIBAgIQOGW77bhKIQBVcKBkruQEjDAKBggqhkjOPQQDAjAoMRIw
+EAYDVQQKEwlWMlJheSBJbmMxEjAQBgNVBAMTCVYyUmF5IEluYzAeFw0yNDA5MTUx
+NjIyMjRaFw0yNDEyMTQxNzIyMjRaMCgxEjAQBgNVBAoTCVYyUmF5IEluYzESMBAG
+A1UEAxMJVjJSYXkgSW5jMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmKTCe3pJ
+6qYR8JSt4LHurI9ukGQISTBBLrFw8fDsWTeJielnHZdqgKL9swcC+IF/ikjzbT5W
+iP0EGUBGk6wbPKM1MDMwDgYDVR0PAQH/BAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUF
+BwMBMAwGA1UdEwEB/wQCMAAwCgYIKoZIzj0EAwIDSQAwRgIhAKIZM1xlaHwSHsZP
+V6aN+AbWnoRgwVVJuY4I5q17FY0cAiEAiLr9NkHd9glFz0BzALygvo7gnNpgF69l
+DdiZ4828MXY=
+-----END CERTIFICATE-----

+ 5 - 0
testing/scenarios/cert/self-signed_key.pem

@@ -0,0 +1,5 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgmkOATgwafiG4sDs/
+J1xVZfimvgREFJy0mtZHeGM2O6ehRANCAASYpMJ7eknqphHwlK3gse6sj26QZAhJ
+MEEusXDx8OxZN4mJ6Wcdl2qAov2zBwL4gX+KSPNtPlaI/QQZQEaTrBs8
+-----END RSA PRIVATE KEY-----

+ 21 - 0
testing/scenarios/common.go

@@ -4,6 +4,7 @@ import (
 	"bytes"
 	"crypto/rand"
 	"fmt"
+	"golang.org/x/net/proxy"
 	"io"
 	"os"
 	"os/exec"
@@ -168,6 +169,26 @@ func withDefaultApps(config *core.Config) *core.Config {
 	return config
 }
 
+func testTCPConnViaSocks(socksPort, testPort net.Port, payloadSize int, timeout time.Duration) func() error {
+	return func() error {
+		socksDialer, err := proxy.SOCKS5("tcp", "127.0.0.1:"+socksPort.String(), nil, nil)
+		if err != nil {
+			return err
+		}
+		destAddr := &net.TCPAddr{
+			IP:   []byte{127, 0, 0, 1},
+			Port: int(testPort),
+		}
+		conn, err := socksDialer.Dial("tcp", destAddr.String())
+		if err != nil {
+			return err
+		}
+		defer conn.Close()
+
+		return testTCPConn2(conn, payloadSize, timeout)()
+	}
+}
+
 func testTCPConn(port net.Port, payloadSize int, timeout time.Duration) func() error {
 	return func() error {
 		conn, err := net.DialTCP("tcp", nil, &net.TCPAddr{

+ 27 - 0
testing/scenarios/common_instanceMgr.go

@@ -0,0 +1,27 @@
+package scenarios
+
+import (
+	core "github.com/v2fly/v2ray-core/v5"
+	"github.com/v2fly/v2ray-core/v5/app/instman"
+	"github.com/v2fly/v2ray-core/v5/common"
+	"github.com/v2fly/v2ray-core/v5/common/serial"
+	"github.com/v2fly/v2ray-core/v5/features/extension"
+)
+
+func NewInstanceManagerInstanceConfig() *core.Config {
+	config := &core.Config{}
+	config.App = append(config.App, serial.ToTypedMessage(&instman.Config{}))
+	return config
+}
+
+func NewInstanceManagerCoreInstance() (*core.Instance, extension.InstanceManagement) {
+	coreConfig := NewInstanceManagerInstanceConfig()
+	instance, err := core.New(coreConfig)
+	if err != nil {
+		panic(err)
+	}
+	common.Must(instance.Start())
+	instanceMgr := instance.GetFeature(extension.InstanceManagementType())
+	InstanceMgrIfce := instanceMgr.(extension.InstanceManagement)
+	return instance, InstanceMgrIfce
+}

+ 7 - 0
testing/scenarios/common_instanceMgr_test.go

@@ -0,0 +1,7 @@
+package scenarios
+
+import "testing"
+
+func TestInstanceMgrInit(t *testing.T) {
+	NewInstanceManagerCoreInstance()
+}

+ 45 - 0
testing/scenarios/config/grpc_client.json

@@ -0,0 +1,45 @@
+{
+  "log": {
+    "error": {
+      "level": "Debug",
+      "type": "Console"
+    },
+    "access": {
+      "type": "None"
+    }
+  },
+  "outbounds": [
+    {
+      "protocol": "vmess",
+      "settings": {
+        "address": "127.0.0.1",
+        "port": 17783,
+        "uuid": "bcc71618-e552-42c2-a2a3-d4c17a9df764"
+      },
+      "streamSettings": {
+        "transport": "grpc",
+        "transportSettings": {
+        },
+        "security": "tls",
+        "securitySettings": {
+          "pinnedPeerCertificateChainSha256": [
+            "kqHyvea27Pn+JiSqA72lhu9IKAKeGR+3yCyA8JR1mug="
+          ],
+          "allowInsecureIfPinnedPeerCertificate": true
+        }
+      }
+    }
+  ],
+  "inbounds": [
+    {
+      "protocol": "socks",
+      "settings": {
+        "udpEnabled": false,
+        "address": "127.0.0.1",
+        "packetEncoding": "Packet"
+      },
+      "port": 17784,
+      "listen": "127.0.0.1"
+    }
+  ]
+}

+ 43 - 0
testing/scenarios/config/grpc_server.json

@@ -0,0 +1,43 @@
+{
+  "log": {
+    "error": {
+      "level": "Debug",
+      "type": "Console"
+    },
+    "access": {
+      "type": "None"
+    }
+  },
+  "outbounds": [
+    {
+      "protocol": "freedom"
+    }
+  ],
+  "inbounds": [
+    {
+      "listen": "127.0.0.1",
+      "port": 17783,
+      "protocol": "vmess",
+      "settings": {
+        "users": [
+          "bcc71618-e552-42c2-a2a3-d4c17a9df764"
+        ]
+      },
+      "streamSettings": {
+        "transport": "grpc",
+        "transportSettings": {
+        },
+        "security": "tls",
+        "securitySettings": {
+          "certificate": [
+            {
+              "usage": "ENCIPHERMENT",
+              "certificateFile": "cert/self-signed_cert.pem",
+              "keyFile": "cert/self-signed_key.pem"
+            }
+          ]
+        }
+      }
+    }
+  ]
+}

+ 46 - 0
testing/scenarios/config/grpc_servicename_client.json

@@ -0,0 +1,46 @@
+{
+  "log": {
+    "error": {
+      "level": "Debug",
+      "type": "Console"
+    },
+    "access": {
+      "type": "None"
+    }
+  },
+  "outbounds": [
+    {
+      "protocol": "vmess",
+      "settings": {
+        "address": "127.0.0.1",
+        "port": 17793,
+        "uuid": "bcc71618-e552-42c2-a2a3-d4c17a9df764"
+      },
+      "streamSettings": {
+        "transport": "grpc",
+        "transportSettings": {
+          "serviceName": "0eae44595474"
+        },
+        "security": "tls",
+        "securitySettings": {
+          "pinnedPeerCertificateChainSha256": [
+            "kqHyvea27Pn+JiSqA72lhu9IKAKeGR+3yCyA8JR1mug="
+          ],
+          "allowInsecureIfPinnedPeerCertificate": true
+        }
+      }
+    }
+  ],
+  "inbounds": [
+    {
+      "protocol": "socks",
+      "settings": {
+        "udpEnabled": false,
+        "address": "127.0.0.1",
+        "packetEncoding": "Packet"
+      },
+      "port": 17794,
+      "listen": "127.0.0.1"
+    }
+  ]
+}

+ 44 - 0
testing/scenarios/config/grpc_servicename_server.json

@@ -0,0 +1,44 @@
+{
+  "log": {
+    "error": {
+      "level": "Debug",
+      "type": "Console"
+    },
+    "access": {
+      "type": "None"
+    }
+  },
+  "outbounds": [
+    {
+      "protocol": "freedom"
+    }
+  ],
+  "inbounds": [
+    {
+      "listen": "127.0.0.1",
+      "port": 17793,
+      "protocol": "vmess",
+      "settings": {
+        "users": [
+          "bcc71618-e552-42c2-a2a3-d4c17a9df764"
+        ]
+      },
+      "streamSettings": {
+        "transport": "grpc",
+        "transportSettings": {
+          "serviceName": "0eae44595474"
+        },
+        "security": "tls",
+        "securitySettings": {
+          "certificate": [
+            {
+              "usage": "ENCIPHERMENT",
+              "certificateFile": "cert/self-signed_cert.pem",
+              "keyFile": "cert/self-signed_key.pem"
+            }
+          ]
+        }
+      }
+    }
+  ]
+}

+ 46 - 0
testing/scenarios/config/httpupgrade_client.json

@@ -0,0 +1,46 @@
+{
+  "log": {
+    "error": {
+      "level": "Debug",
+      "type": "Console"
+    },
+    "access": {
+      "type": "None"
+    }
+  },
+  "outbounds": [
+    {
+      "protocol": "vmess",
+      "settings": {
+        "address": "127.0.0.1",
+        "port": 17793,
+        "uuid": "bcc71618-e552-42c2-a2a3-d4c17a9df764"
+      },
+      "streamSettings": {
+        "transport": "httpupgrade",
+        "transportSettings": {
+          "path": "b66efc0c7752"
+        },
+        "security": "tls",
+        "securitySettings": {
+          "pinnedPeerCertificateChainSha256": [
+            "kqHyvea27Pn+JiSqA72lhu9IKAKeGR+3yCyA8JR1mug="
+          ],
+          "allowInsecureIfPinnedPeerCertificate": true
+        }
+      }
+    }
+  ],
+  "inbounds": [
+    {
+      "protocol": "socks",
+      "settings": {
+        "udpEnabled": false,
+        "address": "127.0.0.1",
+        "packetEncoding": "Packet"
+      },
+      "port": 17794,
+      "listen": "127.0.0.1"
+    }
+  ]
+}

+ 44 - 0
testing/scenarios/config/httpupgrade_server.json

@@ -0,0 +1,44 @@
+{
+  "log": {
+    "error": {
+      "level": "Debug",
+      "type": "Console"
+    },
+    "access": {
+      "type": "None"
+    }
+  },
+  "outbounds": [
+    {
+      "protocol": "freedom"
+    }
+  ],
+  "inbounds": [
+    {
+      "listen": "127.0.0.1",
+      "port": 17793,
+      "protocol": "vmess",
+      "settings": {
+        "users": [
+          "bcc71618-e552-42c2-a2a3-d4c17a9df764"
+        ]
+      },
+      "streamSettings": {
+        "transport": "httpupgrade",
+        "transportSettings": {
+          "path": "b66efc0c7752"
+        },
+        "security": "tls",
+        "securitySettings": {
+          "certificate": [
+            {
+              "usage": "ENCIPHERMENT",
+              "certificateFile": "cert/self-signed_cert.pem",
+              "keyFile": "cert/self-signed_key.pem"
+            }
+          ]
+        }
+      }
+    }
+  ]
+}

+ 46 - 0
testing/scenarios/config/meek_client.json

@@ -0,0 +1,46 @@
+{
+  "log": {
+    "error": {
+      "level": "Debug",
+      "type": "Console"
+    },
+    "access": {
+      "type": "None"
+    }
+  },
+  "outbounds": [
+    {
+      "protocol": "vmess",
+      "settings": {
+        "address": "127.0.0.1",
+        "port": 17773,
+        "uuid": "bcc71618-e552-42c2-a2a3-d4c17a9df764"
+      },
+      "streamSettings": {
+        "transport": "meek",
+        "transportSettings": {
+          "url": "https://127.0.0.1:17773/mrss48bvxrkfq1qzeqte5o61mmvc9gx6hq51"
+        },
+        "security": "tls",
+        "securitySettings": {
+          "pinnedPeerCertificateChainSha256": [
+            "kqHyvea27Pn+JiSqA72lhu9IKAKeGR+3yCyA8JR1mug="
+          ],
+          "allowInsecureIfPinnedPeerCertificate": true
+        }
+      }
+    }
+  ],
+  "inbounds": [
+    {
+      "protocol": "socks",
+      "settings": {
+        "udpEnabled": false,
+        "address": "127.0.0.1",
+        "packetEncoding": "Packet"
+      },
+      "port": 17774,
+      "listen": "127.0.0.1"
+    }
+  ]
+}

+ 44 - 0
testing/scenarios/config/meek_server.json

@@ -0,0 +1,44 @@
+{
+  "log": {
+    "error": {
+      "level": "Debug",
+      "type": "Console"
+    },
+    "access": {
+      "type": "None"
+    }
+  },
+  "outbounds": [
+    {
+      "protocol": "freedom"
+    }
+  ],
+  "inbounds": [
+    {
+      "listen": "127.0.0.1",
+      "port": 17773,
+      "protocol": "vmess",
+      "settings": {
+        "users": [
+          "bcc71618-e552-42c2-a2a3-d4c17a9df764"
+        ]
+      },
+      "streamSettings": {
+        "transport": "meek",
+        "transportSettings": {
+          "url": "http://127.0.0.1:12777"
+        },
+        "security": "tls",
+        "securitySettings": {
+          "certificate": [
+            {
+              "usage": "ENCIPHERMENT",
+              "certificateFile": "cert/self-signed_cert.pem",
+              "keyFile": "cert/self-signed_key.pem"
+            }
+          ]
+        }
+      }
+    }
+  ]
+}

+ 91 - 0
testing/scenarios/grpc_test.go

@@ -0,0 +1,91 @@
+package scenarios
+
+import (
+	"context"
+	"os"
+	"testing"
+	"time"
+
+	"github.com/v2fly/v2ray-core/v5/common"
+	"github.com/v2fly/v2ray-core/v5/testing/servers/tcp"
+
+	_ "github.com/v2fly/v2ray-core/v5/main/distro/all"
+)
+
+func TestGRPCDefault(t *testing.T) {
+	tcpServer := tcp.Server{
+		MsgProcessor: xor,
+	}
+	dest, err := tcpServer.Start()
+	common.Must(err)
+	defer tcpServer.Close()
+
+	coreInst, InstMgrIfce := NewInstanceManagerCoreInstance()
+	defer coreInst.Close()
+
+	common.Must(InstMgrIfce.AddInstance(
+		context.TODO(),
+		"grpc_client",
+		common.Must2(os.ReadFile("config/grpc_client.json")).([]byte),
+		"jsonv5"))
+
+	common.Must(InstMgrIfce.AddInstance(
+		context.TODO(),
+		"grpc_server",
+		common.Must2(os.ReadFile("config/grpc_server.json")).([]byte),
+		"jsonv5"))
+
+	common.Must(InstMgrIfce.StartInstance(context.TODO(), "grpc_server"))
+	common.Must(InstMgrIfce.StartInstance(context.TODO(), "grpc_client"))
+
+	defer func() {
+		common.Must(InstMgrIfce.StopInstance(context.TODO(), "grpc_server"))
+		common.Must(InstMgrIfce.StopInstance(context.TODO(), "grpc_client"))
+		common.Must(InstMgrIfce.UntrackInstance(context.TODO(), "grpc_server"))
+		common.Must(InstMgrIfce.UntrackInstance(context.TODO(), "grpc_client"))
+		coreInst.Close()
+	}()
+
+	if err := testTCPConnViaSocks(17784, dest.Port, 1024, time.Second*2)(); err != nil {
+		t.Error(err)
+	}
+}
+
+func TestGRPCWithServiceName(t *testing.T) {
+	tcpServer := tcp.Server{
+		MsgProcessor: xor,
+	}
+	dest, err := tcpServer.Start()
+	common.Must(err)
+	defer tcpServer.Close()
+
+	coreInst, InstMgrIfce := NewInstanceManagerCoreInstance()
+	defer coreInst.Close()
+
+	common.Must(InstMgrIfce.AddInstance(
+		context.TODO(),
+		"grpc_client",
+		common.Must2(os.ReadFile("config/grpc_servicename_client.json")).([]byte),
+		"jsonv5"))
+
+	common.Must(InstMgrIfce.AddInstance(
+		context.TODO(),
+		"grpc_server",
+		common.Must2(os.ReadFile("config/grpc_servicename_server.json")).([]byte),
+		"jsonv5"))
+
+	common.Must(InstMgrIfce.StartInstance(context.TODO(), "grpc_server"))
+	common.Must(InstMgrIfce.StartInstance(context.TODO(), "grpc_client"))
+
+	defer func() {
+		common.Must(InstMgrIfce.StopInstance(context.TODO(), "grpc_server"))
+		common.Must(InstMgrIfce.StopInstance(context.TODO(), "grpc_client"))
+		common.Must(InstMgrIfce.UntrackInstance(context.TODO(), "grpc_server"))
+		common.Must(InstMgrIfce.UntrackInstance(context.TODO(), "grpc_client"))
+		coreInst.Close()
+	}()
+
+	if err := testTCPConnViaSocks(17794, dest.Port, 1024, time.Second*2)(); err != nil {
+		t.Error(err)
+	}
+}

+ 52 - 0
testing/scenarios/httpupgrade_test.go

@@ -0,0 +1,52 @@
+package scenarios
+
+import (
+	"context"
+	"os"
+	"testing"
+	"time"
+
+	"github.com/v2fly/v2ray-core/v5/common"
+	"github.com/v2fly/v2ray-core/v5/testing/servers/tcp"
+
+	_ "github.com/v2fly/v2ray-core/v5/main/distro/all"
+)
+
+func TestHTTPUpgrade(t *testing.T) {
+	tcpServer := tcp.Server{
+		MsgProcessor: xor,
+	}
+	dest, err := tcpServer.Start()
+	common.Must(err)
+	defer tcpServer.Close()
+
+	coreInst, InstMgrIfce := NewInstanceManagerCoreInstance()
+	defer coreInst.Close()
+
+	common.Must(InstMgrIfce.AddInstance(
+		context.TODO(),
+		"httpupgrade_client",
+		common.Must2(os.ReadFile("config/httpupgrade_client.json")).([]byte),
+		"jsonv5"))
+
+	common.Must(InstMgrIfce.AddInstance(
+		context.TODO(),
+		"httpupgrade_server",
+		common.Must2(os.ReadFile("config/httpupgrade_server.json")).([]byte),
+		"jsonv5"))
+
+	common.Must(InstMgrIfce.StartInstance(context.TODO(), "httpupgrade_server"))
+	common.Must(InstMgrIfce.StartInstance(context.TODO(), "httpupgrade_client"))
+
+	defer func() {
+		common.Must(InstMgrIfce.StopInstance(context.TODO(), "httpupgrade_server"))
+		common.Must(InstMgrIfce.StopInstance(context.TODO(), "httpupgrade_client"))
+		common.Must(InstMgrIfce.UntrackInstance(context.TODO(), "httpupgrade_server"))
+		common.Must(InstMgrIfce.UntrackInstance(context.TODO(), "httpupgrade_client"))
+		coreInst.Close()
+	}()
+
+	if err := testTCPConnViaSocks(17794, dest.Port, 1024, time.Second*2)(); err != nil {
+		t.Error(err)
+	}
+}

+ 52 - 0
testing/scenarios/meek_test.go

@@ -0,0 +1,52 @@
+package scenarios
+
+import (
+	"context"
+	"os"
+	"testing"
+	"time"
+
+	"github.com/v2fly/v2ray-core/v5/common"
+	"github.com/v2fly/v2ray-core/v5/testing/servers/tcp"
+
+	_ "github.com/v2fly/v2ray-core/v5/main/distro/all"
+)
+
+func TestMeek(t *testing.T) {
+	tcpServer := tcp.Server{
+		MsgProcessor: xor,
+	}
+	dest, err := tcpServer.Start()
+	common.Must(err)
+	defer tcpServer.Close()
+
+	coreInst, InstMgrIfce := NewInstanceManagerCoreInstance()
+	defer coreInst.Close()
+
+	common.Must(InstMgrIfce.AddInstance(
+		context.TODO(),
+		"meek_client",
+		common.Must2(os.ReadFile("config/meek_client.json")).([]byte),
+		"jsonv5"))
+
+	common.Must(InstMgrIfce.AddInstance(
+		context.TODO(),
+		"meek_server",
+		common.Must2(os.ReadFile("config/meek_server.json")).([]byte),
+		"jsonv5"))
+
+	common.Must(InstMgrIfce.StartInstance(context.TODO(), "meek_server"))
+	common.Must(InstMgrIfce.StartInstance(context.TODO(), "meek_client"))
+
+	defer func() {
+		common.Must(InstMgrIfce.StopInstance(context.TODO(), "meek_server"))
+		common.Must(InstMgrIfce.StopInstance(context.TODO(), "meek_client"))
+		common.Must(InstMgrIfce.UntrackInstance(context.TODO(), "meek_server"))
+		common.Must(InstMgrIfce.UntrackInstance(context.TODO(), "meek_client"))
+		coreInst.Close()
+	}()
+
+	if err := testTCPConnViaSocks(17774, dest.Port, 1024, time.Second*2)(); err != nil {
+		t.Error(err)
+	}
+}