github.com/kelleygo/clashcore@v1.0.2/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/kelleygo/clashcore/common/net"
    13  	"github.com/kelleygo/clashcore/common/utils"
    14  	"github.com/kelleygo/clashcore/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  }