1
0

hysteria2_test.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. package main
  2. import (
  3. "net/netip"
  4. "testing"
  5. "time"
  6. C "github.com/sagernet/sing-box/constant"
  7. "github.com/sagernet/sing-box/option"
  8. "github.com/sagernet/sing-quic/hysteria2"
  9. "github.com/sagernet/sing/common"
  10. F "github.com/sagernet/sing/common/format"
  11. "github.com/sagernet/sing/common/json/badoption"
  12. )
  13. func TestHysteria2Self(t *testing.T) {
  14. t.Run("self", func(t *testing.T) {
  15. testHysteria2Self(t, "", false)
  16. })
  17. t.Run("self-salamander", func(t *testing.T) {
  18. testHysteria2Self(t, "password", false)
  19. })
  20. t.Run("self-hop", func(t *testing.T) {
  21. testHysteria2Self(t, "", true)
  22. })
  23. t.Run("self-hop-salamander", func(t *testing.T) {
  24. testHysteria2Self(t, "password", true)
  25. })
  26. }
  27. func TestHysteria2Hop(t *testing.T) {
  28. testHysteria2Self(t, "password", true)
  29. }
  30. func testHysteria2Self(t *testing.T, salamanderPassword string, portHop bool) {
  31. _, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
  32. var obfs *option.Hysteria2Obfs
  33. if salamanderPassword != "" {
  34. obfs = &option.Hysteria2Obfs{
  35. Type: hysteria2.ObfsTypeSalamander,
  36. Password: salamanderPassword,
  37. }
  38. }
  39. var (
  40. serverPorts []string
  41. hopInterval time.Duration
  42. )
  43. if portHop {
  44. serverPorts = []string{F.ToString(serverPort, ":", serverPort)}
  45. hopInterval = 5 * time.Second
  46. }
  47. startInstance(t, option.Options{
  48. Inbounds: []option.Inbound{
  49. {
  50. Type: C.TypeMixed,
  51. Tag: "mixed-in",
  52. Options: &option.HTTPMixedInboundOptions{
  53. ListenOptions: option.ListenOptions{
  54. Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
  55. ListenPort: clientPort,
  56. },
  57. },
  58. },
  59. {
  60. Type: C.TypeHysteria2,
  61. Options: &option.Hysteria2InboundOptions{
  62. ListenOptions: option.ListenOptions{
  63. Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
  64. ListenPort: serverPort,
  65. },
  66. UpMbps: 100,
  67. DownMbps: 100,
  68. Obfs: obfs,
  69. Users: []option.Hysteria2User{{
  70. Password: "password",
  71. }},
  72. InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{
  73. TLS: &option.InboundTLSOptions{
  74. Enabled: true,
  75. ServerName: "example.org",
  76. CertificatePath: certPem,
  77. KeyPath: keyPem,
  78. },
  79. },
  80. },
  81. },
  82. },
  83. Outbounds: []option.Outbound{
  84. {
  85. Type: C.TypeDirect,
  86. },
  87. {
  88. Type: C.TypeHysteria2,
  89. Tag: "hy2-out",
  90. Options: &option.Hysteria2OutboundOptions{
  91. ServerOptions: option.ServerOptions{
  92. Server: "127.0.0.1",
  93. ServerPort: serverPort,
  94. },
  95. ServerPorts: serverPorts,
  96. HopInterval: badoption.Duration(hopInterval),
  97. UpMbps: 100,
  98. DownMbps: 100,
  99. Obfs: obfs,
  100. Password: "password",
  101. OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
  102. TLS: &option.OutboundTLSOptions{
  103. Enabled: true,
  104. ServerName: "example.org",
  105. CertificatePath: certPem,
  106. },
  107. },
  108. },
  109. },
  110. },
  111. Route: &option.RouteOptions{
  112. Rules: []option.Rule{
  113. {
  114. Type: C.RuleTypeDefault,
  115. DefaultOptions: option.DefaultRule{
  116. RawDefaultRule: option.RawDefaultRule{
  117. Inbound: []string{"mixed-in"},
  118. },
  119. RuleAction: option.RuleAction{
  120. Action: C.RuleActionTypeRoute,
  121. RouteOptions: option.RouteActionOptions{
  122. Outbound: "hy2-out",
  123. },
  124. },
  125. },
  126. },
  127. },
  128. },
  129. })
  130. testSuitLargeUDP(t, clientPort, testPort)
  131. if portHop {
  132. time.Sleep(5 * time.Second)
  133. testSuitLargeUDP(t, clientPort, testPort)
  134. }
  135. }
  136. func TestHysteria2Inbound(t *testing.T) {
  137. caPem, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
  138. startInstance(t, option.Options{
  139. Inbounds: []option.Inbound{
  140. {
  141. Type: C.TypeHysteria2,
  142. Options: &option.Hysteria2InboundOptions{
  143. ListenOptions: option.ListenOptions{
  144. Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
  145. ListenPort: serverPort,
  146. },
  147. Obfs: &option.Hysteria2Obfs{
  148. Type: hysteria2.ObfsTypeSalamander,
  149. Password: "cry_me_a_r1ver",
  150. },
  151. Users: []option.Hysteria2User{{
  152. Password: "password",
  153. }},
  154. InboundTLSOptionsContainer: option.InboundTLSOptionsContainer{
  155. TLS: &option.InboundTLSOptions{
  156. Enabled: true,
  157. ServerName: "example.org",
  158. CertificatePath: certPem,
  159. KeyPath: keyPem,
  160. },
  161. },
  162. },
  163. },
  164. },
  165. })
  166. startDockerContainer(t, DockerOptions{
  167. Image: ImageHysteria2,
  168. Ports: []uint16{serverPort, clientPort},
  169. Cmd: []string{"client", "-c", "/etc/hysteria/config.yml", "--disable-update-check", "--log-level", "debug"},
  170. Bind: map[string]string{
  171. "hysteria2-client.yml": "/etc/hysteria/config.yml",
  172. caPem: "/etc/hysteria/ca.pem",
  173. },
  174. })
  175. testSuit(t, clientPort, testPort)
  176. }
  177. func TestHysteria2Outbound(t *testing.T) {
  178. _, certPem, keyPem := createSelfSignedCertificate(t, "example.org")
  179. startDockerContainer(t, DockerOptions{
  180. Image: ImageHysteria2,
  181. Ports: []uint16{testPort},
  182. Cmd: []string{"server", "-c", "/etc/hysteria/config.yml", "--disable-update-check", "--log-level", "debug"},
  183. Bind: map[string]string{
  184. "hysteria2-server.yml": "/etc/hysteria/config.yml",
  185. certPem: "/etc/hysteria/cert.pem",
  186. keyPem: "/etc/hysteria/key.pem",
  187. },
  188. })
  189. startInstance(t, option.Options{
  190. Inbounds: []option.Inbound{
  191. {
  192. Type: C.TypeMixed,
  193. Options: &option.HTTPMixedInboundOptions{
  194. ListenOptions: option.ListenOptions{
  195. Listen: common.Ptr(badoption.Addr(netip.IPv4Unspecified())),
  196. ListenPort: clientPort,
  197. },
  198. },
  199. },
  200. },
  201. Outbounds: []option.Outbound{
  202. {
  203. Type: C.TypeHysteria2,
  204. Options: &option.Hysteria2OutboundOptions{
  205. ServerOptions: option.ServerOptions{
  206. Server: "127.0.0.1",
  207. ServerPort: serverPort,
  208. },
  209. Obfs: &option.Hysteria2Obfs{
  210. Type: hysteria2.ObfsTypeSalamander,
  211. Password: "cry_me_a_r1ver",
  212. },
  213. Password: "password",
  214. OutboundTLSOptionsContainer: option.OutboundTLSOptionsContainer{
  215. TLS: &option.OutboundTLSOptions{
  216. Enabled: true,
  217. ServerName: "example.org",
  218. CertificatePath: certPem,
  219. },
  220. },
  221. },
  222. },
  223. },
  224. })
  225. testSuitSimple1(t, clientPort, testPort)
  226. }