github.com/metacubex/mihomo@v1.18.5/listener/inbound/tun.go (about)

     1  package inbound
     2  
     3  import (
     4  	"errors"
     5  	"strings"
     6  
     7  	C "github.com/metacubex/mihomo/constant"
     8  	LC "github.com/metacubex/mihomo/listener/config"
     9  	"github.com/metacubex/mihomo/listener/sing_tun"
    10  	"github.com/metacubex/mihomo/log"
    11  )
    12  
    13  type TunOption struct {
    14  	BaseOption
    15  	Device              string   `inbound:"device,omitempty"`
    16  	Stack               string   `inbound:"stack,omitempty"`
    17  	DNSHijack           []string `inbound:"dns-hijack,omitempty"`
    18  	AutoRoute           bool     `inbound:"auto-route,omitempty"`
    19  	AutoDetectInterface bool     `inbound:"auto-detect-interface,omitempty"`
    20  
    21  	MTU                      uint32   `inbound:"mtu,omitempty"`
    22  	GSO                      bool     `inbound:"gso,omitempty"`
    23  	GSOMaxSize               uint32   `inbound:"gso-max-size,omitempty"`
    24  	Inet4Address             []string `inbound:"inet4_address,omitempty"`
    25  	Inet6Address             []string `inbound:"inet6_address,omitempty"`
    26  	StrictRoute              bool     `inbound:"strict_route,omitempty"`
    27  	Inet4RouteAddress        []string `inbound:"inet4_route_address,omitempty"`
    28  	Inet6RouteAddress        []string `inbound:"inet6_route_address,omitempty"`
    29  	Inet4RouteExcludeAddress []string `inbound:"inet4_route_exclude_address,omitempty"`
    30  	Inet6RouteExcludeAddress []string `inbound:"inet6_route_exclude_address,omitempty"`
    31  	IncludeInterface         []string `inbound:"include-interface,omitempty"`
    32  	ExcludeInterface         []string `inbound:"exclude-interface" json:"exclude-interface,omitempty"`
    33  	IncludeUID               []uint32 `inbound:"include_uid,omitempty"`
    34  	IncludeUIDRange          []string `inbound:"include_uid_range,omitempty"`
    35  	ExcludeUID               []uint32 `inbound:"exclude_uid,omitempty"`
    36  	ExcludeUIDRange          []string `inbound:"exclude_uid_range,omitempty"`
    37  	IncludeAndroidUser       []int    `inbound:"include_android_user,omitempty"`
    38  	IncludePackage           []string `inbound:"include_package,omitempty"`
    39  	ExcludePackage           []string `inbound:"exclude_package,omitempty"`
    40  	EndpointIndependentNat   bool     `inbound:"endpoint_independent_nat,omitempty"`
    41  	UDPTimeout               int64    `inbound:"udp_timeout,omitempty"`
    42  	FileDescriptor           int      `inbound:"file-descriptor,omitempty"`
    43  	TableIndex               int      `inbound:"table-index,omitempty"`
    44  }
    45  
    46  func (o TunOption) Equal(config C.InboundConfig) bool {
    47  	return optionToString(o) == optionToString(config)
    48  }
    49  
    50  type Tun struct {
    51  	*Base
    52  	config *TunOption
    53  	l      *sing_tun.Listener
    54  	tun    LC.Tun
    55  }
    56  
    57  func NewTun(options *TunOption) (*Tun, error) {
    58  	base, err := NewBase(&options.BaseOption)
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  	stack, exist := C.StackTypeMapping[strings.ToLower(options.Stack)]
    63  	if !exist {
    64  		return nil, errors.New("invalid tun stack")
    65  	}
    66  	inet4Address, err := LC.StringSliceToNetipPrefixSlice(options.Inet4Address)
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  	inet6Address, err := LC.StringSliceToNetipPrefixSlice(options.Inet6Address)
    71  	if err != nil {
    72  		return nil, err
    73  	}
    74  	inet4RouteAddress, err := LC.StringSliceToNetipPrefixSlice(options.Inet4RouteAddress)
    75  	if err != nil {
    76  		return nil, err
    77  	}
    78  	inet6RouteAddress, err := LC.StringSliceToNetipPrefixSlice(options.Inet6RouteAddress)
    79  	if err != nil {
    80  		return nil, err
    81  	}
    82  	inet4RouteExcludeAddress, err := LC.StringSliceToNetipPrefixSlice(options.Inet4RouteExcludeAddress)
    83  	if err != nil {
    84  		return nil, err
    85  	}
    86  	inet6RouteExcludeAddress, err := LC.StringSliceToNetipPrefixSlice(options.Inet6RouteExcludeAddress)
    87  	if err != nil {
    88  		return nil, err
    89  	}
    90  	return &Tun{
    91  		Base:   base,
    92  		config: options,
    93  		tun: LC.Tun{
    94  			Enable:                   true,
    95  			Device:                   options.Device,
    96  			Stack:                    stack,
    97  			DNSHijack:                options.DNSHijack,
    98  			AutoRoute:                options.AutoRoute,
    99  			AutoDetectInterface:      options.AutoDetectInterface,
   100  			MTU:                      options.MTU,
   101  			GSO:                      options.GSO,
   102  			GSOMaxSize:               options.GSOMaxSize,
   103  			Inet4Address:             inet4Address,
   104  			Inet6Address:             inet6Address,
   105  			StrictRoute:              options.StrictRoute,
   106  			Inet4RouteAddress:        inet4RouteAddress,
   107  			Inet6RouteAddress:        inet6RouteAddress,
   108  			Inet4RouteExcludeAddress: inet4RouteExcludeAddress,
   109  			Inet6RouteExcludeAddress: inet6RouteExcludeAddress,
   110  			IncludeInterface:         options.IncludeInterface,
   111  			ExcludeInterface:         options.ExcludeInterface,
   112  			IncludeUID:               options.IncludeUID,
   113  			IncludeUIDRange:          options.IncludeUIDRange,
   114  			ExcludeUID:               options.ExcludeUID,
   115  			ExcludeUIDRange:          options.ExcludeUIDRange,
   116  			IncludeAndroidUser:       options.IncludeAndroidUser,
   117  			IncludePackage:           options.IncludePackage,
   118  			ExcludePackage:           options.ExcludePackage,
   119  			EndpointIndependentNat:   options.EndpointIndependentNat,
   120  			UDPTimeout:               options.UDPTimeout,
   121  			FileDescriptor:           options.FileDescriptor,
   122  			TableIndex:               options.TableIndex,
   123  		},
   124  	}, nil
   125  }
   126  
   127  // Config implements constant.InboundListener
   128  func (t *Tun) Config() C.InboundConfig {
   129  	return t.config
   130  }
   131  
   132  // Address implements constant.InboundListener
   133  func (t *Tun) Address() string {
   134  	return t.l.Address()
   135  }
   136  
   137  // Listen implements constant.InboundListener
   138  func (t *Tun) Listen(tunnel C.Tunnel) error {
   139  	var err error
   140  	t.l, err = sing_tun.New(t.tun, tunnel, t.Additions()...)
   141  	if err != nil {
   142  		return err
   143  	}
   144  	log.Infoln("Tun[%s] proxy listening at: %s", t.Name(), t.Address())
   145  	return nil
   146  }
   147  
   148  // Close implements constant.InboundListener
   149  func (t *Tun) Close() error {
   150  	return t.l.Close()
   151  }
   152  
   153  var _ C.InboundListener = (*Tun)(nil)