types.go 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. package option
  2. import (
  3. "net/http"
  4. "net/netip"
  5. "strings"
  6. "time"
  7. "github.com/sagernet/sing-box/common/json"
  8. "github.com/sagernet/sing-dns"
  9. E "github.com/sagernet/sing/common/exceptions"
  10. F "github.com/sagernet/sing/common/format"
  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 NetworkList string
  46. func (v *NetworkList) UnmarshalJSON(content []byte) error {
  47. var networkList []string
  48. err := json.Unmarshal(content, &networkList)
  49. if err != nil {
  50. var networkItem string
  51. err = json.Unmarshal(content, &networkItem)
  52. if err != nil {
  53. return err
  54. }
  55. networkList = []string{networkItem}
  56. }
  57. for _, networkName := range networkList {
  58. switch networkName {
  59. case N.NetworkTCP, N.NetworkUDP:
  60. break
  61. default:
  62. return E.New("unknown network: " + networkName)
  63. }
  64. }
  65. *v = NetworkList(strings.Join(networkList, "\n"))
  66. return nil
  67. }
  68. func (v NetworkList) Build() []string {
  69. if v == "" {
  70. return []string{N.NetworkTCP, N.NetworkUDP}
  71. }
  72. return strings.Split(string(v), "\n")
  73. }
  74. type Listable[T comparable] []T
  75. func (l Listable[T]) MarshalJSON() ([]byte, error) {
  76. arrayList := []T(l)
  77. if len(arrayList) == 1 {
  78. return json.Marshal(arrayList[0])
  79. }
  80. return json.Marshal(arrayList)
  81. }
  82. func (l *Listable[T]) UnmarshalJSON(content []byte) error {
  83. err := json.Unmarshal(content, (*[]T)(l))
  84. if err == nil {
  85. return nil
  86. }
  87. var singleItem T
  88. newError := json.Unmarshal(content, &singleItem)
  89. if newError != nil {
  90. return E.Errors(err, newError)
  91. }
  92. *l = []T{singleItem}
  93. return nil
  94. }
  95. type DomainStrategy dns.DomainStrategy
  96. func (s DomainStrategy) MarshalJSON() ([]byte, error) {
  97. var value string
  98. switch dns.DomainStrategy(s) {
  99. case dns.DomainStrategyAsIS:
  100. value = ""
  101. // value = "AsIS"
  102. case dns.DomainStrategyPreferIPv4:
  103. value = "prefer_ipv4"
  104. case dns.DomainStrategyPreferIPv6:
  105. value = "prefer_ipv6"
  106. case dns.DomainStrategyUseIPv4:
  107. value = "ipv4_only"
  108. case dns.DomainStrategyUseIPv6:
  109. value = "ipv6_only"
  110. default:
  111. return nil, E.New("unknown domain strategy: ", s)
  112. }
  113. return json.Marshal(value)
  114. }
  115. func (s *DomainStrategy) UnmarshalJSON(bytes []byte) error {
  116. var value string
  117. err := json.Unmarshal(bytes, &value)
  118. if err != nil {
  119. return err
  120. }
  121. switch value {
  122. case "", "as_is":
  123. *s = DomainStrategy(dns.DomainStrategyAsIS)
  124. case "prefer_ipv4":
  125. *s = DomainStrategy(dns.DomainStrategyPreferIPv4)
  126. case "prefer_ipv6":
  127. *s = DomainStrategy(dns.DomainStrategyPreferIPv6)
  128. case "ipv4_only":
  129. *s = DomainStrategy(dns.DomainStrategyUseIPv4)
  130. case "ipv6_only":
  131. *s = DomainStrategy(dns.DomainStrategyUseIPv6)
  132. default:
  133. return E.New("unknown domain strategy: ", value)
  134. }
  135. return nil
  136. }
  137. type Duration time.Duration
  138. func (d Duration) MarshalJSON() ([]byte, error) {
  139. return json.Marshal((time.Duration)(d).String())
  140. }
  141. func (d *Duration) UnmarshalJSON(bytes []byte) error {
  142. var value string
  143. err := json.Unmarshal(bytes, &value)
  144. if err != nil {
  145. return err
  146. }
  147. duration, err := ParseDuration(value)
  148. if err != nil {
  149. return err
  150. }
  151. *d = Duration(duration)
  152. return nil
  153. }
  154. type DNSQueryType uint16
  155. func (t DNSQueryType) String() string {
  156. typeName, loaded := mDNS.TypeToString[uint16(t)]
  157. if loaded {
  158. return typeName
  159. }
  160. return F.ToString(uint16(t))
  161. }
  162. func (t DNSQueryType) MarshalJSON() ([]byte, error) {
  163. typeName, loaded := mDNS.TypeToString[uint16(t)]
  164. if loaded {
  165. return json.Marshal(typeName)
  166. }
  167. return json.Marshal(uint16(t))
  168. }
  169. func (t *DNSQueryType) UnmarshalJSON(bytes []byte) error {
  170. var valueNumber uint16
  171. err := json.Unmarshal(bytes, &valueNumber)
  172. if err == nil {
  173. *t = DNSQueryType(valueNumber)
  174. return nil
  175. }
  176. var valueString string
  177. err = json.Unmarshal(bytes, &valueString)
  178. if err == nil {
  179. queryType, loaded := mDNS.StringToType[valueString]
  180. if loaded {
  181. *t = DNSQueryType(queryType)
  182. return nil
  183. }
  184. }
  185. return E.New("unknown DNS query type: ", string(bytes))
  186. }
  187. func DNSQueryTypeToString(queryType uint16) string {
  188. typeName, loaded := mDNS.TypeToString[queryType]
  189. if loaded {
  190. return typeName
  191. }
  192. return F.ToString(queryType)
  193. }
  194. type HTTPHeader map[string]Listable[string]
  195. func (h HTTPHeader) Build() http.Header {
  196. header := make(http.Header)
  197. for name, values := range h {
  198. for _, value := range values {
  199. header.Add(name, value)
  200. }
  201. }
  202. return header
  203. }