github.com/Asutorufa/yuhaiin@v0.3.6-0.20240502055049-7984da7023a0/pkg/net/proxy/tun/tun.go (about)

     1  package tun
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"net/netip"
     7  
     8  	"github.com/Asutorufa/yuhaiin/pkg/net/netapi"
     9  	"github.com/Asutorufa/yuhaiin/pkg/net/netlink"
    10  	tun "github.com/Asutorufa/yuhaiin/pkg/net/proxy/tun/gvisor"
    11  	"github.com/Asutorufa/yuhaiin/pkg/net/proxy/tun/tun2socket"
    12  	"github.com/Asutorufa/yuhaiin/pkg/protos/config/listener"
    13  )
    14  
    15  func init() {
    16  	listener.RegisterProtocol(NewTun)
    17  }
    18  
    19  func NewTun(o *listener.Inbound_Tun) func(netapi.Listener) (s netapi.Accepter, err error) {
    20  	return func(l netapi.Listener) (s netapi.Accepter, err error) {
    21  		v4address, v4err := toPrefix(o.Tun.Portal)
    22  		v6address, v6err := toPrefix(o.Tun.PortalV6)
    23  		if v4err != nil && v6err != nil {
    24  			return nil, errors.Join(v4err, v6err)
    25  		}
    26  
    27  		sc, err := netlink.ParseTunScheme(o.Tun.Name)
    28  		if err != nil {
    29  			return nil, err
    30  		}
    31  
    32  		opt := &tun.Opt{
    33  			Inbound_Tun: o,
    34  			Options: &netlink.Options{
    35  				Interface: sc,
    36  				MTU:       int(o.Tun.Mtu),
    37  				Routes:    toRoutes(o.Tun.Route),
    38  			},
    39  		}
    40  
    41  		if v4address.IsValid() {
    42  			opt.Inet4Address = []netip.Prefix{v4address}
    43  		}
    44  
    45  		if v6address.IsValid() {
    46  			opt.Inet6Address = []netip.Prefix{v6address}
    47  		}
    48  
    49  		if o.Tun.Driver == listener.Tun_system_gvisor {
    50  			return tun2socket.New(opt)
    51  		} else {
    52  			return tun.New(opt)
    53  		}
    54  	}
    55  }
    56  
    57  func toRoutes(r *listener.Route) []netip.Prefix {
    58  	if r == nil {
    59  		return nil
    60  	}
    61  
    62  	var x []netip.Prefix
    63  	for _, v := range r.Routes {
    64  		prefix, err := toPrefix(v)
    65  		if err == nil {
    66  			x = append(x, prefix)
    67  		}
    68  	}
    69  
    70  	return x
    71  }
    72  
    73  func toPrefix(str string) (netip.Prefix, error) {
    74  	prefix, err := netip.ParsePrefix(str)
    75  	if err == nil {
    76  		return prefix, nil
    77  	}
    78  
    79  	address, er := netip.ParseAddr(str)
    80  	if er == nil {
    81  		return netip.PrefixFrom(address, address.BitLen()), nil
    82  	}
    83  
    84  	return netip.Prefix{}, fmt.Errorf("invalid IP address: %w", err)
    85  }