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

     1  package provider
     2  
     3  import (
     4  	"net"
     5  
     6  	"github.com/yaling888/clash/component/resolver"
     7  	"github.com/yaling888/clash/constant"
     8  )
     9  
    10  // Vehicle Type
    11  const (
    12  	File VehicleType = iota
    13  	HTTP
    14  	Compatible
    15  )
    16  
    17  // VehicleType defined
    18  type VehicleType int
    19  
    20  func (v VehicleType) String() string {
    21  	switch v {
    22  	case File:
    23  		return "File"
    24  	case HTTP:
    25  		return "HTTP"
    26  	case Compatible:
    27  		return "Compatible"
    28  	default:
    29  		return "Unknown"
    30  	}
    31  }
    32  
    33  type Vehicle interface {
    34  	Read() ([]byte, error)
    35  	Path() string
    36  	Proxy() bool
    37  	Type() VehicleType
    38  }
    39  
    40  // Provider Type
    41  const (
    42  	Proxy ProviderType = iota
    43  	Rule
    44  )
    45  
    46  // ProviderType defined
    47  type ProviderType int
    48  
    49  func (pt ProviderType) String() string {
    50  	switch pt {
    51  	case Proxy:
    52  		return "Proxy"
    53  	case Rule:
    54  		return "Rule"
    55  	default:
    56  		return "Unknown"
    57  	}
    58  }
    59  
    60  // Provider interface
    61  type Provider interface {
    62  	Name() string
    63  	VehicleType() VehicleType
    64  	Type() ProviderType
    65  	Initial() error
    66  	Update() error
    67  }
    68  
    69  // ProxyProvider interface
    70  type ProxyProvider interface {
    71  	Provider
    72  	Proxies() []constant.Proxy
    73  	// Touch is used to inform the provider that the proxy is actually being used while getting the list of proxies.
    74  	// Commonly used in DialContext and DialPacketConn
    75  	Touch()
    76  	HealthCheck()
    77  	Finalize()
    78  }
    79  
    80  // Rule Type
    81  const (
    82  	Domain RuleType = iota
    83  	IPCIDR
    84  	Classical
    85  )
    86  
    87  // RuleType defined
    88  type RuleType int
    89  
    90  func (rt RuleType) String() string {
    91  	switch rt {
    92  	case Domain:
    93  		return "Domain"
    94  	case IPCIDR:
    95  		return "IPCIDR"
    96  	case Classical:
    97  		return "Classical"
    98  	default:
    99  		return "Unknown"
   100  	}
   101  }
   102  
   103  // RuleProvider interface
   104  type RuleProvider interface {
   105  	Provider
   106  	Behavior() RuleType
   107  	Match(*constant.Metadata) bool
   108  	ShouldResolveIP() bool
   109  	AsRule(adaptor string) constant.Rule
   110  }
   111  
   112  func Cleanup(proxies map[string]constant.Proxy, providers map[string]ProxyProvider) {
   113  	for _, p := range proxies {
   114  		go func(m constant.ProxyAdapter) {
   115  			m.Cleanup()
   116  			if m.Addr() == "" {
   117  				return
   118  			}
   119  			host, _, _ := net.SplitHostPort(m.Addr())
   120  			if host == "" {
   121  				return
   122  			}
   123  			resolver.RemoveCache(host)
   124  		}(p)
   125  	}
   126  	for _, pd := range providers {
   127  		go func(pp ProxyProvider) {
   128  			if pp.VehicleType() != Compatible {
   129  				for _, p := range pp.Proxies() {
   130  					p.Cleanup()
   131  					if p.Addr() == "" {
   132  						continue
   133  					}
   134  					host, _, _ := net.SplitHostPort(p.Addr())
   135  					if host == "" {
   136  						continue
   137  					}
   138  					resolver.RemoveCache(host)
   139  				}
   140  			}
   141  			pp.Finalize()
   142  		}(pd)
   143  	}
   144  }