github.com/chwjbn/xclash@v0.2.0/adapter/outbound/base.go (about)

     1  package outbound
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"errors"
     7  	"net"
     8  
     9  	"github.com/chwjbn/xclash/component/dialer"
    10  	C "github.com/chwjbn/xclash/constant"
    11  )
    12  
    13  type Base struct {
    14  	name  string
    15  	addr  string
    16  	iface string
    17  	tp    C.AdapterType
    18  	udp   bool
    19  	rmark int
    20  }
    21  
    22  // Name implements C.ProxyAdapter
    23  func (b *Base) Name() string {
    24  	return b.name
    25  }
    26  
    27  // Type implements C.ProxyAdapter
    28  func (b *Base) Type() C.AdapterType {
    29  	return b.tp
    30  }
    31  
    32  // StreamConn implements C.ProxyAdapter
    33  func (b *Base) StreamConn(c net.Conn, metadata *C.Metadata) (net.Conn, error) {
    34  	return c, errors.New("no support")
    35  }
    36  
    37  // ListenPacketContext implements C.ProxyAdapter
    38  func (b *Base) ListenPacketContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.PacketConn, error) {
    39  	return nil, errors.New("no support")
    40  }
    41  
    42  // SupportUDP implements C.ProxyAdapter
    43  func (b *Base) SupportUDP() bool {
    44  	return b.udp
    45  }
    46  
    47  // MarshalJSON implements C.ProxyAdapter
    48  func (b *Base) MarshalJSON() ([]byte, error) {
    49  	return json.Marshal(map[string]string{
    50  		"type": b.Type().String(),
    51  	})
    52  }
    53  
    54  // Addr implements C.ProxyAdapter
    55  func (b *Base) Addr() string {
    56  	return b.addr
    57  }
    58  
    59  // Unwrap implements C.ProxyAdapter
    60  func (b *Base) Unwrap(metadata *C.Metadata) C.Proxy {
    61  	return nil
    62  }
    63  
    64  // DialOptions return []dialer.Option from struct
    65  func (b *Base) DialOptions(opts ...dialer.Option) []dialer.Option {
    66  	if b.iface != "" {
    67  		opts = append(opts, dialer.WithInterface(b.iface))
    68  	}
    69  
    70  	if b.rmark != 0 {
    71  		opts = append(opts, dialer.WithRoutingMark(b.rmark))
    72  	}
    73  
    74  	return opts
    75  }
    76  
    77  type BasicOption struct {
    78  	Interface   string `proxy:"interface-name,omitempty" group:"interface-name,omitempty"`
    79  	RoutingMark int    `proxy:"routing-mark,omitempty" group:"routing-mark,omitempty"`
    80  }
    81  
    82  type BaseOption struct {
    83  	Name        string
    84  	Addr        string
    85  	Type        C.AdapterType
    86  	UDP         bool
    87  	Interface   string
    88  	RoutingMark int
    89  }
    90  
    91  func NewBase(opt BaseOption) *Base {
    92  	return &Base{
    93  		name:  opt.Name,
    94  		addr:  opt.Addr,
    95  		tp:    opt.Type,
    96  		udp:   opt.UDP,
    97  		iface: opt.Interface,
    98  		rmark: opt.RoutingMark,
    99  	}
   100  }
   101  
   102  type conn struct {
   103  	net.Conn
   104  	chain C.Chain
   105  }
   106  
   107  // Chains implements C.Connection
   108  func (c *conn) Chains() C.Chain {
   109  	return c.chain
   110  }
   111  
   112  // AppendToChains implements C.Connection
   113  func (c *conn) AppendToChains(a C.ProxyAdapter) {
   114  	c.chain = append(c.chain, a.Name())
   115  }
   116  
   117  func NewConn(c net.Conn, a C.ProxyAdapter) C.Conn {
   118  	return &conn{c, []string{a.Name()}}
   119  }
   120  
   121  type packetConn struct {
   122  	net.PacketConn
   123  	chain C.Chain
   124  }
   125  
   126  // Chains implements C.Connection
   127  func (c *packetConn) Chains() C.Chain {
   128  	return c.chain
   129  }
   130  
   131  // AppendToChains implements C.Connection
   132  func (c *packetConn) AppendToChains(a C.ProxyAdapter) {
   133  	c.chain = append(c.chain, a.Name())
   134  }
   135  
   136  func newPacketConn(pc net.PacketConn, a C.ProxyAdapter) C.PacketConn {
   137  	return &packetConn{pc, []string{a.Name()}}
   138  }