1
0

xdns_test.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. package maskcompat
  2. import (
  3. "encoding/json"
  4. "testing"
  5. "github.com/xtls/xray-core/infra/conf"
  6. )
  7. // buildXdnsSettings runs an xdns mask's settings through conf.XDNS, the loader
  8. // the core calls at startup, so the test's verdict is the core's verdict.
  9. func buildXdnsSettings(t *testing.T, settings any) error {
  10. t.Helper()
  11. raw, err := json.Marshal(settings)
  12. if err != nil {
  13. t.Fatalf("marshal xdns settings: %v", err)
  14. }
  15. var mask conf.XDNS
  16. if err := json.Unmarshal(raw, &mask); err != nil {
  17. return err
  18. }
  19. _, err = mask.Build()
  20. return err
  21. }
  22. func TestUpgradeLegacyXdns(t *testing.T) {
  23. tests := []struct {
  24. name string
  25. mask string
  26. want string
  27. }{
  28. {
  29. name: "bare server domain becomes TXT with the legacy EDNS0 size",
  30. mask: `{"type":"xdns","settings":{"domains":["t.example.com"]}}`,
  31. want: `{"domains":[{"edns0":1232,"name":"t.example.com","types":[16]}]}`,
  32. },
  33. {
  34. name: "method suffixes map to their record types",
  35. mask: `{"type":"xdns","settings":{"domains":["a.example.com:a","q.example.com:AAAA","t.example.com:txt"]}}`,
  36. want: `{"domains":[{"edns0":1232,"name":"a.example.com","types":[1]},{"edns0":1232,"name":"q.example.com","types":[28]},{"edns0":1232,"name":"t.example.com","types":[16]}]}`,
  37. },
  38. {
  39. name: "client resolver splits into its domain and a udp resolver",
  40. mask: `{"type":"XDNS","settings":{"resolvers":["t.example.com:a+udp://8.8.8.8:53"]}}`,
  41. want: `{"domains":[{"edns0":1232,"name":"t.example.com","types":[1]}],"resolvers":[{"settings":{"addr":"8.8.8.8:53"},"type":"udp"}]}`,
  42. },
  43. {
  44. name: "a resolver for an already listed domain adds no duplicate",
  45. mask: `{"type":"xdns","settings":{"domains":["t.example.com"],"resolvers":["T.example.com+udp://1.1.1.1:53"]}}`,
  46. want: `{"domains":[{"edns0":1232,"name":"t.example.com","types":[16]}],"resolvers":[{"settings":{"addr":"1.1.1.1:53"},"type":"udp"}]}`,
  47. },
  48. {
  49. name: "entries the old core refused are dropped",
  50. mask: `{"type":"xdns","settings":{"domains":["t.example.com","m.example.com:mx"],"resolvers":["1.1.1.1:53"]}}`,
  51. want: `{"domains":[{"edns0":1232,"name":"t.example.com","types":[16]}]}`,
  52. },
  53. }
  54. for _, tc := range tests {
  55. t.Run(tc.name, func(t *testing.T) {
  56. var mask map[string]any
  57. if err := json.Unmarshal([]byte(tc.mask), &mask); err != nil {
  58. t.Fatalf("unmarshal mask: %v", err)
  59. }
  60. if err := buildXdnsSettings(t, mask["settings"]); err == nil {
  61. t.Fatal("the core accepted the legacy string shape; the upgrade is no longer needed")
  62. }
  63. finalmask := map[string]any{"udp": []any{mask}}
  64. if !UpgradeLegacyXdns(finalmask) {
  65. t.Fatal("UpgradeLegacyXdns reported no change for a legacy mask")
  66. }
  67. got, err := json.Marshal(mask["settings"])
  68. if err != nil {
  69. t.Fatalf("marshal upgraded settings: %v", err)
  70. }
  71. if string(got) != tc.want {
  72. t.Fatalf("upgraded settings\n got: %s\nwant: %s", got, tc.want)
  73. }
  74. if err := buildXdnsSettings(t, mask["settings"]); err != nil {
  75. t.Fatalf("the core refuses the upgraded settings: %v", err)
  76. }
  77. })
  78. }
  79. }
  80. func TestUpgradeLegacyXdnsLeavesCurrentShapeAlone(t *testing.T) {
  81. const current = `{"udp":[{"type":"xdns","settings":{"domains":[{"name":"t.example.com","types":[16,28],"edns0":1232}],"resolvers":[{"type":"tcp","settings":{"addr":"8.8.8.8:53"}}],"extraPoll":2}},{"type":"salamander","settings":{"password":"x"}}]}`
  82. var finalmask map[string]any
  83. if err := json.Unmarshal([]byte(current), &finalmask); err != nil {
  84. t.Fatalf("unmarshal finalmask: %v", err)
  85. }
  86. if UpgradeLegacyXdns(finalmask) {
  87. t.Fatal("UpgradeLegacyXdns rewrote a mask that is already in the object shape")
  88. }
  89. var want map[string]any
  90. _ = json.Unmarshal([]byte(current), &want)
  91. got, _ := json.Marshal(finalmask)
  92. wantJSON, _ := json.Marshal(want)
  93. if string(got) != string(wantJSON) {
  94. t.Fatalf("finalmask changed\n got: %s\nwant: %s", got, wantJSON)
  95. }
  96. }