github.com/yaling888/clash@v1.53.0/constant/adapters.go (about)

     1  package constant
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net"
     7  	"time"
     8  
     9  	"github.com/yaling888/clash/component/dialer"
    10  )
    11  
    12  // Adapter Type
    13  const (
    14  	Direct AdapterType = iota
    15  	Reject
    16  	Mitm
    17  
    18  	Shadowsocks
    19  	ShadowsocksR
    20  	Snell
    21  	Socks5
    22  	Http
    23  	Vmess
    24  	Vless
    25  	Trojan
    26  	WireGuard
    27  
    28  	Relay
    29  	Selector
    30  	Fallback
    31  	URLTest
    32  	LoadBalance
    33  )
    34  
    35  const (
    36  	DefaultTCPTimeout = 8 * time.Second
    37  	DefaultUDPTimeout = DefaultTCPTimeout
    38  	DefaultTLSTimeout = DefaultTCPTimeout
    39  )
    40  
    41  type Connection interface {
    42  	Chains() Chain
    43  	AppendToChains(adapter ProxyAdapter)
    44  	SetChains(chains []string)
    45  	String() string
    46  }
    47  
    48  type Chain []string
    49  
    50  func (c Chain) String() string {
    51  	switch len(c) {
    52  	case 0:
    53  		return ""
    54  	case 1:
    55  		return c[0]
    56  	default:
    57  		return fmt.Sprintf("%s[%s]", c[len(c)-1], c[0])
    58  	}
    59  }
    60  
    61  func (c Chain) Last() string {
    62  	switch len(c) {
    63  	case 0:
    64  		return ""
    65  	default:
    66  		return c[0]
    67  	}
    68  }
    69  
    70  type Conn interface {
    71  	net.Conn
    72  	Connection
    73  }
    74  
    75  type PacketConn interface {
    76  	net.PacketConn
    77  	Connection
    78  }
    79  
    80  type ProxyAdapter interface {
    81  	Name() string
    82  	Type() AdapterType
    83  	Addr() string
    84  	SupportUDP() bool
    85  	DisableDnsResolve() bool
    86  	MarshalJSON() ([]byte, error)
    87  
    88  	// StreamConn wraps a protocol around net.Conn with Metadata.
    89  	//
    90  	// Examples:
    91  	//	conn, _ := net.DialContext(context.Background(), "tcp", "host:port")
    92  	//	conn, _ = adapter.StreamConn(conn, metadata)
    93  	//
    94  	// It returns a C.Conn with protocol which start with
    95  	// a new session (if any)
    96  	StreamConn(c net.Conn, metadata *Metadata) (net.Conn, error)
    97  
    98  	// StreamPacketConn wraps a UDP protocol around net.Conn with Metadata.
    99  	StreamPacketConn(c net.Conn, metadata *Metadata) (net.Conn, error)
   100  
   101  	// DialContext return a C.Conn with protocol which
   102  	// contains multiplexing-related reuse logic (if any)
   103  	DialContext(ctx context.Context, metadata *Metadata, opts ...dialer.Option) (Conn, error)
   104  
   105  	// ListenPacketContext listen for a PacketConn
   106  	ListenPacketContext(ctx context.Context, metadata *Metadata, opts ...dialer.Option) (PacketConn, error)
   107  
   108  	// Unwrap extracts the proxy from a proxy-group. It returns nil when nothing to extract.
   109  	Unwrap(metadata *Metadata) Proxy
   110  
   111  	// Cleanup released resources.
   112  	Cleanup()
   113  }
   114  
   115  type DelayHistory struct {
   116  	Time     time.Time `json:"time"`
   117  	Delay    uint16    `json:"delay"`
   118  	AvgDelay uint16    `json:"meanDelay"`
   119  }
   120  
   121  type Proxy interface {
   122  	ProxyAdapter
   123  	Alive() bool
   124  	HasV6() bool
   125  	DelayHistory() []DelayHistory
   126  	LastDelay() uint16
   127  	URLTest(ctx context.Context, url string) (uint16, uint16, error)
   128  }
   129  
   130  // AdapterType is enum of adapter type
   131  type AdapterType int
   132  
   133  func (at AdapterType) String() string {
   134  	switch at {
   135  	case Direct:
   136  		return "Direct"
   137  	case Reject:
   138  		return "Reject"
   139  	case Mitm:
   140  		return "Mitm"
   141  
   142  	case Shadowsocks:
   143  		return "Shadowsocks"
   144  	case ShadowsocksR:
   145  		return "ShadowsocksR"
   146  	case Snell:
   147  		return "Snell"
   148  	case Socks5:
   149  		return "Socks5"
   150  	case Http:
   151  		return "Http"
   152  	case Vmess:
   153  		return "Vmess"
   154  	case Vless:
   155  		return "Vless"
   156  	case Trojan:
   157  		return "Trojan"
   158  	case WireGuard:
   159  		return "WireGuard"
   160  
   161  	case Relay:
   162  		return "Relay"
   163  	case Selector:
   164  		return "Selector"
   165  	case Fallback:
   166  		return "Fallback"
   167  	case URLTest:
   168  		return "URLTest"
   169  	case LoadBalance:
   170  		return "LoadBalance"
   171  
   172  	default:
   173  		return "Unknown"
   174  	}
   175  }
   176  
   177  // UDPPacket contains the data of UDP packet, and offers control/info of UDP packet's source
   178  type UDPPacket interface {
   179  	// Data get the payload of UDP Packet
   180  	Data() *[]byte
   181  
   182  	// WriteBack writes the payload with source IP/Port equals addr
   183  	// - variable source IP/Port is important to STUN
   184  	// - if addr is not provided, WriteBack will write out UDP packet with SourceIP/Port equals to original Target,
   185  	//   this is important when using Fake-IP.
   186  	WriteBack(b []byte, addr net.Addr) (n int, err error)
   187  
   188  	// Drop call after packet is used, could recycle buffer in this function.
   189  	Drop()
   190  
   191  	// LocalAddr returns the source IP/Port of packet
   192  	LocalAddr() net.Addr
   193  }
   194  
   195  type RawProxy struct {
   196  	Name     string         `yaml:"name"`
   197  	Type     string         `yaml:"type"`
   198  	Server   string         `yaml:"server"`
   199  	UUID     string         `yaml:"uuid,omitempty"`
   200  	Password string         `yaml:"password,omitempty"`
   201  	M        map[string]any `yaml:",inline"`
   202  }
   203  
   204  func (m *RawProxy) Init() {
   205  	if m == nil {
   206  		return
   207  	}
   208  	if m.M == nil {
   209  		m.M = make(map[string]any)
   210  	}
   211  	if m.Name != "" {
   212  		m.M["name"] = m.Name
   213  	}
   214  	if m.Type != "" {
   215  		m.M["type"] = m.Type
   216  	}
   217  	if m.Server != "" {
   218  		m.M["server"] = m.Server
   219  	}
   220  	if m.UUID != "" {
   221  		m.M["uuid"] = m.UUID
   222  	}
   223  	if m.Password != "" {
   224  		m.M["password"] = m.Password
   225  	}
   226  }