From 35bf309fbd2d11f7d525ea71f8588df0776626b0 Mon Sep 17 00:00:00 2001 From: wencaiwulue <895703375@qq.com> Date: Fri, 17 Feb 2023 21:36:39 +0800 Subject: [PATCH] feat: add route dynamic --- go.mod | 4 +++- go.sum | 4 ++++ pkg/handler/connect.go | 38 ++++++++++++++++++++++---------------- pkg/tun/tun.go | 4 ++++ pkg/tun/tun_darwin.go | 4 ++++ pkg/tun/tun_linux.go | 4 ++++ pkg/tun/tun_other.go | 4 ++++ pkg/tun/tun_windows.go | 19 ++++++++++++++++++- 8 files changed, 63 insertions(+), 18 deletions(-) diff --git a/go.mod b/go.mod index 7dc19418..63644572 100644 --- a/go.mod +++ b/go.mod @@ -37,7 +37,9 @@ require ( require ( github.com/containernetworking/cni v1.1.2 + github.com/google/uuid v1.3.0 github.com/hashicorp/go-version v1.6.0 + github.com/libp2p/go-netroute v0.2.1 github.com/mattbaird/jsonpatch v0.0.0-20200820163806-098863c1fc24 github.com/prometheus-community/pro-bing v0.1.0 github.com/schollz/progressbar/v3 v3.13.0 @@ -82,8 +84,8 @@ require ( github.com/google/gnostic v0.6.9 // indirect github.com/google/go-cmp v0.5.9 // indirect github.com/google/gofuzz v1.2.0 // indirect + github.com/google/gopacket v1.1.19 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect - github.com/google/uuid v1.3.0 // indirect github.com/gorilla/mux v1.8.0 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect github.com/imdario/mergo v0.3.13 // indirect diff --git a/go.sum b/go.sum index 88fb689f..80d0e608 100644 --- a/go.sum +++ b/go.sum @@ -264,6 +264,8 @@ github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= +github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= @@ -352,6 +354,8 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lib/pq v0.0.0-20150723085316-0dad96c0b94f/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= +github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= diff --git a/pkg/handler/connect.go b/pkg/handler/connect.go index c2b6ece9..12ce6df6 100644 --- a/pkg/handler/connect.go +++ b/pkg/handler/connect.go @@ -9,6 +9,7 @@ import ( "time" "github.com/containernetworking/cni/pkg/types" + netroute "github.com/libp2p/go-netroute" "github.com/pkg/errors" log "github.com/sirupsen/logrus" v1 "k8s.io/api/core/v1" @@ -127,7 +128,7 @@ func (c *ConnectOptions) DoConnect() (err error) { if err != nil { return err } - //go c.addRouteDynamic(ctx) + go c.addRouteDynamic(ctx) c.deleteFirewallRule(ctx) c.setupDNS() log.Info("dns service ok") @@ -258,6 +259,16 @@ func (c *ConnectOptions) startLocalTunServe(ctx context.Context, forwardAddress // Listen all pod, add route if needed func (c *ConnectOptions) addRouteDynamic(ctx context.Context) { + r, err := netroute.New() + if err != nil { + return + } + + tunIface, err := tun.GetInterface() + if err != nil { + return + } + for { select { case <-ctx.Done(): @@ -290,26 +301,21 @@ func (c *ConnectOptions) addRouteDynamic(ctx context.Context) { continue } ip := pod.Status.PodIP - if ip == "" { + if ip == "" || net.ParseIP(ip) == nil { continue } if pod.Status.Phase == v1.PodSucceeded || pod.Status.Phase == v1.PodFailed { continue } - go func(phase v1.PodPhase, name, ip string) { - // if pod is running and ping is ok, not need add route - if phase == v1.PodRunning { - if ok, _ := util.Ping(ip); ok { - return - } - } - err := tun.AddRoutes(types.Route{Dst: net.IPNet{IP: net.ParseIP(ip), Mask: net.CIDRMask(32, 32)}}) - if err != nil { - log.Debugf("[route] add route failed, pod: %s, ip: %s,err: %v", name, ip, err) - } else { - log.Debugf("[route] add route ok, pod: %s, ip: %s", name, ip) - } - }(pod.Status.Phase, pod.Name, ip) + // if route is right, not need add route + iface, _, _, err := r.Route(net.ParseIP(ip)) + if err == nil && tunIface.Name == iface.Name { + continue + } + err = tun.AddRoutes(types.Route{Dst: net.IPNet{IP: net.ParseIP(ip), Mask: net.CIDRMask(32, 32)}}) + if err != nil { + log.Debugf("[route] add route failed, pod: %s, ip: %s,err: %v", pod.Name, ip, err) + } } } }() diff --git a/pkg/tun/tun.go b/pkg/tun/tun.go index 978eeed7..bcf69cb1 100644 --- a/pkg/tun/tun.go +++ b/pkg/tun/tun.go @@ -115,3 +115,7 @@ func AddRoutes(routes ...types.Route) error { env := os.Getenv(config.EnvTunNameOrLUID) return addTunRoutes(env, routes...) } + +func GetInterface() (*net.Interface, error) { + return getInterface() +} diff --git a/pkg/tun/tun_darwin.go b/pkg/tun/tun_darwin.go index c6d78f13..e46f7fc2 100644 --- a/pkg/tun/tun_darwin.go +++ b/pkg/tun/tun_darwin.go @@ -77,3 +77,7 @@ func addTunRoutes(ifName string, routes ...types.Route) error { } return nil } + +func getInterface() (*net.Interface, error) { + return net.InterfaceByName(os.Getenv(config.EnvTunNameOrLUID)) +} diff --git a/pkg/tun/tun_linux.go b/pkg/tun/tun_linux.go index a7892431..2d498914 100644 --- a/pkg/tun/tun_linux.go +++ b/pkg/tun/tun_linux.go @@ -99,3 +99,7 @@ func addTunRoutes(ifName string, routes ...types.Route) error { } return nil } + +func getInterface() (*net.Interface, error) { + return net.InterfaceByName(os.Getenv(config.EnvTunNameOrLUID)) +} diff --git a/pkg/tun/tun_other.go b/pkg/tun/tun_other.go index e945c953..ab432e15 100644 --- a/pkg/tun/tun_other.go +++ b/pkg/tun/tun_other.go @@ -76,3 +76,7 @@ func addTunRoutes(ifName string, routes ...types.Route) error { } return nil } + +func getInterface() (*net.Interface, error) { + return net.InterfaceByName(os.Getenv(config.EnvTunNameOrLUID)) +} diff --git a/pkg/tun/tun_windows.go b/pkg/tun/tun_windows.go index 9be6076c..5b030bb4 100644 --- a/pkg/tun/tun_windows.go +++ b/pkg/tun/tun_windows.go @@ -50,6 +50,7 @@ func createTun(cfg Config) (net.Conn, *net.Interface, error) { if err = os.Setenv(config.EnvTunNameOrLUID, luid); err != nil { return nil, nil, err } + _ = ifName.FlushRoutes(windows.AF_INET) if err = addTunRoutes(luid /*cfg.Gateway,*/, cfg.Routes...); err != nil { return nil, nil, err } @@ -65,7 +66,6 @@ func addTunRoutes(luid string, routes ...types.Route) error { return err } ifName := winipcfg.LUID(parseUint) - _ = ifName.FlushRoutes(windows.AF_INET) for _, route := range routes { if route.Dst.String() == "" { continue @@ -134,3 +134,20 @@ func (c *winTunConn) SetReadDeadline(time.Time) error { func (c *winTunConn) SetWriteDeadline(time.Time) error { return &net.OpError{Op: "set", Net: "tun", Source: nil, Addr: nil, Err: errors.New("deadline not supported")} } + +func getInterface() (*net.Interface, error) { + env := os.Getenv(config.EnvTunNameOrLUID) + parseUint, err := strconv.ParseUint(env, 10, 64) + if err != nil { + return nil, err + } + ifRow, err := winipcfg.LUID(parseUint).Interface() + if err != nil { + return nil, err + } + iface, err := net.InterfaceByIndex(int(ifRow.InterfaceIndex)) + if err != nil { + return nil, err + } + return iface, nil +}