types.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. package option
  2. import (
  3. "strings"
  4. C "github.com/sagernet/sing-box/constant"
  5. E "github.com/sagernet/sing/common/exceptions"
  6. F "github.com/sagernet/sing/common/format"
  7. "github.com/sagernet/sing/common/json"
  8. N "github.com/sagernet/sing/common/network"
  9. mDNS "github.com/miekg/dns"
  10. )
  11. type NetworkList string
  12. func (v *NetworkList) UnmarshalJSON(content []byte) error {
  13. var networkList []string
  14. err := json.Unmarshal(content, &networkList)
  15. if err != nil {
  16. var networkItem string
  17. err = json.Unmarshal(content, &networkItem)
  18. if err != nil {
  19. return err
  20. }
  21. networkList = []string{networkItem}
  22. }
  23. for _, networkName := range networkList {
  24. switch networkName {
  25. case N.NetworkTCP, N.NetworkUDP:
  26. break
  27. default:
  28. return E.New("unknown network: " + networkName)
  29. }
  30. }
  31. *v = NetworkList(strings.Join(networkList, "\n"))
  32. return nil
  33. }
  34. func (v NetworkList) Build() []string {
  35. if v == "" {
  36. return []string{N.NetworkTCP, N.NetworkUDP}
  37. }
  38. return strings.Split(string(v), "\n")
  39. }
  40. type DomainStrategy C.DomainStrategy
  41. func (s DomainStrategy) String() string {
  42. switch C.DomainStrategy(s) {
  43. case C.DomainStrategyAsIS:
  44. return ""
  45. case C.DomainStrategyPreferIPv4:
  46. return "prefer_ipv4"
  47. case C.DomainStrategyPreferIPv6:
  48. return "prefer_ipv6"
  49. case C.DomainStrategyIPv4Only:
  50. return "ipv4_only"
  51. case C.DomainStrategyIPv6Only:
  52. return "ipv6_only"
  53. default:
  54. panic(E.New("unknown domain strategy: ", s))
  55. }
  56. }
  57. func (s DomainStrategy) MarshalJSON() ([]byte, error) {
  58. var value string
  59. switch C.DomainStrategy(s) {
  60. case C.DomainStrategyAsIS:
  61. value = ""
  62. // value = "as_is"
  63. case C.DomainStrategyPreferIPv4:
  64. value = "prefer_ipv4"
  65. case C.DomainStrategyPreferIPv6:
  66. value = "prefer_ipv6"
  67. case C.DomainStrategyIPv4Only:
  68. value = "ipv4_only"
  69. case C.DomainStrategyIPv6Only:
  70. value = "ipv6_only"
  71. default:
  72. return nil, E.New("unknown domain strategy: ", s)
  73. }
  74. return json.Marshal(value)
  75. }
  76. func (s *DomainStrategy) UnmarshalJSON(bytes []byte) error {
  77. var value string
  78. err := json.Unmarshal(bytes, &value)
  79. if err != nil {
  80. return err
  81. }
  82. switch value {
  83. case "", "as_is":
  84. *s = DomainStrategy(C.DomainStrategyAsIS)
  85. case "prefer_ipv4":
  86. *s = DomainStrategy(C.DomainStrategyPreferIPv4)
  87. case "prefer_ipv6":
  88. *s = DomainStrategy(C.DomainStrategyPreferIPv6)
  89. case "ipv4_only":
  90. *s = DomainStrategy(C.DomainStrategyIPv4Only)
  91. case "ipv6_only":
  92. *s = DomainStrategy(C.DomainStrategyIPv6Only)
  93. default:
  94. return E.New("unknown domain strategy: ", value)
  95. }
  96. return nil
  97. }
  98. type DNSQueryType uint16
  99. func (t DNSQueryType) String() string {
  100. typeName, loaded := mDNS.TypeToString[uint16(t)]
  101. if loaded {
  102. return typeName
  103. }
  104. return F.ToString(uint16(t))
  105. }
  106. func (t DNSQueryType) MarshalJSON() ([]byte, error) {
  107. typeName, loaded := mDNS.TypeToString[uint16(t)]
  108. if loaded {
  109. return json.Marshal(typeName)
  110. }
  111. return json.Marshal(uint16(t))
  112. }
  113. func (t *DNSQueryType) UnmarshalJSON(bytes []byte) error {
  114. var valueNumber uint16
  115. err := json.Unmarshal(bytes, &valueNumber)
  116. if err == nil {
  117. *t = DNSQueryType(valueNumber)
  118. return nil
  119. }
  120. var valueString string
  121. err = json.Unmarshal(bytes, &valueString)
  122. if err == nil {
  123. queryType, loaded := mDNS.StringToType[valueString]
  124. if loaded {
  125. *t = DNSQueryType(queryType)
  126. return nil
  127. }
  128. }
  129. return E.New("unknown DNS query type: ", string(bytes))
  130. }
  131. func DNSQueryTypeToString(queryType uint16) string {
  132. typeName, loaded := mDNS.TypeToString[queryType]
  133. if loaded {
  134. return typeName
  135. }
  136. return F.ToString(queryType)
  137. }
  138. type NetworkStrategy C.NetworkStrategy
  139. func (n NetworkStrategy) MarshalJSON() ([]byte, error) {
  140. return json.Marshal(C.NetworkStrategy(n).String())
  141. }
  142. func (n *NetworkStrategy) UnmarshalJSON(content []byte) error {
  143. var value string
  144. err := json.Unmarshal(content, &value)
  145. if err != nil {
  146. return err
  147. }
  148. strategy, loaded := C.StringToNetworkStrategy[value]
  149. if !loaded {
  150. return E.New("unknown network strategy: ", value)
  151. }
  152. *n = NetworkStrategy(strategy)
  153. return nil
  154. }
  155. type InterfaceType C.InterfaceType
  156. func (t InterfaceType) Build() C.InterfaceType {
  157. return C.InterfaceType(t)
  158. }
  159. func (t InterfaceType) MarshalJSON() ([]byte, error) {
  160. return json.Marshal(C.InterfaceType(t).String())
  161. }
  162. func (t *InterfaceType) UnmarshalJSON(content []byte) error {
  163. var value string
  164. err := json.Unmarshal(content, &value)
  165. if err != nil {
  166. return err
  167. }
  168. interfaceType, loaded := C.StringToInterfaceType[value]
  169. if !loaded {
  170. return E.New("unknown interface type: ", value)
  171. }
  172. *t = InterfaceType(interfaceType)
  173. return nil
  174. }