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