transport_test.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. package conf_test
  2. import (
  3. "encoding/json"
  4. "testing"
  5. "github.com/golang/protobuf/proto"
  6. "github.com/xtls/xray-core/common/protocol"
  7. "github.com/xtls/xray-core/common/serial"
  8. . "github.com/xtls/xray-core/infra/conf"
  9. "github.com/xtls/xray-core/transport/global"
  10. "github.com/xtls/xray-core/transport/internet"
  11. "github.com/xtls/xray-core/transport/internet/grpc"
  12. "github.com/xtls/xray-core/transport/internet/headers/http"
  13. "github.com/xtls/xray-core/transport/internet/headers/noop"
  14. "github.com/xtls/xray-core/transport/internet/headers/tls"
  15. "github.com/xtls/xray-core/transport/internet/kcp"
  16. "github.com/xtls/xray-core/transport/internet/quic"
  17. "github.com/xtls/xray-core/transport/internet/tcp"
  18. "github.com/xtls/xray-core/transport/internet/websocket"
  19. )
  20. func TestSocketConfig(t *testing.T) {
  21. createParser := func() func(string) (proto.Message, error) {
  22. return func(s string) (proto.Message, error) {
  23. config := new(SocketConfig)
  24. if err := json.Unmarshal([]byte(s), config); err != nil {
  25. return nil, err
  26. }
  27. return config.Build()
  28. }
  29. }
  30. // test "tcpFastOpen": true, queue length 256 is expected. other parameters are tested here too
  31. expectedOutput := &internet.SocketConfig{
  32. Mark: 1,
  33. Tfo: 256,
  34. DomainStrategy: internet.DomainStrategy_USE_IP,
  35. DialerProxy: "tag",
  36. }
  37. runMultiTestCase(t, []TestCase{
  38. {
  39. Input: `{
  40. "mark": 1,
  41. "tcpFastOpen": true,
  42. "domainStrategy": "UseIP",
  43. "dialerProxy": "tag"
  44. }`,
  45. Parser: createParser(),
  46. Output: expectedOutput,
  47. },
  48. })
  49. if expectedOutput.ParseTFOValue() != 256 {
  50. t.Fatalf("unexpected parsed TFO value, which should be 256")
  51. }
  52. // test "tcpFastOpen": false, disabled TFO is expected
  53. expectedOutput = &internet.SocketConfig{
  54. Mark: 0,
  55. Tfo: -1,
  56. }
  57. runMultiTestCase(t, []TestCase{
  58. {
  59. Input: `{
  60. "tcpFastOpen": false
  61. }`,
  62. Parser: createParser(),
  63. Output: expectedOutput,
  64. },
  65. })
  66. if expectedOutput.ParseTFOValue() != 0 {
  67. t.Fatalf("unexpected parsed TFO value, which should be 0")
  68. }
  69. // test "tcpFastOpen": 65535, queue length 65535 is expected
  70. expectedOutput = &internet.SocketConfig{
  71. Mark: 0,
  72. Tfo: 65535,
  73. }
  74. runMultiTestCase(t, []TestCase{
  75. {
  76. Input: `{
  77. "tcpFastOpen": 65535
  78. }`,
  79. Parser: createParser(),
  80. Output: expectedOutput,
  81. },
  82. })
  83. if expectedOutput.ParseTFOValue() != 65535 {
  84. t.Fatalf("unexpected parsed TFO value, which should be 65535")
  85. }
  86. // test "tcpFastOpen": -65535, disable TFO is expected
  87. expectedOutput = &internet.SocketConfig{
  88. Mark: 0,
  89. Tfo: -65535,
  90. }
  91. runMultiTestCase(t, []TestCase{
  92. {
  93. Input: `{
  94. "tcpFastOpen": -65535
  95. }`,
  96. Parser: createParser(),
  97. Output: expectedOutput,
  98. },
  99. })
  100. if expectedOutput.ParseTFOValue() != 0 {
  101. t.Fatalf("unexpected parsed TFO value, which should be 0")
  102. }
  103. // test "tcpFastOpen": 0, no operation is expected
  104. expectedOutput = &internet.SocketConfig{
  105. Mark: 0,
  106. Tfo: 0,
  107. }
  108. runMultiTestCase(t, []TestCase{
  109. {
  110. Input: `{
  111. "tcpFastOpen": 0
  112. }`,
  113. Parser: createParser(),
  114. Output: expectedOutput,
  115. },
  116. })
  117. if expectedOutput.ParseTFOValue() != -1 {
  118. t.Fatalf("unexpected parsed TFO value, which should be -1")
  119. }
  120. // test omit "tcpFastOpen", no operation is expected
  121. expectedOutput = &internet.SocketConfig{
  122. Mark: 0,
  123. Tfo: 0,
  124. }
  125. runMultiTestCase(t, []TestCase{
  126. {
  127. Input: `{}`,
  128. Parser: createParser(),
  129. Output: expectedOutput,
  130. },
  131. })
  132. if expectedOutput.ParseTFOValue() != -1 {
  133. t.Fatalf("unexpected parsed TFO value, which should be -1")
  134. }
  135. // test "tcpFastOpen": null, no operation is expected
  136. expectedOutput = &internet.SocketConfig{
  137. Mark: 0,
  138. Tfo: 0,
  139. }
  140. runMultiTestCase(t, []TestCase{
  141. {
  142. Input: `{
  143. "tcpFastOpen": null
  144. }`,
  145. Parser: createParser(),
  146. Output: expectedOutput,
  147. },
  148. })
  149. if expectedOutput.ParseTFOValue() != -1 {
  150. t.Fatalf("unexpected parsed TFO value, which should be -1")
  151. }
  152. }
  153. func TestTransportConfig(t *testing.T) {
  154. createParser := func() func(string) (proto.Message, error) {
  155. return func(s string) (proto.Message, error) {
  156. config := new(TransportConfig)
  157. if err := json.Unmarshal([]byte(s), config); err != nil {
  158. return nil, err
  159. }
  160. return config.Build()
  161. }
  162. }
  163. runMultiTestCase(t, []TestCase{
  164. {
  165. Input: `{
  166. "tcpSettings": {
  167. "header": {
  168. "type": "http",
  169. "request": {
  170. "version": "1.1",
  171. "method": "GET",
  172. "path": "/b",
  173. "headers": {
  174. "a": "b",
  175. "c": "d"
  176. }
  177. },
  178. "response": {
  179. "version": "1.0",
  180. "status": "404",
  181. "reason": "Not Found"
  182. }
  183. }
  184. },
  185. "kcpSettings": {
  186. "mtu": 1200,
  187. "header": {
  188. "type": "none"
  189. }
  190. },
  191. "wsSettings": {
  192. "path": "/t"
  193. },
  194. "quicSettings": {
  195. "key": "abcd",
  196. "header": {
  197. "type": "dtls"
  198. }
  199. },
  200. "grpcSettings": {
  201. "serviceName": "name",
  202. "multiMode": true
  203. }
  204. }`,
  205. Parser: createParser(),
  206. Output: &global.Config{
  207. TransportSettings: []*internet.TransportConfig{
  208. {
  209. ProtocolName: "tcp",
  210. Settings: serial.ToTypedMessage(&tcp.Config{
  211. HeaderSettings: serial.ToTypedMessage(&http.Config{
  212. Request: &http.RequestConfig{
  213. Version: &http.Version{Value: "1.1"},
  214. Method: &http.Method{Value: "GET"},
  215. Uri: []string{"/b"},
  216. Header: []*http.Header{
  217. {Name: "a", Value: []string{"b"}},
  218. {Name: "c", Value: []string{"d"}},
  219. },
  220. },
  221. Response: &http.ResponseConfig{
  222. Version: &http.Version{Value: "1.0"},
  223. Status: &http.Status{Code: "404", Reason: "Not Found"},
  224. Header: []*http.Header{
  225. {
  226. Name: "Content-Type",
  227. Value: []string{"application/octet-stream", "video/mpeg"},
  228. },
  229. {
  230. Name: "Transfer-Encoding",
  231. Value: []string{"chunked"},
  232. },
  233. {
  234. Name: "Connection",
  235. Value: []string{"keep-alive"},
  236. },
  237. {
  238. Name: "Pragma",
  239. Value: []string{"no-cache"},
  240. },
  241. {
  242. Name: "Cache-Control",
  243. Value: []string{"private", "no-cache"},
  244. },
  245. },
  246. },
  247. }),
  248. }),
  249. },
  250. {
  251. ProtocolName: "mkcp",
  252. Settings: serial.ToTypedMessage(&kcp.Config{
  253. Mtu: &kcp.MTU{Value: 1200},
  254. HeaderConfig: serial.ToTypedMessage(&noop.Config{}),
  255. }),
  256. },
  257. {
  258. ProtocolName: "websocket",
  259. Settings: serial.ToTypedMessage(&websocket.Config{
  260. Path: "/t",
  261. }),
  262. },
  263. {
  264. ProtocolName: "quic",
  265. Settings: serial.ToTypedMessage(&quic.Config{
  266. Key: "abcd",
  267. Security: &protocol.SecurityConfig{
  268. Type: protocol.SecurityType_NONE,
  269. },
  270. Header: serial.ToTypedMessage(&tls.PacketConfig{}),
  271. }),
  272. },
  273. {
  274. ProtocolName: "grpc",
  275. Settings: serial.ToTypedMessage(&grpc.Config{
  276. ServiceName: "name",
  277. MultiMode: true,
  278. }),
  279. },
  280. },
  281. },
  282. },
  283. {
  284. Input: `{
  285. "gunSettings": {
  286. "serviceName": "name"
  287. }
  288. }`,
  289. Parser: createParser(),
  290. Output: &global.Config{
  291. TransportSettings: []*internet.TransportConfig{
  292. {
  293. ProtocolName: "grpc",
  294. Settings: serial.ToTypedMessage(&grpc.Config{
  295. ServiceName: "name",
  296. }),
  297. },
  298. },
  299. },
  300. },
  301. })
  302. }