types.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. package option
  2. import (
  3. "net/http"
  4. "net/netip"
  5. "strings"
  6. "time"
  7. "github.com/sagernet/sing-dns"
  8. E "github.com/sagernet/sing/common/exceptions"
  9. F "github.com/sagernet/sing/common/format"
  10. "github.com/sagernet/sing/common/json"
  11. N "github.com/sagernet/sing/common/network"
  12. mDNS "github.com/miekg/dns"
  13. )
  14. type ListenAddress netip.Addr
  15. func NewListenAddress(addr netip.Addr) *ListenAddress {
  16. address := ListenAddress(addr)
  17. return &address
  18. }
  19. func (a ListenAddress) MarshalJSON() ([]byte, error) {
  20. addr := netip.Addr(a)
  21. if !addr.IsValid() {
  22. return nil, nil
  23. }
  24. return json.Marshal(addr.String())
  25. }
  26. func (a *ListenAddress) UnmarshalJSON(content []byte) error {
  27. var value string
  28. err := json.Unmarshal(content, &value)
  29. if err != nil {
  30. return err
  31. }
  32. addr, err := netip.ParseAddr(value)
  33. if err != nil {
  34. return err
  35. }
  36. *a = ListenAddress(addr)
  37. return nil
  38. }
  39. func (a *ListenAddress) Build() netip.Addr {
  40. if a == nil {
  41. return netip.AddrFrom4([4]byte{127, 0, 0, 1})
  42. }
  43. return (netip.Addr)(*a)
  44. }
  45. type AddrPrefix netip.Prefix
  46. func (a AddrPrefix) MarshalJSON() ([]byte, error) {
  47. prefix := netip.Prefix(a)
  48. if prefix.Bits() == prefix.Addr().BitLen() {
  49. return json.Marshal(prefix.Addr().String())
  50. } else {
  51. return json.Marshal(prefix.String())
  52. }
  53. }
  54. func (a *AddrPrefix) UnmarshalJSON(content []byte) error {
  55. var value string
  56. err := json.Unmarshal(content, &value)
  57. if err != nil {
  58. return err
  59. }
  60. prefix, prefixErr := netip.ParsePrefix(value)
  61. if prefixErr == nil {
  62. *a = AddrPrefix(prefix)
  63. return nil
  64. }
  65. addr, addrErr := netip.ParseAddr(value)
  66. if addrErr == nil {
  67. *a = AddrPrefix(netip.PrefixFrom(addr, addr.BitLen()))
  68. return nil
  69. }
  70. return prefixErr
  71. }
  72. func (a *AddrPrefix) Build() netip.Prefix {
  73. if a == nil {
  74. return netip.Prefix{}
  75. }
  76. return netip.Prefix(*a)
  77. }
  78. type NetworkList string
  79. func (v *NetworkList) UnmarshalJSON(content []byte) error {
  80. var networkList []string
  81. err := json.Unmarshal(content, &networkList)
  82. if err != nil {
  83. var networkItem string
  84. err = json.Unmarshal(content, &networkItem)
  85. if err != nil {
  86. return err
  87. }
  88. networkList = []string{networkItem}
  89. }
  90. for _, networkName := range networkList {
  91. switch networkName {
  92. case N.NetworkTCP, N.NetworkUDP:
  93. break
  94. default:
  95. return E.New("unknown network: " + networkName)
  96. }
  97. }
  98. *v = NetworkList(strings.Join(networkList, "\n"))
  99. return nil
  100. }
  101. func (v NetworkList) Build() []string {
  102. if v == "" {
  103. return []string{N.NetworkTCP, N.NetworkUDP}
  104. }
  105. return strings.Split(string(v), "\n")
  106. }
  107. type Listable[T any] []T
  108. func (l Listable[T]) MarshalJSON() ([]byte, error) {
  109. arrayList := []T(l)
  110. if len(arrayList) == 1 {
  111. return json.Marshal(arrayList[0])
  112. }
  113. return json.Marshal(arrayList)
  114. }
  115. func (l *Listable[T]) UnmarshalJSON(content []byte) error {
  116. err := json.UnmarshalDisallowUnknownFields(content, (*[]T)(l))
  117. if err == nil {
  118. return nil
  119. }
  120. var singleItem T
  121. newError := json.UnmarshalDisallowUnknownFields(content, &singleItem)
  122. if newError != nil {
  123. return E.Errors(err, newError)
  124. }
  125. *l = []T{singleItem}
  126. return nil
  127. }
  128. type DomainStrategy dns.DomainStrategy
  129. func (s DomainStrategy) String() string {
  130. switch dns.DomainStrategy(s) {
  131. case dns.DomainStrategyAsIS:
  132. return ""
  133. case dns.DomainStrategyPreferIPv4:
  134. return "prefer_ipv4"
  135. case dns.DomainStrategyPreferIPv6:
  136. return "prefer_ipv6"
  137. case dns.DomainStrategyUseIPv4:
  138. return "ipv4_only"
  139. case dns.DomainStrategyUseIPv6:
  140. return "ipv6_only"
  141. default:
  142. panic(E.New("unknown domain strategy: ", s))
  143. }
  144. }
  145. func (s DomainStrategy) MarshalJSON() ([]byte, error) {
  146. var value string
  147. switch dns.DomainStrategy(s) {
  148. case dns.DomainStrategyAsIS:
  149. value = ""
  150. // value = "as_is"
  151. case dns.DomainStrategyPreferIPv4:
  152. value = "prefer_ipv4"
  153. case dns.DomainStrategyPreferIPv6:
  154. value = "prefer_ipv6"
  155. case dns.DomainStrategyUseIPv4:
  156. value = "ipv4_only"
  157. case dns.DomainStrategyUseIPv6:
  158. value = "ipv6_only"
  159. default:
  160. return nil, E.New("unknown domain strategy: ", s)
  161. }
  162. return json.Marshal(value)
  163. }
  164. func (s *DomainStrategy) UnmarshalJSON(bytes []byte) error {
  165. var value string
  166. err := json.Unmarshal(bytes, &value)
  167. if err != nil {
  168. return err
  169. }
  170. switch value {
  171. case "", "as_is":
  172. *s = DomainStrategy(dns.DomainStrategyAsIS)
  173. case "prefer_ipv4":
  174. *s = DomainStrategy(dns.DomainStrategyPreferIPv4)
  175. case "prefer_ipv6":
  176. *s = DomainStrategy(dns.DomainStrategyPreferIPv6)
  177. case "ipv4_only":
  178. *s = DomainStrategy(dns.DomainStrategyUseIPv4)
  179. case "ipv6_only":
  180. *s = DomainStrategy(dns.DomainStrategyUseIPv6)
  181. default:
  182. return E.New("unknown domain strategy: ", value)
  183. }
  184. return nil
  185. }
  186. type Duration time.Duration
  187. func (d Duration) MarshalJSON() ([]byte, error) {
  188. return json.Marshal((time.Duration)(d).String())
  189. }
  190. func (d *Duration) UnmarshalJSON(bytes []byte) error {
  191. var value string
  192. err := json.Unmarshal(bytes, &value)
  193. if err != nil {
  194. return err
  195. }
  196. duration, err := ParseDuration(value)
  197. if err != nil {
  198. return err
  199. }
  200. *d = Duration(duration)
  201. return nil
  202. }
  203. type DNSQueryType uint16
  204. func (t DNSQueryType) String() string {
  205. typeName, loaded := mDNS.TypeToString[uint16(t)]
  206. if loaded {
  207. return typeName
  208. }
  209. return F.ToString(uint16(t))
  210. }
  211. func (t DNSQueryType) MarshalJSON() ([]byte, error) {
  212. typeName, loaded := mDNS.TypeToString[uint16(t)]
  213. if loaded {
  214. return json.Marshal(typeName)
  215. }
  216. return json.Marshal(uint16(t))
  217. }
  218. func (t *DNSQueryType) UnmarshalJSON(bytes []byte) error {
  219. var valueNumber uint16
  220. err := json.Unmarshal(bytes, &valueNumber)
  221. if err == nil {
  222. *t = DNSQueryType(valueNumber)
  223. return nil
  224. }
  225. var valueString string
  226. err = json.Unmarshal(bytes, &valueString)
  227. if err == nil {
  228. queryType, loaded := mDNS.StringToType[valueString]
  229. if loaded {
  230. *t = DNSQueryType(queryType)
  231. return nil
  232. }
  233. }
  234. return E.New("unknown DNS query type: ", string(bytes))
  235. }
  236. func DNSQueryTypeToString(queryType uint16) string {
  237. typeName, loaded := mDNS.TypeToString[queryType]
  238. if loaded {
  239. return typeName
  240. }
  241. return F.ToString(queryType)
  242. }
  243. type HTTPHeader map[string]Listable[string]
  244. func (h HTTPHeader) Build() http.Header {
  245. header := make(http.Header)
  246. for name, values := range h {
  247. for _, value := range values {
  248. header.Add(name, value)
  249. }
  250. }
  251. return header
  252. }