feat(tun): export sing-tun auto route config

This commit is contained in:
Haruue 2024-03-20 13:45:12 +08:00
parent 91406ab0f9
commit 2e93c12cdc
No known key found for this signature in database
GPG key ID: F6083B28CBCBC148
4 changed files with 75 additions and 16 deletions

View file

@ -5,6 +5,7 @@ import (
"crypto/x509"
"encoding/hex"
"errors"
"fmt"
"net"
"net/netip"
"os"
@ -153,8 +154,17 @@ type tunConfig struct {
Name string `mapstructure:"name"`
MTU uint32 `mapstructure:"mtu"`
Timeout time.Duration `mapstructure:"timeout"`
Prefix4 string `mapstructure:"prefix4"`
Prefix6 string `mapstructure:"prefix6"`
Address struct {
IPv4 string `mapstructure:"ipv4"`
IPv6 string `mapstructure:"ipv6"`
} `mapstructure:"address"`
Route *struct {
Strict bool `mapstructure:"strict"`
IPv4 []string `mapstructure:"ipv4"`
IPv6 []string `mapstructure:"ipv6"`
IPv4Exclude []string `mapstructure:"ipv4Exclude"`
IPv6Exclude []string `mapstructure:"ipv6Exclude"`
} `mapstructure:"route"`
}
func (c *clientConfig) fillServerAddr(hyConfig *client.Config) error {
@ -684,19 +694,19 @@ func clientTUN(config tunConfig, c client.Client) error {
if timeout == 0 {
timeout = 300
}
if config.Prefix4 == "" {
config.Prefix4 = "100.100.100.101/30"
if config.Address.IPv4 == "" {
config.Address.IPv4 = "100.100.100.101/30"
}
prefix4, err := netip.ParsePrefix(config.Prefix4)
prefix4, err := netip.ParsePrefix(config.Address.IPv4)
if err != nil {
return configError{Field: "prefix4", Err: err}
return configError{Field: "address.ipv4", Err: err}
}
if config.Prefix6 == "" {
config.Prefix6 = "2001::ffff:ffff:ffff:fff1/126"
if config.Address.IPv6 == "" {
config.Address.IPv6 = "2001::ffff:ffff:ffff:fff1/126"
}
prefix6, err := netip.ParsePrefix(config.Prefix6)
prefix6, err := netip.ParsePrefix(config.Address.IPv6)
if err != nil {
return configError{Field: "prefix6", Err: err}
return configError{Field: "address.ipv6", Err: err}
}
server := &tun.Server{
HyClient: c,
@ -708,6 +718,39 @@ func clientTUN(config tunConfig, c client.Client) error {
Inet4Address: []netip.Prefix{prefix4},
Inet6Address: []netip.Prefix{prefix6},
}
if config.Route != nil {
server.AutoRoute = true
server.StructRoute = config.Route.Strict
parsePrefixes := func(field string, s []string) ([]netip.Prefix, error) {
var prefixes []netip.Prefix
for i, s := range s {
p, err := netip.ParsePrefix(s)
if err != nil {
return nil, configError{Field: fmt.Sprintf("%s[%d]", field, i), Err: err}
}
prefixes = append(prefixes, p)
}
return prefixes, nil
}
server.Inet4RouteAddress, err = parsePrefixes("route.ipv4", config.Route.IPv4)
if err != nil {
return err
}
server.Inet6RouteAddress, err = parsePrefixes("route.ipv6", config.Route.IPv6)
if err != nil {
return err
}
server.Inet4RouteExcludeAddress, err = parsePrefixes("route.ipv4Exclude", config.Route.IPv4Exclude)
if err != nil {
return err
}
server.Inet6RouteExcludeAddress, err = parsePrefixes("route.ipv6Exclude", config.Route.IPv6Exclude)
if err != nil {
return err
}
}
logger.Info("TUN listening", zap.String("interface", config.Name))
return server.Serve()
}

View file

@ -6,7 +6,7 @@ require (
github.com/apernet/go-tproxy v0.0.0-20230809025308-8f4723fd742f
github.com/apernet/hysteria/core v0.0.0-00010101000000-000000000000
github.com/apernet/hysteria/extras v0.0.0-00010101000000-000000000000
github.com/apernet/sing-tun v0.2.5-0.20240319071017-94362fc6c4cd
github.com/apernet/sing-tun v0.2.5-0.20240320024814-b1e6f9d4930f
github.com/caddyserver/certmagic v0.17.2
github.com/mdp/qrterminal/v3 v3.1.1
github.com/mholt/acmez v1.0.4

View file

@ -46,6 +46,8 @@ github.com/apernet/sing-tun v0.2.5-0.20240319051541-59e6f4bd5d1e h1:yFDb2wKpWQmz
github.com/apernet/sing-tun v0.2.5-0.20240319051541-59e6f4bd5d1e/go.mod h1:S5IydyLSN/QAfvY+r2GoomPJ6hidtXWm/Ad18sJVssk=
github.com/apernet/sing-tun v0.2.5-0.20240319071017-94362fc6c4cd h1:2EOhAnrNARO2xt7doxlV8+6c6W0hi48hFHiqhlYqtDM=
github.com/apernet/sing-tun v0.2.5-0.20240319071017-94362fc6c4cd/go.mod h1:S5IydyLSN/QAfvY+r2GoomPJ6hidtXWm/Ad18sJVssk=
github.com/apernet/sing-tun v0.2.5-0.20240320024814-b1e6f9d4930f h1:IK/7rFSnRRLXCjcuWreyPzfPEfZd2Xz9v2+RsFoodbs=
github.com/apernet/sing-tun v0.2.5-0.20240320024814-b1e6f9d4930f/go.mod h1:S5IydyLSN/QAfvY+r2GoomPJ6hidtXWm/Ad18sJVssk=
github.com/babolivier/go-doh-client v0.0.0-20201028162107-a76cff4cb8b6 h1:4NNbNM2Iq/k57qEu7WfL67UrbPq1uFWxW4qODCohi+0=
github.com/babolivier/go-doh-client v0.0.0-20201028162107-a76cff4cb8b6/go.mod h1:J29hk+f9lJrblVIfiJOtTFk+OblBawmib4uz/VdKzlg=
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=

View file

@ -31,6 +31,14 @@ type Server struct {
// required by system stack
Inet4Address []netip.Prefix
Inet6Address []netip.Prefix
// auto route
AutoRoute bool
StructRoute bool
Inet4RouteAddress []netip.Prefix
Inet6RouteAddress []netip.Prefix
Inet4RouteExcludeAddress []netip.Prefix
Inet6RouteExcludeAddress []netip.Prefix
}
type EventLogger interface {
@ -42,11 +50,17 @@ type EventLogger interface {
func (s *Server) Serve() error {
tunOpts := tun.Options{
Name: s.IfName,
Inet4Address: s.Inet4Address,
Inet6Address: s.Inet6Address,
MTU: s.MTU,
GSO: true,
Name: s.IfName,
Inet4Address: s.Inet4Address,
Inet6Address: s.Inet6Address,
MTU: s.MTU,
GSO: true,
AutoRoute: s.AutoRoute,
StrictRoute: s.StructRoute,
Inet4RouteAddress: s.Inet4RouteAddress,
Inet6RouteAddress: s.Inet6RouteAddress,
Inet4RouteExcludeAddress: s.Inet4RouteExcludeAddress,
Inet6RouteExcludeAddress: s.Inet6RouteExcludeAddress,
Logger: &singLogger{
tag: "tun",
zapLogger: s.Logger,