types.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. package option
  2. import (
  3. "net/netip"
  4. "strings"
  5. "time"
  6. "github.com/sagernet/sing-box/common/json"
  7. "github.com/sagernet/sing-dns"
  8. E "github.com/sagernet/sing/common/exceptions"
  9. N "github.com/sagernet/sing/common/network"
  10. )
  11. type ListenAddress netip.Addr
  12. func (a ListenAddress) MarshalJSON() ([]byte, error) {
  13. addr := netip.Addr(a)
  14. if !addr.IsValid() {
  15. return json.Marshal("")
  16. }
  17. return json.Marshal(addr.String())
  18. }
  19. func (a *ListenAddress) UnmarshalJSON(content []byte) error {
  20. var value string
  21. err := json.Unmarshal(content, &value)
  22. if err != nil {
  23. return err
  24. }
  25. addr, err := netip.ParseAddr(value)
  26. if err != nil {
  27. return err
  28. }
  29. *a = ListenAddress(addr)
  30. return nil
  31. }
  32. type NetworkList string
  33. func (v *NetworkList) UnmarshalJSON(content []byte) error {
  34. var networkList []string
  35. err := json.Unmarshal(content, &networkList)
  36. if err != nil {
  37. var networkItem string
  38. err = json.Unmarshal(content, &networkItem)
  39. if err != nil {
  40. return err
  41. }
  42. networkList = []string{networkItem}
  43. }
  44. for _, networkName := range networkList {
  45. switch networkName {
  46. case N.NetworkTCP, N.NetworkUDP:
  47. break
  48. default:
  49. return E.New("unknown network: " + networkName)
  50. }
  51. }
  52. *v = NetworkList(strings.Join(networkList, "\n"))
  53. return nil
  54. }
  55. func (v NetworkList) Build() []string {
  56. if v == "" {
  57. return []string{N.NetworkTCP, N.NetworkUDP}
  58. }
  59. return strings.Split(string(v), "\n")
  60. }
  61. type Listable[T comparable] []T
  62. func (l Listable[T]) MarshalJSON() ([]byte, error) {
  63. arrayList := []T(l)
  64. if len(arrayList) == 1 {
  65. return json.Marshal(arrayList[0])
  66. }
  67. return json.Marshal(arrayList)
  68. }
  69. func (l *Listable[T]) UnmarshalJSON(content []byte) error {
  70. err := json.Unmarshal(content, (*[]T)(l))
  71. if err == nil {
  72. return nil
  73. }
  74. var singleItem T
  75. err = json.Unmarshal(content, &singleItem)
  76. if err != nil {
  77. return err
  78. }
  79. *l = []T{singleItem}
  80. return nil
  81. }
  82. type DomainStrategy dns.DomainStrategy
  83. func (s DomainStrategy) MarshalJSON() ([]byte, error) {
  84. var value string
  85. switch dns.DomainStrategy(s) {
  86. case dns.DomainStrategyAsIS:
  87. value = ""
  88. // value = "AsIS"
  89. case dns.DomainStrategyPreferIPv4:
  90. value = "prefer_ipv4"
  91. case dns.DomainStrategyPreferIPv6:
  92. value = "prefer_ipv6"
  93. case dns.DomainStrategyUseIPv4:
  94. value = "ipv4_only"
  95. case dns.DomainStrategyUseIPv6:
  96. value = "ipv6_only"
  97. default:
  98. return nil, E.New("unknown domain strategy: ", s)
  99. }
  100. return json.Marshal(value)
  101. }
  102. func (s *DomainStrategy) UnmarshalJSON(bytes []byte) error {
  103. var value string
  104. err := json.Unmarshal(bytes, &value)
  105. if err != nil {
  106. return err
  107. }
  108. switch value {
  109. case "", "AsIS":
  110. *s = DomainStrategy(dns.DomainStrategyAsIS)
  111. case "prefer_ipv4":
  112. *s = DomainStrategy(dns.DomainStrategyPreferIPv4)
  113. case "prefer_ipv6":
  114. *s = DomainStrategy(dns.DomainStrategyPreferIPv6)
  115. case "ipv4_only":
  116. *s = DomainStrategy(dns.DomainStrategyUseIPv4)
  117. case "ipv6_only":
  118. *s = DomainStrategy(dns.DomainStrategyUseIPv6)
  119. default:
  120. return E.New("unknown domain strategy: ", value)
  121. }
  122. return nil
  123. }
  124. type Duration time.Duration
  125. func (d Duration) MarshalJSON() ([]byte, error) {
  126. return json.Marshal((time.Duration)(d).String())
  127. }
  128. func (d *Duration) UnmarshalJSON(bytes []byte) error {
  129. var value string
  130. err := json.Unmarshal(bytes, &value)
  131. if err != nil {
  132. return err
  133. }
  134. duration, err := time.ParseDuration(value)
  135. if err != nil {
  136. return err
  137. }
  138. *d = Duration(duration)
  139. return nil
  140. }
  141. type ListenPrefix netip.Prefix
  142. func (p ListenPrefix) MarshalJSON() ([]byte, error) {
  143. prefix := netip.Prefix(p)
  144. if !prefix.IsValid() {
  145. return json.Marshal(nil)
  146. }
  147. return json.Marshal(prefix.String())
  148. }
  149. func (p *ListenPrefix) UnmarshalJSON(bytes []byte) error {
  150. var value string
  151. err := json.Unmarshal(bytes, &value)
  152. if err != nil {
  153. return err
  154. }
  155. prefix, err := netip.ParsePrefix(value)
  156. if err != nil {
  157. return err
  158. }
  159. *p = ListenPrefix(prefix)
  160. return nil
  161. }
  162. func (p *ListenPrefix) Build() netip.Prefix {
  163. if p == nil {
  164. return netip.Prefix{}
  165. }
  166. return netip.Prefix(*p)
  167. }