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 }