github.com/sagernet/sing-box@v1.9.0-rc.20/experimental/libbox/tun.go (about)

     1  package libbox
     2  
     3  import (
     4  	"net"
     5  	"net/netip"
     6  
     7  	"github.com/sagernet/sing-box/option"
     8  	"github.com/sagernet/sing-tun"
     9  	"github.com/sagernet/sing/common"
    10  	E "github.com/sagernet/sing/common/exceptions"
    11  )
    12  
    13  type TunOptions interface {
    14  	GetInet4Address() RoutePrefixIterator
    15  	GetInet6Address() RoutePrefixIterator
    16  	GetDNSServerAddress() (string, error)
    17  	GetMTU() int32
    18  	GetAutoRoute() bool
    19  	GetStrictRoute() bool
    20  	GetInet4RouteAddress() RoutePrefixIterator
    21  	GetInet6RouteAddress() RoutePrefixIterator
    22  	GetInet4RouteExcludeAddress() RoutePrefixIterator
    23  	GetInet6RouteExcludeAddress() RoutePrefixIterator
    24  	GetInet4RouteRange() RoutePrefixIterator
    25  	GetInet6RouteRange() RoutePrefixIterator
    26  	GetIncludePackage() StringIterator
    27  	GetExcludePackage() StringIterator
    28  	IsHTTPProxyEnabled() bool
    29  	GetHTTPProxyServer() string
    30  	GetHTTPProxyServerPort() int32
    31  	GetHTTPProxyBypassDomain() StringIterator
    32  	GetHTTPProxyMatchDomain() StringIterator
    33  }
    34  
    35  type RoutePrefix struct {
    36  	address netip.Addr
    37  	prefix  int
    38  }
    39  
    40  func (p *RoutePrefix) Address() string {
    41  	return p.address.String()
    42  }
    43  
    44  func (p *RoutePrefix) Prefix() int32 {
    45  	return int32(p.prefix)
    46  }
    47  
    48  func (p *RoutePrefix) Mask() string {
    49  	var bits int
    50  	if p.address.Is6() {
    51  		bits = 128
    52  	} else {
    53  		bits = 32
    54  	}
    55  	return net.IP(net.CIDRMask(p.prefix, bits)).String()
    56  }
    57  
    58  func (p *RoutePrefix) String() string {
    59  	return netip.PrefixFrom(p.address, p.prefix).String()
    60  }
    61  
    62  type RoutePrefixIterator interface {
    63  	Next() *RoutePrefix
    64  	HasNext() bool
    65  }
    66  
    67  func mapRoutePrefix(prefixes []netip.Prefix) RoutePrefixIterator {
    68  	return newIterator(common.Map(prefixes, func(prefix netip.Prefix) *RoutePrefix {
    69  		return &RoutePrefix{
    70  			address: prefix.Addr(),
    71  			prefix:  prefix.Bits(),
    72  		}
    73  	}))
    74  }
    75  
    76  var _ TunOptions = (*tunOptions)(nil)
    77  
    78  type tunOptions struct {
    79  	*tun.Options
    80  	routeRanges []netip.Prefix
    81  	option.TunPlatformOptions
    82  }
    83  
    84  func (o *tunOptions) GetInet4Address() RoutePrefixIterator {
    85  	return mapRoutePrefix(o.Inet4Address)
    86  }
    87  
    88  func (o *tunOptions) GetInet6Address() RoutePrefixIterator {
    89  	return mapRoutePrefix(o.Inet6Address)
    90  }
    91  
    92  func (o *tunOptions) GetDNSServerAddress() (string, error) {
    93  	if len(o.Inet4Address) == 0 || o.Inet4Address[0].Bits() == 32 {
    94  		return "", E.New("need one more IPv4 address for DNS hijacking")
    95  	}
    96  	return o.Inet4Address[0].Addr().Next().String(), nil
    97  }
    98  
    99  func (o *tunOptions) GetMTU() int32 {
   100  	return int32(o.MTU)
   101  }
   102  
   103  func (o *tunOptions) GetAutoRoute() bool {
   104  	return o.AutoRoute
   105  }
   106  
   107  func (o *tunOptions) GetStrictRoute() bool {
   108  	return o.StrictRoute
   109  }
   110  
   111  func (o *tunOptions) GetInet4RouteAddress() RoutePrefixIterator {
   112  	return mapRoutePrefix(o.Inet4RouteAddress)
   113  }
   114  
   115  func (o *tunOptions) GetInet6RouteAddress() RoutePrefixIterator {
   116  	return mapRoutePrefix(o.Inet6RouteAddress)
   117  }
   118  
   119  func (o *tunOptions) GetInet4RouteExcludeAddress() RoutePrefixIterator {
   120  	return mapRoutePrefix(o.Inet4RouteExcludeAddress)
   121  }
   122  
   123  func (o *tunOptions) GetInet6RouteExcludeAddress() RoutePrefixIterator {
   124  	return mapRoutePrefix(o.Inet6RouteExcludeAddress)
   125  }
   126  
   127  func (o *tunOptions) GetInet4RouteRange() RoutePrefixIterator {
   128  	return mapRoutePrefix(common.Filter(o.routeRanges, func(it netip.Prefix) bool {
   129  		return it.Addr().Is4()
   130  	}))
   131  }
   132  
   133  func (o *tunOptions) GetInet6RouteRange() RoutePrefixIterator {
   134  	return mapRoutePrefix(common.Filter(o.routeRanges, func(it netip.Prefix) bool {
   135  		return it.Addr().Is6()
   136  	}))
   137  }
   138  
   139  func (o *tunOptions) GetIncludePackage() StringIterator {
   140  	return newIterator(o.IncludePackage)
   141  }
   142  
   143  func (o *tunOptions) GetExcludePackage() StringIterator {
   144  	return newIterator(o.ExcludePackage)
   145  }
   146  
   147  func (o *tunOptions) IsHTTPProxyEnabled() bool {
   148  	if o.TunPlatformOptions.HTTPProxy == nil {
   149  		return false
   150  	}
   151  	return o.TunPlatformOptions.HTTPProxy.Enabled
   152  }
   153  
   154  func (o *tunOptions) GetHTTPProxyServer() string {
   155  	return o.TunPlatformOptions.HTTPProxy.Server
   156  }
   157  
   158  func (o *tunOptions) GetHTTPProxyServerPort() int32 {
   159  	return int32(o.TunPlatformOptions.HTTPProxy.ServerPort)
   160  }
   161  
   162  func (o *tunOptions) GetHTTPProxyBypassDomain() StringIterator {
   163  	return newIterator(o.TunPlatformOptions.HTTPProxy.BypassDomain)
   164  }
   165  
   166  func (o *tunOptions) GetHTTPProxyMatchDomain() StringIterator {
   167  	return newIterator(o.TunPlatformOptions.HTTPProxy.MatchDomain)
   168  }