github.com/yaling888/clash@v1.53.0/adapter/outbound/base.go (about)

     1  package outbound
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"errors"
     7  	"io"
     8  	"net"
     9  
    10  	"github.com/yaling888/clash/component/dialer"
    11  	C "github.com/yaling888/clash/constant"
    12  )
    13  
    14  type Base struct {
    15  	name  string
    16  	addr  string
    17  	iface string
    18  	tp    C.AdapterType
    19  	udp   bool
    20  	dns   bool
    21  	rmark int
    22  }
    23  
    24  // Name implements C.ProxyAdapter
    25  func (b *Base) Name() string {
    26  	return b.name
    27  }
    28  
    29  // Type implements C.ProxyAdapter
    30  func (b *Base) Type() C.AdapterType {
    31  	return b.tp
    32  }
    33  
    34  // StreamConn implements C.ProxyAdapter
    35  func (b *Base) StreamConn(c net.Conn, _ *C.Metadata) (net.Conn, error) {
    36  	return c, errors.New("no support")
    37  }
    38  
    39  // StreamPacketConn implements C.ProxyAdapter
    40  func (b *Base) StreamPacketConn(c net.Conn, _ *C.Metadata) (net.Conn, error) {
    41  	return c, errors.New("no support")
    42  }
    43  
    44  // ListenPacketContext implements C.ProxyAdapter
    45  func (b *Base) ListenPacketContext(_ context.Context, _ *C.Metadata, _ ...dialer.Option) (C.PacketConn, error) {
    46  	return nil, errors.New("no support")
    47  }
    48  
    49  // SupportUDP implements C.ProxyAdapter
    50  func (b *Base) SupportUDP() bool {
    51  	return b.udp
    52  }
    53  
    54  // DisableDnsResolve implements C.DisableDnsResolve
    55  func (b *Base) DisableDnsResolve() bool {
    56  	return !b.dns
    57  }
    58  
    59  // MarshalJSON implements C.ProxyAdapter
    60  func (b *Base) MarshalJSON() ([]byte, error) {
    61  	return json.Marshal(map[string]string{
    62  		"type": b.Type().String(),
    63  	})
    64  }
    65  
    66  // Addr implements C.ProxyAdapter
    67  func (b *Base) Addr() string {
    68  	return b.addr
    69  }
    70  
    71  // Unwrap implements C.ProxyAdapter
    72  func (b *Base) Unwrap(_ *C.Metadata) C.Proxy {
    73  	return nil
    74  }
    75  
    76  // Cleanup implements C.ProxyAdapter
    77  func (b *Base) Cleanup() {}
    78  
    79  // DialOptions return []dialer.Option from struct
    80  func (b *Base) DialOptions(opts ...dialer.Option) []dialer.Option {
    81  	if b.iface != "" {
    82  		opts = append(opts, dialer.WithInterface(b.iface))
    83  	}
    84  
    85  	if b.rmark != 0 {
    86  		opts = append(opts, dialer.WithRoutingMark(b.rmark))
    87  	}
    88  
    89  	return opts
    90  }
    91  
    92  type BasicOption struct {
    93  	Interface   string `proxy:"interface-name,omitempty" group:"interface-name,omitempty"`
    94  	RoutingMark int    `proxy:"routing-mark,omitempty" group:"routing-mark,omitempty"`
    95  }
    96  
    97  type BaseOption struct {
    98  	Name        string
    99  	Addr        string
   100  	Type        C.AdapterType
   101  	UDP         bool
   102  	Interface   string
   103  	RoutingMark int
   104  }
   105  
   106  func NewBase(opt BaseOption) *Base {
   107  	return &Base{
   108  		name:  opt.Name,
   109  		addr:  opt.Addr,
   110  		tp:    opt.Type,
   111  		udp:   opt.UDP,
   112  		iface: opt.Interface,
   113  		rmark: opt.RoutingMark,
   114  	}
   115  }
   116  
   117  type conn struct {
   118  	net.Conn
   119  	chain C.Chain
   120  }
   121  
   122  // Chains implements C.Connection
   123  func (c *conn) Chains() C.Chain {
   124  	return c.chain
   125  }
   126  
   127  // AppendToChains implements C.Connection
   128  func (c *conn) AppendToChains(a C.ProxyAdapter) {
   129  	c.chain = append(c.chain, a.Name())
   130  }
   131  
   132  // SetChains implements C.Connection
   133  func (c *conn) SetChains(chains []string) {
   134  	c.chain = chains
   135  }
   136  
   137  func (c *conn) String() string {
   138  	return c.Chains().String()
   139  }
   140  
   141  func NewConn(c net.Conn, a C.ProxyAdapter) C.Conn {
   142  	return &conn{c, []string{a.Name()}}
   143  }
   144  
   145  type packetConn struct {
   146  	net.PacketConn
   147  	chain C.Chain
   148  }
   149  
   150  // Chains implements C.Connection
   151  func (c *packetConn) Chains() C.Chain {
   152  	return c.chain
   153  }
   154  
   155  // AppendToChains implements C.Connection
   156  func (c *packetConn) AppendToChains(a C.ProxyAdapter) {
   157  	c.chain = append(c.chain, a.Name())
   158  }
   159  
   160  // SetChains implements C.Connection
   161  func (c *packetConn) SetChains(chains []string) {
   162  	c.chain = chains
   163  }
   164  
   165  func (c *packetConn) String() string {
   166  	return c.Chains().String()
   167  }
   168  
   169  func NewPacketConn(pc net.PacketConn, a C.ProxyAdapter) C.PacketConn {
   170  	return &packetConn{pc, []string{a.Name()}}
   171  }
   172  
   173  type wrapConn struct {
   174  	net.PacketConn
   175  }
   176  
   177  func (*wrapConn) Read([]byte) (int, error) {
   178  	return 0, io.EOF
   179  }
   180  
   181  func (*wrapConn) Write([]byte) (int, error) {
   182  	return 0, io.EOF
   183  }
   184  
   185  func (*wrapConn) RemoteAddr() net.Addr {
   186  	return nil
   187  }
   188  
   189  func WrapConn(packetConn net.PacketConn) net.Conn {
   190  	return &wrapConn{
   191  		PacketConn: packetConn,
   192  	}
   193  }
   194  
   195  func IsPacketConn(c net.Conn) bool {
   196  	if _, ok := c.(net.PacketConn); !ok {
   197  		return false
   198  	}
   199  
   200  	if ua, ok := c.LocalAddr().(*net.UnixAddr); ok {
   201  		return ua.Net == "unixgram"
   202  	}
   203  
   204  	return true
   205  }