outbound.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. package option
  2. import (
  3. C "github.com/sagernet/sing-box/constant"
  4. "github.com/sagernet/sing/common"
  5. E "github.com/sagernet/sing/common/exceptions"
  6. M "github.com/sagernet/sing/common/metadata"
  7. "github.com/goccy/go-json"
  8. )
  9. type _Outbound struct {
  10. Type string `json:"type"`
  11. Tag string `json:"tag,omitempty"`
  12. DirectOptions DirectOutboundOptions `json:"-"`
  13. SocksOptions SocksOutboundOptions `json:"-"`
  14. HTTPOptions HTTPOutboundOptions `json:"-"`
  15. ShadowsocksOptions ShadowsocksOutboundOptions `json:"-"`
  16. VMessOptions VMessOutboundOptions `json:"-"`
  17. SelectorOptions SelectorOutboundOptions `json:"-"`
  18. URLTestOptions URLTestOutboundOptions `json:"-"`
  19. }
  20. type Outbound _Outbound
  21. func (h Outbound) Equals(other Outbound) bool {
  22. return h.Type == other.Type &&
  23. h.Tag == other.Tag &&
  24. h.DirectOptions == other.DirectOptions &&
  25. h.SocksOptions == other.SocksOptions &&
  26. h.HTTPOptions == other.HTTPOptions &&
  27. h.ShadowsocksOptions == other.ShadowsocksOptions &&
  28. h.VMessOptions == other.VMessOptions &&
  29. common.Equals(h.SelectorOptions, other.SelectorOptions) &&
  30. common.Equals(h.URLTestOptions, other.URLTestOptions)
  31. }
  32. func (h Outbound) MarshalJSON() ([]byte, error) {
  33. var v any
  34. switch h.Type {
  35. case C.TypeDirect:
  36. v = h.DirectOptions
  37. case C.TypeBlock, C.TypeDNS:
  38. v = nil
  39. case C.TypeSocks:
  40. v = h.SocksOptions
  41. case C.TypeHTTP:
  42. v = h.HTTPOptions
  43. case C.TypeShadowsocks:
  44. v = h.ShadowsocksOptions
  45. case C.TypeVMess:
  46. v = h.VMessOptions
  47. case C.TypeSelector:
  48. v = h.SelectorOptions
  49. case C.TypeURLTest:
  50. v = h.URLTestOptions
  51. default:
  52. return nil, E.New("unknown outbound type: ", h.Type)
  53. }
  54. return MarshallObjects((_Outbound)(h), v)
  55. }
  56. func (h *Outbound) UnmarshalJSON(bytes []byte) error {
  57. err := json.Unmarshal(bytes, (*_Outbound)(h))
  58. if err != nil {
  59. return err
  60. }
  61. var v any
  62. switch h.Type {
  63. case C.TypeDirect:
  64. v = &h.DirectOptions
  65. case C.TypeBlock, C.TypeDNS:
  66. v = nil
  67. case C.TypeSocks:
  68. v = &h.SocksOptions
  69. case C.TypeHTTP:
  70. v = &h.HTTPOptions
  71. case C.TypeShadowsocks:
  72. v = &h.ShadowsocksOptions
  73. case C.TypeVMess:
  74. v = &h.VMessOptions
  75. case C.TypeSelector:
  76. v = &h.SelectorOptions
  77. case C.TypeURLTest:
  78. v = &h.URLTestOptions
  79. default:
  80. return nil
  81. }
  82. err = UnmarshallExcluded(bytes, (*_Outbound)(h), v)
  83. if err != nil {
  84. return E.Cause(err, "outbound options")
  85. }
  86. return nil
  87. }
  88. type DialerOptions struct {
  89. Detour string `json:"detour,omitempty"`
  90. BindInterface string `json:"bind_interface,omitempty"`
  91. ProtectPath string `json:"protect_path,omitempty"`
  92. RoutingMark int `json:"routing_mark,omitempty"`
  93. ReuseAddr bool `json:"reuse_addr,omitempty"`
  94. ConnectTimeout Duration `json:"connect_timeout,omitempty"`
  95. TCPFastOpen bool `json:"tcp_fast_open,omitempty"`
  96. }
  97. type OutboundDialerOptions struct {
  98. DialerOptions
  99. DomainStrategy DomainStrategy `json:"domain_strategy,omitempty"`
  100. FallbackDelay Duration `json:"fallback_delay,omitempty"`
  101. }
  102. type ServerOptions struct {
  103. Server string `json:"server"`
  104. ServerPort uint16 `json:"server_port"`
  105. }
  106. func (o ServerOptions) Build() M.Socksaddr {
  107. return M.ParseSocksaddrHostPort(o.Server, o.ServerPort)
  108. }
  109. type DirectOutboundOptions struct {
  110. OutboundDialerOptions
  111. OverrideAddress string `json:"override_address,omitempty"`
  112. OverridePort uint16 `json:"override_port,omitempty"`
  113. }
  114. type SocksOutboundOptions struct {
  115. OutboundDialerOptions
  116. ServerOptions
  117. Version string `json:"version,omitempty"`
  118. Username string `json:"username,omitempty"`
  119. Password string `json:"password,omitempty"`
  120. Network NetworkList `json:"network,omitempty"`
  121. }
  122. type HTTPOutboundOptions struct {
  123. OutboundDialerOptions
  124. ServerOptions
  125. Username string `json:"username,omitempty"`
  126. Password string `json:"password,omitempty"`
  127. TLSOptions *OutboundTLSOptions `json:"tls,omitempty"`
  128. }
  129. type OutboundTLSOptions struct {
  130. Enabled bool `json:"enabled,omitempty"`
  131. DisableSNI bool `json:"disable_sni,omitempty"`
  132. ServerName string `json:"server_name,omitempty"`
  133. Insecure bool `json:"insecure,omitempty"`
  134. }
  135. type ShadowsocksOutboundOptions struct {
  136. OutboundDialerOptions
  137. ServerOptions
  138. Method string `json:"method"`
  139. Password string `json:"password"`
  140. Network NetworkList `json:"network,omitempty"`
  141. }
  142. type VMessOutboundOptions struct {
  143. OutboundDialerOptions
  144. ServerOptions
  145. UUID string `json:"uuid"`
  146. Security string `json:"security"`
  147. AlterId int `json:"alter_id,omitempty"`
  148. GlobalPadding bool `json:"global_padding,omitempty"`
  149. AuthenticatedLength bool `json:"authenticated_length,omitempty"`
  150. Network NetworkList `json:"network,omitempty"`
  151. TLSOptions *OutboundTLSOptions `json:"tls,omitempty"`
  152. }
  153. type SelectorOutboundOptions struct {
  154. Outbounds []string `json:"outbounds"`
  155. Default string `json:"default,omitempty"`
  156. }
  157. func (o SelectorOutboundOptions) Equals(other SelectorOutboundOptions) bool {
  158. return common.ComparableSliceEquals(o.Outbounds, other.Outbounds) &&
  159. o.Default == other.Default
  160. }
  161. type URLTestOutboundOptions struct {
  162. Outbounds []string `json:"outbounds"`
  163. URL string `json:"url,omitempty"`
  164. Interval Duration `json:"interval,omitempty"`
  165. Tolerance uint16 `json:"tolerance,omitempty"`
  166. }
  167. func (o URLTestOutboundOptions) Equals(other URLTestOutboundOptions) bool {
  168. return common.ComparableSliceEquals(o.Outbounds, other.Outbounds) &&
  169. o.URL == other.URL &&
  170. o.Interval == other.Interval &&
  171. o.Tolerance == other.Tolerance
  172. }