adapters.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. package constant
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "net"
  7. "net/netip"
  8. "sync"
  9. "time"
  10. N "github.com/metacubex/mihomo/common/net"
  11. "github.com/metacubex/mihomo/common/utils"
  12. "github.com/metacubex/mihomo/component/dialer"
  13. )
  14. // Adapter Type
  15. const (
  16. Direct AdapterType = iota
  17. Reject
  18. RejectDrop
  19. Compatible
  20. Pass
  21. Dns
  22. Relay
  23. Selector
  24. Fallback
  25. URLTest
  26. LoadBalance
  27. Shadowsocks
  28. ShadowsocksR
  29. Snell
  30. Socks5
  31. Http
  32. Vmess
  33. Vless
  34. Trojan
  35. Hysteria
  36. Hysteria2
  37. WireGuard
  38. Tuic
  39. Ssh
  40. )
  41. const (
  42. DefaultTCPTimeout = dialer.DefaultTCPTimeout
  43. DefaultUDPTimeout = dialer.DefaultUDPTimeout
  44. DefaultDropTime = 12 * DefaultTCPTimeout
  45. DefaultTLSTimeout = DefaultTCPTimeout
  46. )
  47. var DefaultTestURL = "https://www.gstatic.com/generate_204"
  48. var ErrNotSupport = errors.New("no support")
  49. type Connection interface {
  50. Chains() Chain
  51. AppendToChains(adapter ProxyAdapter)
  52. RemoteDestination() string
  53. }
  54. type Chain []string
  55. func (c Chain) String() string {
  56. switch len(c) {
  57. case 0:
  58. return ""
  59. case 1:
  60. return c[0]
  61. default:
  62. return fmt.Sprintf("%s[%s]", c[len(c)-1], c[0])
  63. }
  64. }
  65. func (c Chain) Last() string {
  66. switch len(c) {
  67. case 0:
  68. return ""
  69. default:
  70. return c[0]
  71. }
  72. }
  73. type Conn interface {
  74. N.ExtendedConn
  75. Connection
  76. }
  77. type PacketConn interface {
  78. N.EnhancePacketConn
  79. Connection
  80. // Deprecate WriteWithMetadata because of remote resolve DNS cause TURN failed
  81. // WriteWithMetadata(p []byte, metadata *Metadata) (n int, err error)
  82. }
  83. type Dialer interface {
  84. DialContext(ctx context.Context, network, address string) (net.Conn, error)
  85. ListenPacket(ctx context.Context, network, address string, rAddrPort netip.AddrPort) (net.PacketConn, error)
  86. }
  87. type ProxyAdapter interface {
  88. Name() string
  89. Type() AdapterType
  90. Addr() string
  91. SupportUDP() bool
  92. SupportXUDP() bool
  93. SupportTFO() bool
  94. MarshalJSON() ([]byte, error)
  95. // Deprecated: use DialContextWithDialer and ListenPacketWithDialer instead.
  96. // StreamConn wraps a protocol around net.Conn with Metadata.
  97. //
  98. // Examples:
  99. // conn, _ := net.DialContext(context.Background(), "tcp", "host:port")
  100. // conn, _ = adapter.StreamConnContext(context.Background(), conn, metadata)
  101. //
  102. // It returns a C.Conn with protocol which start with
  103. // a new session (if any)
  104. StreamConnContext(ctx context.Context, c net.Conn, metadata *Metadata) (net.Conn, error)
  105. // DialContext return a C.Conn with protocol which
  106. // contains multiplexing-related reuse logic (if any)
  107. DialContext(ctx context.Context, metadata *Metadata, opts ...dialer.Option) (Conn, error)
  108. ListenPacketContext(ctx context.Context, metadata *Metadata, opts ...dialer.Option) (PacketConn, error)
  109. // SupportUOT return UDP over TCP support
  110. SupportUOT() bool
  111. SupportWithDialer() NetWork
  112. DialContextWithDialer(ctx context.Context, dialer Dialer, metadata *Metadata) (Conn, error)
  113. ListenPacketWithDialer(ctx context.Context, dialer Dialer, metadata *Metadata) (PacketConn, error)
  114. // IsL3Protocol return ProxyAdapter working in L3 (tell dns module not pass the domain to avoid loopback)
  115. IsL3Protocol(metadata *Metadata) bool
  116. // Unwrap extracts the proxy from a proxy-group. It returns nil when nothing to extract.
  117. Unwrap(metadata *Metadata, touch bool) Proxy
  118. }
  119. type Group interface {
  120. URLTest(ctx context.Context, url string, expectedStatus utils.IntRanges[uint16]) (mp map[string]uint16, err error)
  121. GetProxies(touch bool) []Proxy
  122. Touch()
  123. }
  124. type DelayHistory struct {
  125. Time time.Time `json:"time"`
  126. Delay uint16 `json:"delay"`
  127. }
  128. type ProxyState struct {
  129. Alive bool `json:"alive"`
  130. History []DelayHistory `json:"history"`
  131. }
  132. type DelayHistoryStoreType int
  133. type Proxy interface {
  134. ProxyAdapter
  135. AliveForTestUrl(url string) bool
  136. DelayHistory() []DelayHistory
  137. ExtraDelayHistories() map[string]ProxyState
  138. LastDelayForTestUrl(url string) uint16
  139. URLTest(ctx context.Context, url string, expectedStatus utils.IntRanges[uint16]) (uint16, error)
  140. // Deprecated: use DialContext instead.
  141. Dial(metadata *Metadata) (Conn, error)
  142. // Deprecated: use DialPacketConn instead.
  143. DialUDP(metadata *Metadata) (PacketConn, error)
  144. }
  145. // AdapterType is enum of adapter type
  146. type AdapterType int
  147. func (at AdapterType) String() string {
  148. switch at {
  149. case Direct:
  150. return "Direct"
  151. case Reject:
  152. return "Reject"
  153. case RejectDrop:
  154. return "RejectDrop"
  155. case Compatible:
  156. return "Compatible"
  157. case Pass:
  158. return "Pass"
  159. case Dns:
  160. return "Dns"
  161. case Shadowsocks:
  162. return "Shadowsocks"
  163. case ShadowsocksR:
  164. return "ShadowsocksR"
  165. case Snell:
  166. return "Snell"
  167. case Socks5:
  168. return "Socks5"
  169. case Http:
  170. return "Http"
  171. case Vmess:
  172. return "Vmess"
  173. case Vless:
  174. return "Vless"
  175. case Trojan:
  176. return "Trojan"
  177. case Hysteria:
  178. return "Hysteria"
  179. case Hysteria2:
  180. return "Hysteria2"
  181. case WireGuard:
  182. return "WireGuard"
  183. case Tuic:
  184. return "Tuic"
  185. case Relay:
  186. return "Relay"
  187. case Selector:
  188. return "Selector"
  189. case Fallback:
  190. return "Fallback"
  191. case URLTest:
  192. return "URLTest"
  193. case LoadBalance:
  194. return "LoadBalance"
  195. case Ssh:
  196. return "Ssh"
  197. default:
  198. return "Unknown"
  199. }
  200. }
  201. // UDPPacket contains the data of UDP packet, and offers control/info of UDP packet's source
  202. type UDPPacket interface {
  203. // Data get the payload of UDP Packet
  204. Data() []byte
  205. // WriteBack writes the payload with source IP/Port equals addr
  206. // - variable source IP/Port is important to STUN
  207. // - if addr is not provided, WriteBack will write out UDP packet with SourceIP/Port equals to original Target,
  208. // this is important when using Fake-IP.
  209. WriteBack
  210. // Drop call after packet is used, could recycle buffer in this function.
  211. Drop()
  212. // LocalAddr returns the source IP/Port of packet
  213. LocalAddr() net.Addr
  214. }
  215. type UDPPacketInAddr interface {
  216. InAddr() net.Addr
  217. }
  218. // PacketAdapter is a UDP Packet adapter for socks/redir/tun
  219. type PacketAdapter interface {
  220. UDPPacket
  221. Metadata() *Metadata
  222. }
  223. type packetAdapter struct {
  224. UDPPacket
  225. metadata *Metadata
  226. }
  227. // Metadata returns destination metadata
  228. func (s *packetAdapter) Metadata() *Metadata {
  229. return s.metadata
  230. }
  231. func NewPacketAdapter(packet UDPPacket, metadata *Metadata) PacketAdapter {
  232. return &packetAdapter{
  233. packet,
  234. metadata,
  235. }
  236. }
  237. type WriteBack interface {
  238. WriteBack(b []byte, addr net.Addr) (n int, err error)
  239. }
  240. type WriteBackProxy interface {
  241. WriteBack
  242. UpdateWriteBack(wb WriteBack)
  243. }
  244. type NatTable interface {
  245. Set(key string, e PacketConn, w WriteBackProxy)
  246. Get(key string) (PacketConn, WriteBackProxy)
  247. GetOrCreateLock(key string) (*sync.Cond, bool)
  248. Delete(key string)
  249. DeleteLock(key string)
  250. GetForLocalConn(lAddr, rAddr string) *net.UDPConn
  251. AddForLocalConn(lAddr, rAddr string, conn *net.UDPConn) bool
  252. RangeForLocalConn(lAddr string, f func(key string, value *net.UDPConn) bool)
  253. GetOrCreateLockForLocalConn(lAddr string, key string) (*sync.Cond, bool)
  254. DeleteForLocalConn(lAddr, key string)
  255. DeleteLockForLocalConn(lAddr, key string)
  256. }