vmess_test.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. package main
  2. import (
  3. "fmt"
  4. "testing"
  5. "time"
  6. "github.com/docker/docker/api/types/container"
  7. "github.com/metacubex/mihomo/adapter/outbound"
  8. C "github.com/metacubex/mihomo/constant"
  9. "github.com/stretchr/testify/require"
  10. )
  11. func TestMihomo_Vmess(t *testing.T) {
  12. configPath := C.Path.Resolve("vmess.json")
  13. cfg := &container.Config{
  14. Image: ImageVmess,
  15. ExposedPorts: defaultExposedPorts,
  16. }
  17. hostCfg := &container.HostConfig{
  18. PortBindings: defaultPortBindings,
  19. Binds: []string{fmt.Sprintf("%s:/etc/v2ray/config.json", configPath)},
  20. }
  21. id, err := startContainer(cfg, hostCfg, "vmess")
  22. require.NoError(t, err)
  23. t.Cleanup(func() {
  24. cleanContainer(id)
  25. })
  26. proxy, err := outbound.NewVmess(outbound.VmessOption{
  27. Name: "vmess",
  28. Server: localIP.String(),
  29. Port: 10002,
  30. UUID: "b831381d-6324-4d53-ad4f-8cda48b30811",
  31. Cipher: "auto",
  32. UDP: true,
  33. })
  34. require.NoError(t, err)
  35. time.Sleep(waitTime)
  36. testSuit(t, proxy)
  37. }
  38. func TestMihomo_VmessAuthenticatedLength(t *testing.T) {
  39. configPath := C.Path.Resolve("vmess.json")
  40. cfg := &container.Config{
  41. Image: ImageVmess,
  42. ExposedPorts: defaultExposedPorts,
  43. }
  44. hostCfg := &container.HostConfig{
  45. PortBindings: defaultPortBindings,
  46. Binds: []string{fmt.Sprintf("%s:/etc/v2ray/config.json", configPath)},
  47. }
  48. id, err := startContainer(cfg, hostCfg, "vmess")
  49. require.NoError(t, err)
  50. t.Cleanup(func() {
  51. cleanContainer(id)
  52. })
  53. proxy, err := outbound.NewVmess(outbound.VmessOption{
  54. Name: "vmess",
  55. Server: localIP.String(),
  56. Port: 10002,
  57. UUID: "b831381d-6324-4d53-ad4f-8cda48b30811",
  58. Cipher: "auto",
  59. UDP: true,
  60. AuthenticatedLength: true,
  61. })
  62. require.NoError(t, err)
  63. time.Sleep(waitTime)
  64. testSuit(t, proxy)
  65. }
  66. func TestMihomo_VmessPacketAddr(t *testing.T) {
  67. configPath := C.Path.Resolve("vmess.json")
  68. cfg := &container.Config{
  69. Image: ImageVmessLatest,
  70. ExposedPorts: defaultExposedPorts,
  71. }
  72. hostCfg := &container.HostConfig{
  73. PortBindings: defaultPortBindings,
  74. Binds: []string{fmt.Sprintf("%s:/etc/v2ray/config.json", configPath)},
  75. }
  76. id, err := startContainer(cfg, hostCfg, "vmess")
  77. require.NoError(t, err)
  78. t.Cleanup(func() {
  79. cleanContainer(id)
  80. })
  81. proxy, err := outbound.NewVmess(outbound.VmessOption{
  82. Name: "vmess",
  83. Server: localIP.String(),
  84. Port: 10002,
  85. UUID: "b831381d-6324-4d53-ad4f-8cda48b30811",
  86. Cipher: "auto",
  87. UDP: true,
  88. PacketAddr: true,
  89. })
  90. require.NoError(t, err)
  91. time.Sleep(waitTime)
  92. testSuit(t, proxy)
  93. }
  94. func TestMihomo_VmessTLS(t *testing.T) {
  95. cfg := &container.Config{
  96. Image: ImageVmess,
  97. ExposedPorts: defaultExposedPorts,
  98. }
  99. hostCfg := &container.HostConfig{
  100. PortBindings: defaultPortBindings,
  101. Binds: []string{
  102. fmt.Sprintf("%s:/etc/v2ray/config.json", C.Path.Resolve("vmess-tls.json")),
  103. fmt.Sprintf("%s:/etc/ssl/v2ray/fullchain.pem", C.Path.Resolve("example.org.pem")),
  104. fmt.Sprintf("%s:/etc/ssl/v2ray/privkey.pem", C.Path.Resolve("example.org-key.pem")),
  105. },
  106. }
  107. id, err := startContainer(cfg, hostCfg, "vmess-tls")
  108. require.NoError(t, err)
  109. t.Cleanup(func() {
  110. cleanContainer(id)
  111. })
  112. proxy, err := outbound.NewVmess(outbound.VmessOption{
  113. Name: "vmess",
  114. Server: localIP.String(),
  115. Port: 10002,
  116. UUID: "b831381d-6324-4d53-ad4f-8cda48b30811",
  117. Cipher: "auto",
  118. TLS: true,
  119. SkipCertVerify: true,
  120. ServerName: "example.org",
  121. UDP: true,
  122. })
  123. require.NoError(t, err)
  124. time.Sleep(waitTime)
  125. testSuit(t, proxy)
  126. }
  127. func TestMihomo_VmessHTTP2(t *testing.T) {
  128. cfg := &container.Config{
  129. Image: ImageVmess,
  130. ExposedPorts: defaultExposedPorts,
  131. }
  132. hostCfg := &container.HostConfig{
  133. PortBindings: defaultPortBindings,
  134. Binds: []string{
  135. fmt.Sprintf("%s:/etc/v2ray/config.json", C.Path.Resolve("vmess-http2.json")),
  136. fmt.Sprintf("%s:/etc/ssl/v2ray/fullchain.pem", C.Path.Resolve("example.org.pem")),
  137. fmt.Sprintf("%s:/etc/ssl/v2ray/privkey.pem", C.Path.Resolve("example.org-key.pem")),
  138. },
  139. }
  140. id, err := startContainer(cfg, hostCfg, "vmess-http2")
  141. require.NoError(t, err)
  142. t.Cleanup(func() {
  143. cleanContainer(id)
  144. })
  145. proxy, err := outbound.NewVmess(outbound.VmessOption{
  146. Name: "vmess",
  147. Server: localIP.String(),
  148. Port: 10002,
  149. UUID: "b831381d-6324-4d53-ad4f-8cda48b30811",
  150. Cipher: "auto",
  151. Network: "h2",
  152. TLS: true,
  153. SkipCertVerify: true,
  154. ServerName: "example.org",
  155. UDP: true,
  156. HTTP2Opts: outbound.HTTP2Options{
  157. Host: []string{"example.org"},
  158. Path: "/test",
  159. },
  160. })
  161. require.NoError(t, err)
  162. time.Sleep(waitTime)
  163. testSuit(t, proxy)
  164. }
  165. func TestMihomo_VmessHTTP(t *testing.T) {
  166. cfg := &container.Config{
  167. Image: ImageVmess,
  168. ExposedPorts: defaultExposedPorts,
  169. }
  170. hostCfg := &container.HostConfig{
  171. PortBindings: defaultPortBindings,
  172. Binds: []string{
  173. fmt.Sprintf("%s:/etc/v2ray/config.json", C.Path.Resolve("vmess-http.json")),
  174. },
  175. }
  176. id, err := startContainer(cfg, hostCfg, "vmess-http")
  177. require.NoError(t, err)
  178. t.Cleanup(func() {
  179. cleanContainer(id)
  180. })
  181. proxy, err := outbound.NewVmess(outbound.VmessOption{
  182. Name: "vmess",
  183. Server: localIP.String(),
  184. Port: 10002,
  185. UUID: "b831381d-6324-4d53-ad4f-8cda48b30811",
  186. Cipher: "auto",
  187. Network: "http",
  188. UDP: true,
  189. HTTPOpts: outbound.HTTPOptions{
  190. Method: "GET",
  191. Path: []string{"/"},
  192. Headers: map[string][]string{
  193. "Host": {"www.amazon.com"},
  194. "User-Agent": {
  195. "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36 Edg/84.0.522.49",
  196. },
  197. "Accept-Encoding": {
  198. "gzip, deflate",
  199. },
  200. "Connection": {
  201. "keep-alive",
  202. },
  203. "Pragma": {"no-cache"},
  204. },
  205. },
  206. })
  207. require.NoError(t, err)
  208. time.Sleep(waitTime)
  209. testSuit(t, proxy)
  210. }
  211. func TestMihomo_VmessWebsocket(t *testing.T) {
  212. cfg := &container.Config{
  213. Image: ImageVmess,
  214. ExposedPorts: defaultExposedPorts,
  215. }
  216. hostCfg := &container.HostConfig{
  217. PortBindings: defaultPortBindings,
  218. Binds: []string{
  219. fmt.Sprintf("%s:/etc/v2ray/config.json", C.Path.Resolve("vmess-ws.json")),
  220. },
  221. }
  222. id, err := startContainer(cfg, hostCfg, "vmess-ws")
  223. require.NoError(t, err)
  224. t.Cleanup(func() {
  225. cleanContainer(id)
  226. })
  227. proxy, err := outbound.NewVmess(outbound.VmessOption{
  228. Name: "vmess",
  229. Server: localIP.String(),
  230. Port: 10002,
  231. UUID: "b831381d-6324-4d53-ad4f-8cda48b30811",
  232. Cipher: "auto",
  233. Network: "ws",
  234. UDP: true,
  235. })
  236. require.NoError(t, err)
  237. time.Sleep(waitTime)
  238. testSuit(t, proxy)
  239. }
  240. func TestMihomo_VmessWebsocketTLS(t *testing.T) {
  241. cfg := &container.Config{
  242. Image: ImageVmess,
  243. ExposedPorts: defaultExposedPorts,
  244. }
  245. hostCfg := &container.HostConfig{
  246. PortBindings: defaultPortBindings,
  247. Binds: []string{
  248. fmt.Sprintf("%s:/etc/v2ray/config.json", C.Path.Resolve("vmess-ws-tls.json")),
  249. fmt.Sprintf("%s:/etc/ssl/v2ray/fullchain.pem", C.Path.Resolve("example.org.pem")),
  250. fmt.Sprintf("%s:/etc/ssl/v2ray/privkey.pem", C.Path.Resolve("example.org-key.pem")),
  251. },
  252. }
  253. id, err := startContainer(cfg, hostCfg, "vmess-ws")
  254. require.NoError(t, err)
  255. t.Cleanup(func() {
  256. cleanContainer(id)
  257. })
  258. proxy, err := outbound.NewVmess(outbound.VmessOption{
  259. Name: "vmess",
  260. Server: localIP.String(),
  261. Port: 10002,
  262. UUID: "b831381d-6324-4d53-ad4f-8cda48b30811",
  263. Cipher: "auto",
  264. Network: "ws",
  265. TLS: true,
  266. SkipCertVerify: true,
  267. UDP: true,
  268. })
  269. require.NoError(t, err)
  270. time.Sleep(waitTime)
  271. testSuit(t, proxy)
  272. }
  273. func TestMihomo_VmessGrpc(t *testing.T) {
  274. cfg := &container.Config{
  275. Image: ImageVmess,
  276. ExposedPorts: defaultExposedPorts,
  277. }
  278. hostCfg := &container.HostConfig{
  279. PortBindings: defaultPortBindings,
  280. Binds: []string{
  281. fmt.Sprintf("%s:/etc/v2ray/config.json", C.Path.Resolve("vmess-grpc.json")),
  282. fmt.Sprintf("%s:/etc/ssl/v2ray/fullchain.pem", C.Path.Resolve("example.org.pem")),
  283. fmt.Sprintf("%s:/etc/ssl/v2ray/privkey.pem", C.Path.Resolve("example.org-key.pem")),
  284. },
  285. }
  286. id, err := startContainer(cfg, hostCfg, "vmess-grpc")
  287. require.NoError(t, err)
  288. t.Cleanup(func() {
  289. cleanContainer(id)
  290. })
  291. proxy, err := outbound.NewVmess(outbound.VmessOption{
  292. Name: "vmess",
  293. Server: localIP.String(),
  294. Port: 10002,
  295. UUID: "b831381d-6324-4d53-ad4f-8cda48b30811",
  296. Cipher: "auto",
  297. Network: "grpc",
  298. TLS: true,
  299. SkipCertVerify: true,
  300. UDP: true,
  301. ServerName: "example.org",
  302. GrpcOpts: outbound.GrpcOptions{
  303. GrpcServiceName: "example!",
  304. },
  305. })
  306. require.NoError(t, err)
  307. time.Sleep(waitTime)
  308. testSuit(t, proxy)
  309. }
  310. func TestMihomo_VmessWebsocket0RTT(t *testing.T) {
  311. cfg := &container.Config{
  312. Image: ImageVmess,
  313. ExposedPorts: defaultExposedPorts,
  314. }
  315. hostCfg := &container.HostConfig{
  316. PortBindings: defaultPortBindings,
  317. Binds: []string{
  318. fmt.Sprintf("%s:/etc/v2ray/config.json", C.Path.Resolve("vmess-ws-0rtt.json")),
  319. },
  320. }
  321. id, err := startContainer(cfg, hostCfg, "vmess-ws-0rtt")
  322. require.NoError(t, err)
  323. t.Cleanup(func() {
  324. cleanContainer(id)
  325. })
  326. proxy, err := outbound.NewVmess(outbound.VmessOption{
  327. Name: "vmess",
  328. Server: localIP.String(),
  329. Port: 10002,
  330. UUID: "b831381d-6324-4d53-ad4f-8cda48b30811",
  331. Cipher: "auto",
  332. Network: "ws",
  333. UDP: true,
  334. ServerName: "example.org",
  335. WSOpts: outbound.WSOptions{
  336. MaxEarlyData: 2048,
  337. EarlyDataHeaderName: "Sec-WebSocket-Protocol",
  338. },
  339. })
  340. require.NoError(t, err)
  341. time.Sleep(waitTime)
  342. testSuit(t, proxy)
  343. }
  344. func TestMihomo_VmessWebsocketXray0RTT(t *testing.T) {
  345. cfg := &container.Config{
  346. Image: ImageXray,
  347. ExposedPorts: defaultExposedPorts,
  348. }
  349. hostCfg := &container.HostConfig{
  350. PortBindings: defaultPortBindings,
  351. Binds: []string{
  352. fmt.Sprintf("%s:/etc/xray/config.json", C.Path.Resolve("vmess-ws-0rtt.json")),
  353. },
  354. }
  355. id, err := startContainer(cfg, hostCfg, "vmess-xray-ws-0rtt")
  356. require.NoError(t, err)
  357. t.Cleanup(func() {
  358. cleanContainer(id)
  359. })
  360. proxy, err := outbound.NewVmess(outbound.VmessOption{
  361. Name: "vmess",
  362. Server: localIP.String(),
  363. Port: 10002,
  364. UUID: "b831381d-6324-4d53-ad4f-8cda48b30811",
  365. Cipher: "auto",
  366. Network: "ws",
  367. UDP: true,
  368. ServerName: "example.org",
  369. WSOpts: outbound.WSOptions{
  370. Path: "/?ed=2048",
  371. },
  372. })
  373. require.NoError(t, err)
  374. time.Sleep(waitTime)
  375. testSuit(t, proxy)
  376. }
  377. func Benchmark_Vmess(b *testing.B) {
  378. configPath := C.Path.Resolve("vmess.json")
  379. cfg := &container.Config{
  380. Image: ImageVmess,
  381. ExposedPorts: defaultExposedPorts,
  382. }
  383. hostCfg := &container.HostConfig{
  384. PortBindings: defaultPortBindings,
  385. Binds: []string{fmt.Sprintf("%s:/etc/v2ray/config.json", configPath)},
  386. }
  387. id, err := startContainer(cfg, hostCfg, "vmess-bench")
  388. require.NoError(b, err)
  389. b.Cleanup(func() {
  390. cleanContainer(id)
  391. })
  392. proxy, err := outbound.NewVmess(outbound.VmessOption{
  393. Name: "vmess",
  394. Server: localIP.String(),
  395. Port: 10002,
  396. UUID: "b831381d-6324-4d53-ad4f-8cda48b30811",
  397. Cipher: "auto",
  398. AlterID: 0,
  399. UDP: true,
  400. })
  401. require.NoError(b, err)
  402. time.Sleep(waitTime)
  403. benchmarkProxy(b, proxy)
  404. }