feat: feat: optimize code and remove detect conflict interface

This commit is contained in:
fengcaiwen
2023-02-08 16:25:01 +08:00
parent 2adfe3c525
commit db7286abec
19 changed files with 111 additions and 844 deletions

3
go.mod
View File

@@ -12,7 +12,6 @@ require (
github.com/milosgajdos/tenus v0.0.3
github.com/moby/term v0.0.0-20221205130635-1aeaba878587
github.com/pkg/errors v0.9.1
github.com/shadowsocks/go-shadowsocks2 v0.1.5
github.com/sirupsen/logrus v1.9.0
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8
github.com/spf13/cobra v1.6.1
@@ -88,13 +87,11 @@ require (
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
github.com/rivo/uniseg v0.4.3 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/xlab/treeprint v1.1.0 // indirect
go.starlark.net v0.0.0-20230112144946-fae38c8a6d89 // indirect
golang.org/x/crypto v0.5.0 // indirect
golang.org/x/mod v0.7.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/term v0.4.0 // indirect

9
go.sum
View File

@@ -281,8 +281,6 @@ github.com/prometheus-community/pro-bing v0.1.0 h1:zjzLGhfNPP0bP1OlzGB+SJcguOViw
github.com/prometheus-community/pro-bing v0.1.0/go.mod h1:BpWlHurD9flHtzq8wrh8QGWYz9ka9z9ZJAyOel8ej58=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw=
github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
@@ -293,8 +291,6 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
github.com/schollz/progressbar/v3 v3.13.0 h1:9TeeWRcjW2qd05I8Kf9knPkW4vLM/hYoa6z9ABvxje8=
github.com/schollz/progressbar/v3 v3.13.0/go.mod h1:ZBYnSuLAX2LU8P8UiKN/KgF2DY58AJC8yfVYLPC8Ly4=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/shadowsocks/go-shadowsocks2 v0.1.5 h1:PDSQv9y2S85Fl7VBeOMF9StzeXZyK1HakRm86CUbr28=
github.com/shadowsocks/go-shadowsocks2 v0.1.5/go.mod h1:AGGpIoek4HRno4xzyFiAtLHkOpcoznZEkAccaI/rplM=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 h1:TG/diQgUe0pntT/2D9tmUCz4VNwm9MfrtPr0SU2qSX8=
@@ -345,9 +341,6 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.5.0 h1:U/0M97KRkSFvyD/3FSmdP5W5swImpNgle/EHFhOsQPE=
golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -454,7 +447,6 @@ golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -486,7 +478,6 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg=

View File

@@ -3,10 +3,8 @@ package core
import (
"context"
"net"
"time"
log "github.com/sirupsen/logrus"
"k8s.io/client-go/util/retry"
)
type Server struct {
@@ -18,34 +16,22 @@ type Server struct {
func (s *Server) Serve(ctx context.Context) error {
l := s.Listener
defer l.Close()
var tempDelay time.Duration
go func() {
<-ctx.Done()
if err := retry.OnError(retry.DefaultBackoff, func(err error) bool { return err != nil }, l.Close); err != nil {
log.Warnf("error while close listener, err: %v", err)
}
}()
for ctx.Err() == nil {
conn, e := l.Accept()
if e != nil {
if ne, ok := e.(net.Error); ok && ne.Timeout() {
if tempDelay == 0 {
tempDelay = 5 * time.Millisecond
} else {
tempDelay *= 2
}
if max := 1 * time.Second; tempDelay > max {
tempDelay = max
}
log.Warnf("server: Accept error: %v; retrying in %v", e, tempDelay)
time.Sleep(tempDelay)
//go func() {
// <-ctx.Done()
// l.Close()
//}()
for {
select {
case <-ctx.Done():
return nil
default:
conn, err := l.Accept()
if err != nil {
log.Warnf("server: accept error: %v", err)
continue
}
return e
go s.Handler.Handle(ctx, conn)
}
tempDelay = 0
go s.Handler.Handle(ctx, conn)
}
return nil
}

View File

@@ -7,8 +7,6 @@ import (
"time"
log "github.com/sirupsen/logrus"
"github.com/wencaiwulue/kubevpn/pkg/config"
)
type fakeUDPTunnelConnector struct {
@@ -33,19 +31,14 @@ func TCPHandler() Handler {
func (h *fakeUdpHandler) Handle(ctx context.Context, tcpConn net.Conn) {
defer tcpConn.Close()
if config.Debug {
log.Debugf("[tcpserver] %s -> %s\n", tcpConn.RemoteAddr(), tcpConn.LocalAddr())
}
log.Debugf("[tcpserver] %s -> %s\n", tcpConn.RemoteAddr(), tcpConn.LocalAddr())
// serve tunnel udp, tunnel <-> remote, handle tunnel udp request
udpConn, err := net.DialUDP("udp", nil, Server8422)
if err != nil {
log.Debugf("[tcpserver] udp-tun %s -> %s : %s", tcpConn.RemoteAddr(), udpConn.LocalAddr(), err)
log.Errorf("[tcpserver] udp-tun %s -> %s : %s", tcpConn.RemoteAddr(), udpConn.LocalAddr(), err)
return
}
defer udpConn.Close()
if config.Debug {
log.Debugf("[tcpserver] udp-tun %s <- %s\n", tcpConn.RemoteAddr(), udpConn.LocalAddr())
}
log.Debugf("[tcpserver] udp-tun %s <-> %s", tcpConn.RemoteAddr(), udpConn.LocalAddr())
_ = h.tunnelServerUDP(tcpConn, udpConn)
log.Debugf("[tcpserver] udp-tun %s >-< %s", tcpConn.RemoteAddr(), udpConn.LocalAddr())
@@ -73,9 +66,7 @@ func (h *fakeUdpHandler) tunnelServerUDP(tcpConn net.Conn, udpConn *net.UDPConn)
errChan <- err
return
}
if config.Debug {
log.Debugf("[tcpserver] udp-tun %s >>> %s length: %d", tcpConn.RemoteAddr(), Server8422, len(dgram.Data))
}
log.Debugf("[tcpserver] udp-tun %s >>> %s length: %d", tcpConn.RemoteAddr(), Server8422, len(dgram.Data))
}
}()
@@ -98,9 +89,7 @@ func (h *fakeUdpHandler) tunnelServerUDP(tcpConn net.Conn, udpConn *net.UDPConn)
errChan <- err
return
}
if config.Debug {
log.Debugf("[tcpserver] udp-tun %s <<< %s length: %d", tcpConn.RemoteAddr(), dgram.Addr(), len(dgram.Data))
}
log.Debugf("[tcpserver] udp-tun %s <<< %s length: %d", tcpConn.RemoteAddr(), dgram.Addr(), len(dgram.Data))
}
}()
return <-errChan
@@ -141,17 +130,3 @@ func (c *fakeUDPTunnelConn) WriteTo(b []byte, _ net.Addr) (int, error) {
func (c *fakeUDPTunnelConn) Close() error {
return c.Conn.Close()
}
func (c *fakeUDPTunnelConn) CloseWrite() error {
if cc, ok := c.Conn.(interface{ CloseWrite() error }); ok {
return cc.CloseWrite()
}
return nil
}
func (c *fakeUDPTunnelConn) CloseRead() error {
if cc, ok := c.Conn.(interface{ CloseRead() error }); ok {
return cc.CloseRead()
}
return nil
}

View File

@@ -3,21 +3,17 @@ package core
import (
"context"
"errors"
"net"
"sync"
"time"
"github.com/shadowsocks/go-shadowsocks2/shadowaead"
log "github.com/sirupsen/logrus"
"github.com/songgao/water/waterutil"
"golang.org/x/net/ipv4"
"golang.org/x/net/ipv6"
"net"
"sync"
"github.com/wencaiwulue/kubevpn/pkg/config"
log "github.com/sirupsen/logrus"
"github.com/songgao/water/waterutil"
)
func ipToTunRouteKey(ip net.IP) string {
return ip.To16().String()
return ip.String()
}
type tunHandler struct {
@@ -37,71 +33,55 @@ func TunHandler(chain *Chain, node *Node) Handler {
}
}
func (h *tunHandler) Handle(ctx context.Context, conn net.Conn) {
defer conn.Close()
func (h *tunHandler) Handle(ctx context.Context, tun net.Conn) {
defer tun.Close()
var err error
var raddr net.Addr
var remoteAddr net.Addr
if addr := h.node.Remote; addr != "" {
raddr, err = net.ResolveUDPAddr("udp", addr)
remoteAddr, err = net.ResolveUDPAddr("udp", addr)
if err != nil {
log.Debugf("[tun] %s: remote addr: %v", conn.LocalAddr(), err)
log.Errorf("[tun] %s: remote addr: %v", tun.LocalAddr(), err)
return
}
}
var tempDelay time.Duration
for ctx.Err() == nil {
for {
err = func() error {
var err error
var pc net.PacketConn
if raddr != nil && !h.chain.IsEmpty() {
var packetConn net.PacketConn
if remoteAddr != nil && !h.chain.IsEmpty() {
cc, err := h.chain.DialContext(ctx)
if err != nil {
return err
}
var ok bool
pc, ok = cc.(net.PacketConn)
packetConn, ok = cc.(net.PacketConn)
if !ok {
err = errors.New("not a packet connection")
log.Debugf("[tun] %s - %s: %s", conn.LocalAddr(), raddr, err)
log.Errorf("[tun] %s - %s: %s", tun.LocalAddr(), remoteAddr, err)
return err
}
} else {
laddr, _ := net.ResolveUDPAddr("udp", h.node.Addr)
pc, err = net.ListenUDP("udp", laddr)
var lc net.ListenConfig
packetConn, err = lc.ListenPacket(ctx, "udp", h.node.Addr)
}
if err != nil {
return err
}
return h.transportTun(ctx, conn, pc, raddr)
return h.transportTun(ctx, tun, packetConn, remoteAddr)
}()
if err != nil {
log.Debugf("[tun] %s: %v", conn.LocalAddr(), err)
log.Debugf("[tun] %s: %v", tun.LocalAddr(), err)
}
select {
case <-h.chExit:
return
case <-ctx.Done():
h.chExit <- struct{}{}
return
default:
log.Debugf("next loop, err: %v", err)
}
if err != nil {
if tempDelay == 0 {
tempDelay = 1000 * time.Millisecond
} else {
tempDelay *= 2
}
if max := 6 * time.Second; tempDelay > max {
tempDelay = max
}
time.Sleep(tempDelay)
continue
}
tempDelay = 0
}
}
@@ -119,24 +99,17 @@ func (h *tunHandler) findRouteFor(dst net.IP) net.Addr {
return nil
}
func (h *tunHandler) transportTun(ctx context.Context, tun net.Conn, conn net.PacketConn, raddr net.Addr) error {
func (h *tunHandler) transportTun(ctx context.Context, tun net.Conn, conn net.PacketConn, remoteAddr net.Addr) error {
errChan := make(chan error, 2)
defer func() {
if c, ok := conn.(interface{ CloseRead() error }); ok {
_ = c.CloseRead()
}
if c, ok := conn.(interface{ CloseWrite() error }); ok {
_ = c.CloseWrite()
}
_ = conn.Close()
}()
defer conn.Close()
go func() {
b := SPool.Get().([]byte)
defer SPool.Put(b)
offset := 8
for ctx.Err() == nil {
for {
err := func() error {
n, err := tun.Read(b[:])
n, err := tun.Read(b[offset:])
if err != nil {
select {
case h.chExit <- struct{}{}:
@@ -146,8 +119,8 @@ func (h *tunHandler) transportTun(ctx context.Context, tun net.Conn, conn net.Pa
}
// client side, deliver packet directly.
if raddr != nil {
_, err = conn.WriteTo(b[:n], raddr)
if remoteAddr != nil {
_, err = conn.WriteTo(b[:n], remoteAddr)
return err
}
@@ -155,25 +128,21 @@ func (h *tunHandler) transportTun(ctx context.Context, tun net.Conn, conn net.Pa
if waterutil.IsIPv4(b[:n]) {
header, err := ipv4.ParseHeader(b[:n])
if err != nil {
log.Debugf("[tun] %s: %v", tun.LocalAddr(), err)
log.Errorf("[tun] %s: %v", tun.LocalAddr(), err)
return nil
}
if config.Debug {
log.Debugf("[tun] %s", header.String())
}
log.Debugf("[tun] %s", header.String())
src, dst = header.Src, header.Dst
} else if waterutil.IsIPv6(b[:n]) {
header, err := ipv6.ParseHeader(b[:n])
if err != nil {
log.Debugf("[tun] %s: %v", tun.LocalAddr(), err)
log.Errorf("[tun] %s: %v", tun.LocalAddr(), err)
return nil
}
if config.Debug {
log.Debugf("[tun] %s", header.String())
}
log.Debugf("[tun] %s", header.String())
src, dst = header.Src, header.Dst
} else {
log.Debugf("[tun] unknown packet")
log.Errorf("[tun] unknown packet")
return nil
}
@@ -183,15 +152,16 @@ func (h *tunHandler) transportTun(ctx context.Context, tun net.Conn, conn net.Pa
return nil
}
if config.Debug {
log.Debugf("[tun] find route: %s -> %s", dst, addr)
}
log.Debugf("[tun] find route: %s -> %s", dst, addr)
_, err = conn.WriteTo(b[:n], addr)
return err
}()
if err != nil {
errChan <- err
select {
case errChan <- err:
default:
}
return
}
}
@@ -201,15 +171,15 @@ func (h *tunHandler) transportTun(ctx context.Context, tun net.Conn, conn net.Pa
b := LPool.Get().([]byte)
defer LPool.Put(b)
for ctx.Err() == nil {
for {
err := func() error {
n, addr, err := conn.ReadFrom(b[:])
if err != nil && err != shadowaead.ErrShortPacket {
n, srcAddr, err := conn.ReadFrom(b[:])
if err != nil {
return err
}
// client side, deliver packet to tun device.
if raddr != nil {
if remoteAddr != nil {
_, err = tun.Write(b[:n])
return err
}
@@ -218,42 +188,36 @@ func (h *tunHandler) transportTun(ctx context.Context, tun net.Conn, conn net.Pa
if waterutil.IsIPv4(b[:n]) {
header, err := ipv4.ParseHeader(b[:n])
if err != nil {
log.Debugf("[tun] %s: %v", tun.LocalAddr(), err)
log.Errorf("[tun] %s: %v", tun.LocalAddr(), err)
return nil
}
if config.Debug {
log.Debugf("[tun] %s", header.String())
}
log.Debugf("[tun] %s", header.String())
src, dst = header.Src, header.Dst
} else if waterutil.IsIPv6(b[:n]) {
header, err := ipv6.ParseHeader(b[:n])
if err != nil {
log.Debugf("[tun] %s: %v", tun.LocalAddr(), err)
log.Errorf("[tun] %s: %v", tun.LocalAddr(), err)
return nil
}
if config.Debug {
log.Debugf("[tun] %s", header.String())
}
log.Debugf("[tun] %s", header.String())
src, dst = header.Src, header.Dst
} else {
log.Debugf("[tun] unknown packet")
log.Errorf("[tun] unknown packet")
return nil
}
routeKey := ipToTunRouteKey(src)
if actual, loaded := h.routes.LoadOrStore(routeKey, addr); loaded {
if actual.(net.Addr).String() != addr.String() {
log.Debugf("[tun] update route: %s -> %s (old %s)", src, addr, actual.(net.Addr))
h.routes.Store(routeKey, addr)
if actual, loaded := h.routes.LoadOrStore(routeKey, srcAddr); loaded {
if actual.(net.Addr).String() != srcAddr.String() {
log.Debugf("[tun] update route: %s -> %s (old %s)", src, srcAddr, actual.(net.Addr))
h.routes.Store(routeKey, srcAddr)
}
} else {
log.Debugf("[tun] new route: %s -> %s", src, addr)
log.Debugf("[tun] new route: %s -> %s", src, srcAddr)
}
if routeToAddr := h.findRouteFor(dst); routeToAddr != nil {
if config.Debug {
log.Debugf("[tun] find route: %s -> %s", dst, routeToAddr)
}
log.Debugf("[tun] find route: %s -> %s", dst, routeToAddr)
_, err = conn.WriteTo(b[:n], routeToAddr)
return err
}
@@ -269,7 +233,10 @@ func (h *tunHandler) transportTun(ctx context.Context, tun net.Conn, conn net.Pa
}()
if err != nil {
errChan <- err
select {
case errChan <- err:
default:
}
return
}
}

View File

@@ -4,11 +4,11 @@ import (
"context"
"fmt"
"net"
"os"
"strconv"
"strings"
"time"
"github.com/containernetworking/cni/pkg/types"
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
v1 "k8s.io/api/core/v1"
@@ -30,7 +30,6 @@ import (
"github.com/wencaiwulue/kubevpn/pkg/config"
"github.com/wencaiwulue/kubevpn/pkg/core"
"github.com/wencaiwulue/kubevpn/pkg/dns"
"github.com/wencaiwulue/kubevpn/pkg/route"
"github.com/wencaiwulue/kubevpn/pkg/tun"
"github.com/wencaiwulue/kubevpn/pkg/util"
)
@@ -133,7 +132,6 @@ func (c *ConnectOptions) DoConnect() (err error) {
c.deleteFirewallRule(ctx)
c.setupDNS()
log.Info("dns service ok")
//c.detectConflictDevice()
return
}
@@ -144,7 +142,7 @@ func (c *ConnectOptions) portForward(ctx context.Context, port string) error {
podInterface := c.clientset.CoreV1().Pods(c.Namespace)
go func() {
var first = pointer.Bool(true)
for ctx.Err() == nil {
for {
func() {
podList, err := c.GetRunningPodList()
if err != nil {
@@ -261,7 +259,7 @@ func (c *ConnectOptions) startLocalTunServe(ctx context.Context, forwardAddress
// Listen all pod, add route if needed
func (c *ConnectOptions) addRouteDynamic(ctx context.Context) {
for ctx.Err() == nil {
for {
func() {
w, err := c.clientset.CoreV1().Pods(v1.NamespaceAll).Watch(ctx, metav1.ListOptions{Watch: true, TimeoutSeconds: pointer.Int64(30)})
if err != nil {
@@ -299,7 +297,7 @@ func (c *ConnectOptions) addRouteDynamic(ctx context.Context) {
return
}
}
err := tun.AddRoutes(tun.IPRoute{Dest: &net.IPNet{IP: net.ParseIP(ip), Mask: net.CIDRMask(32, 32)}})
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 {
@@ -323,16 +321,6 @@ func (c *ConnectOptions) deleteFirewallRule(ctx context.Context) {
go util.Heartbeats(ctx)
}
func (c *ConnectOptions) detectConflictDevice() {
tunName := os.Getenv(config.EnvTunNameOrLUID)
if len(tunName) == 0 {
return
}
if err := route.DetectAndDisableConflictDevice(tunName); err != nil {
log.Warnf("error occours while disable conflict devices, err: %v", err)
}
}
func (c *ConnectOptions) setupDNS() {
const port = 53
pod, err := c.GetRunningPodList()

View File

@@ -148,7 +148,6 @@ func TestPatchAnnotation(t *testing.T) {
func TestPing(t *testing.T) {
ip := "10.233.98.197"
ping, _ := Ping(ip)
pinger, err := probing.NewPinger(ip)
if err != nil {
panic(err)
@@ -159,5 +158,5 @@ func TestPing(t *testing.T) {
panic(err)
}
stats := pinger.Statistics() // get send/receive/duplicate/rtt stats
fmt.Println(ping)
fmt.Println(stats)
}

View File

@@ -5,6 +5,7 @@ import (
"net"
"strings"
"github.com/containernetworking/cni/pkg/types"
"github.com/pkg/errors"
"github.com/wencaiwulue/kubevpn/pkg/config"
@@ -12,6 +13,10 @@ import (
"github.com/wencaiwulue/kubevpn/pkg/tun"
)
// Route example:
// -L "tcp://:10800" -L "tun://:8422?net=223.254.0.100/16"
// -L "tun:/10.233.24.133:8422?net=223.254.0.102/16&route=223.254.0.0/16"
// -L "tun:/127.0.0.1:8422?net=223.254.0.102/16&route=223.254.0.0/16,10.233.0.0/16" -F "tcp://127.0.0.1:10800"
type Route struct {
ServeNodes []string // -L tun
ChainNode string // -F tcp
@@ -78,7 +83,7 @@ func (r *Route) GenerateServers() ([]core.Server, error) {
return servers, nil
}
func parseIPRoutes(routeStringList string) (routes []tun.IPRoute) {
func parseIPRoutes(routeStringList string) (routes []types.Route) {
if len(routeStringList) == 0 {
return
}
@@ -86,7 +91,7 @@ func parseIPRoutes(routeStringList string) (routes []tun.IPRoute) {
routeList := strings.Split(routeStringList, ",")
for _, route := range routeList {
if _, ipNet, _ := net.ParseCIDR(strings.TrimSpace(route)); ipNet != nil {
routes = append(routes, tun.IPRoute{Dest: ipNet})
routes = append(routes, types.Route{Dst: *ipNet})
}
}
return

View File

@@ -1,57 +0,0 @@
package route
import (
"bytes"
"net"
"strings"
log "github.com/sirupsen/logrus"
"k8s.io/apimachinery/pkg/util/sets"
)
// DetectAndDisableConflictDevice will detect conflict route table and try to disable device
// 1, get route table
// 2, detect conflict
// 3, disable device
func DetectAndDisableConflictDevice(origin string) error {
routeTable, err := GetRouteTable()
if err != nil {
return err
}
conflict := detectConflictDevice(origin, routeTable)
if len(conflict) != 0 {
log.Infof("those device: %s will to be disabled because of route conflict with %s", strings.Join(conflict, ","), origin)
}
err = DisableDevice(conflict)
return err
}
func detectConflictDevice(origin string, routeTable map[string][]*net.IPNet) []string {
var conflict = sets.NewString()
vpnRoute := routeTable[origin]
for k, originRoute := range routeTable {
if k == origin {
continue
}
out:
for _, originNet := range originRoute {
for _, vpnNet := range vpnRoute {
// like 255.255.0.0/16 should not take effect
if bytes.Equal(originNet.IP, originNet.Mask) || bytes.Equal(vpnNet.IP, vpnNet.Mask) {
continue
}
if vpnNet.Contains(originNet.IP) || originNet.Contains(vpnNet.IP) {
originMask, _ := originNet.Mask.Size()
vpnMask, _ := vpnNet.Mask.Size()
// means interface: k is more precisely, traffic will go to interface k because route table feature
// mare precisely is preferred
if originMask > vpnMask {
conflict.Insert(k)
break out
}
}
}
}
}
return conflict.Delete(origin).List()
}

View File

@@ -1,156 +0,0 @@
package route
import (
"fmt"
"net"
"syscall"
"testing"
"golang.org/x/net/route"
)
// netstat -anr | grep 10.61
//10.61/16 utun4 USc utun4
//10.61.10.251 10.176.32.40 UGHWIig utun2
//10.61.64/18 10.61.64.1 UCS utun3
//10.61.64.1 10.61.64.0 UH utun3
func TestConflict(t *testing.T) {
var mm = make(map[string][]*net.IPNet)
_, ipNet, err := net.ParseCIDR("10.61.0.0/16")
if err != nil {
panic(err)
}
_, ipNet2, err := net.ParseCIDR("10.61.64.0/18")
if err != nil {
panic(err)
}
_, ipNet3, err := net.ParseCIDR("10.61.64.1/24")
if err != nil {
panic(err)
}
mm["utun4"] = []*net.IPNet{ipNet}
mm["utun3"] = []*net.IPNet{ipNet2, ipNet3}
var origin = "utun4"
conflict := detectConflictDevice(origin, mm)
fmt.Println(conflict)
}
func TestGetConflictDevice(t *testing.T) {
err := DetectAndDisableConflictDevice("utun2")
if err != nil {
panic(err)
}
}
func TestParse(t *testing.T) {
rib, err := route.FetchRIB(syscall.AF_INET, syscall.NET_RT_DUMP, 0)
if err != nil {
panic(err)
}
msgs, err := route.ParseRIB(syscall.NET_RT_DUMP, rib)
if err != nil {
panic(err)
}
nameToIndex := make(map[int]string)
addrs, err := net.Interfaces()
for _, addr := range addrs {
nameToIndex[addr.Index] = addr.Name
}
m := make(map[string][]route.Addr)
for _, msg := range msgs {
message := msg.(*route.RouteMessage)
if name, found := nameToIndex[message.Index]; found {
if v, ok := m[name]; ok {
temp := removeEmptyElement(message)
m[name] = append(v, temp...)
} else {
m[name] = removeEmptyElement(message)
}
}
}
fmt.Println(m)
}
func removeEmptyElement(message *route.RouteMessage) []route.Addr {
var temp []route.Addr
for _, addr := range message.Addrs {
if addr != nil {
temp = append(temp, addr)
}
}
return temp
}
func TestGetRouteTableByNetstat(t *testing.T) {
ip := net.ParseIP("192.168.1.1")
for i := range ip.To4() {
fmt.Println(i)
}
}
func TestInteract(t *testing.T) {
type data struct {
ipNet1 *net.IPNet
ipNet2 *net.IPNet
result bool
}
var list = []data{{
ipNet1: &net.IPNet{
IP: net.ParseIP("192.168.1.1"),
Mask: net.CIDRMask(24, 32),
},
ipNet2: &net.IPNet{
IP: net.ParseIP("192.168.100.100"),
Mask: net.CIDRMask(16, 32),
},
result: true,
}, {
ipNet1: &net.IPNet{
IP: net.ParseIP("192.168.0.0"),
Mask: net.CIDRMask(17, 32),
},
ipNet2: &net.IPNet{
IP: net.ParseIP("192.168.0.0"),
Mask: net.CIDRMask(16, 32),
},
result: true,
}, {
ipNet1: &net.IPNet{
IP: net.ParseIP("191.168.0.0"),
Mask: net.CIDRMask(17, 32),
},
ipNet2: &net.IPNet{
IP: net.ParseIP("192.168.0.0"),
Mask: net.CIDRMask(16, 32),
},
result: false,
}, {
ipNet1: &net.IPNet{
IP: net.ParseIP("255.255.255.0"),
Mask: net.CIDRMask(24, 32),
},
ipNet2: &net.IPNet{
IP: net.ParseIP("255.255.0.0"),
Mask: net.CIDRMask(16, 32),
},
result: true,
}, {
ipNet1: &net.IPNet{
IP: net.ParseIP("255.255.255.255"),
Mask: net.CIDRMask(32, 32),
},
ipNet2: &net.IPNet{
IP: net.ParseIP("255.255.0.0"),
Mask: net.CIDRMask(16, 32),
},
result: false,
}}
for _, d := range list {
if b := d.ipNet1.Contains(d.ipNet2.IP) || d.ipNet2.Contains(d.ipNet1.IP); d.result != b {
t.FailNow()
}
}
}

View File

@@ -1,99 +0,0 @@
//go:build !amd64 && !arm64 && !x86 && !386
// +build !amd64,!arm64,!x86,!386
package route
import (
"net"
"syscall"
"golang.org/x/net/route"
)
// not contains route like 10.61.64/18 10.61.64.1 UCS utun3, todo how about pull a merge to golang sdk???
// just contains 10.61.64, which mask is 0, 8, 16, 32, do not middle number
func getRouteTableByFetchRIB() (map[string][]*net.IPNet, error) {
rib, err := route.FetchRIB(syscall.AF_UNSPEC, syscall.NET_RT_DUMP, 0)
if err != nil {
return nil, err
}
msgs, err := route.ParseRIB(syscall.NET_RT_DUMP, rib)
if err != nil {
return nil, err
}
nameToIndex := make(map[int]string)
addrs, err := net.Interfaces()
for _, addr := range addrs {
nameToIndex[addr.Index] = addr.Name
}
m := make(map[string][]route.Addr)
for _, msg := range msgs {
message := msg.(*route.RouteMessage)
if name, found := nameToIndex[message.Index]; found {
if v, ok := m[name]; ok {
temp := removeNilElement(message)
m[name] = append(v, temp...)
} else {
m[name] = removeNilElement(message)
}
}
}
var mm = make(map[string][]*net.IPNet)
for k, v := range m {
var temp []*net.IPNet
for _, addr := range v {
if a, ok := addr.(*route.Inet4Addr); ok {
var ip = make(net.IP, net.IPv4len)
copy(ip, a.IP[:])
if one, _ := mask(ip).Size(); one == 0 {
continue
}
temp = append(temp, &net.IPNet{IP: ip, Mask: mask(ip)})
} else if a, ok := addr.(*route.Inet6Addr); ok {
var ip = make(net.IP, net.IPv6len)
copy(ip, a.IP[:])
if one, _ := mask(ip).Size(); one == 0 {
continue
}
temp = append(temp, &net.IPNet{IP: ip, Mask: mask(ip)})
} else if _, ok := addr.(*route.LinkAddr); ok {
//fmt.Println(a)
// todo
}
}
mm[k] = temp
}
return mm, nil
}
func removeNilElement(message *route.RouteMessage) []route.Addr {
var temp []route.Addr
for _, addr := range message.Addrs {
if addr != nil {
temp = append(temp, addr)
}
}
return temp
}
// route.FetchRIB fetches a routing information base from the operating system.
// In most cases, zero means a wildcard.
func mask(ip []byte) net.IPMask {
size := 0
for i := len(ip) - 1; i >= 0; i-- {
if ip[i] == 0 {
size++
} else {
break
}
}
// 0.0.0.0
if size == len(ip) {
return net.CIDRMask(len(ip)*8, len(ip)*8)
}
if size == 0 {
return net.CIDRMask(0, len(ip)*8)
}
return net.CIDRMask((len(ip)-size)*8, len(ip)*8)
}

View File

@@ -1,264 +0,0 @@
//go:build darwin
// +build darwin
package route
import (
"net"
"os/exec"
"strconv"
"strings"
log "github.com/sirupsen/logrus"
)
// sudo ifconfig utun3 down
func DisableDevice(conflict []string) error {
for _, dev := range conflict {
if err := exec.Command("sudo", "ifconfig", dev, "down").Run(); err != nil {
log.Errorf("can not disable interface: %s, err: %v", dev, err)
return err
} else {
// todo: optimize it
//handler.RollbackFuncList = append(handler.RollbackFuncList, func() {
// _ = exec.Command("sudo", "ifconfig", dev, "up").Run()
//})
}
}
return nil
}
func GetRouteTable() (map[string][]*net.IPNet, error) {
output, err := exec.Command("netstat", "-anr").CombinedOutput()
if err != nil {
return nil, err
}
split := strings.Split(string(output), "\n")
routeTable := make(map[string][]*net.IPNet)
for _, i := range split {
fields := strings.Fields(i)
if len(fields) >= 4 {
cidr := fields[0]
eth := fields[3]
if _, ipNet, err := parseCIDR(cidr); err == nil {
if v, ok := routeTable[eth]; ok {
routeTable[eth] = append(v, ipNet)
} else {
routeTable[eth] = []*net.IPNet{ipNet}
}
}
}
}
return routeTable, nil
}
const big = 0xFFFFFF
// Decimal to integer.
// Returns number, characters consumed, success.
func dtoi(s string) (n int, i int, ok bool) {
n = 0
for i = 0; i < len(s) && '0' <= s[i] && s[i] <= '9'; i++ {
n = n*10 + int(s[i]-'0')
if n >= big {
return big, i, false
}
}
if i == 0 {
return 0, 0, false
}
return n, i, true
}
// Hexadecimal to integer.
// Returns number, characters consumed, success.
func xtoi(s string) (n int, i int, ok bool) {
n = 0
for i = 0; i < len(s); i++ {
if '0' <= s[i] && s[i] <= '9' {
n *= 16
n += int(s[i] - '0')
} else if 'a' <= s[i] && s[i] <= 'f' {
n *= 16
n += int(s[i]-'a') + 10
} else if 'A' <= s[i] && s[i] <= 'F' {
n *= 16
n += int(s[i]-'A') + 10
} else {
break
}
if n >= big {
return 0, i, false
}
}
if i == 0 {
return 0, i, false
}
return n, i, true
}
func parseCIDR(s string) (net.IP, *net.IPNet, error) {
indexByte6 := strings.Count(s, ":")
indexByte4 := strings.Count(s, ".")
if indexByte4 < 0 && indexByte6 < 0 {
return nil, nil, &net.ParseError{Type: "CIDR address", Text: s}
}
i := strings.IndexByte(s, '/')
var addr, mask string
if i < 0 {
addr = s
// ipv6
if indexByte6 > 0 {
mask = strconv.Itoa((indexByte6 + 1) * 8)
} else {
mask = strconv.Itoa((indexByte4 + 1) * 8)
}
} else {
addr, mask = s[:i], s[i+1:]
}
iplen := net.IPv4len
ip := parseIPv4(addr)
if ip == nil {
iplen = net.IPv6len
ip = parseIPv6(addr)
}
n, i, ok := dtoi(mask)
if ip == nil || !ok || i != len(mask) || n < 0 || n > 8*iplen {
return nil, nil, &net.ParseError{Type: "CIDR address", Text: s}
}
m := net.CIDRMask(n, 8*iplen)
return ip, &net.IPNet{IP: ip.Mask(m), Mask: m}, nil
}
// Parse IPv4 address (d.d.d.d).
func parseIPv4(s string) net.IP {
var p [net.IPv4len]byte
for i := 0; i < net.IPv4len; i++ {
if len(s) == 0 {
// Missing octets.
continue
}
if i > 0 {
if s[0] != '.' {
return nil
}
s = s[1:]
}
n, c, ok := dtoi(s)
if !ok || n > 0xFF {
return nil
}
if c > 1 && s[0] == '0' {
// Reject non-zero components with leading zeroes.
return nil
}
s = s[c:]
p[i] = byte(n)
}
if len(s) != 0 {
return nil
}
return net.IPv4(p[0], p[1], p[2], p[3])
}
func parseIPv6(s string) (ip net.IP) {
ip = make(net.IP, net.IPv6len)
ellipsis := -1 // position of ellipsis in ip
// Might have leading ellipsis
if len(s) >= 2 && s[0] == ':' && s[1] == ':' {
ellipsis = 0
s = s[2:]
// Might be only ellipsis
if len(s) == 0 {
return ip
}
}
// Loop, parsing hex numbers followed by colon.
i := 0
for i < net.IPv6len {
// Hex number.
n, c, ok := xtoi(s)
if !ok || n > 0xFFFF {
i++
continue
}
// If followed by dot, might be in trailing IPv4.
if c < len(s) && s[c] == '.' {
if ellipsis < 0 && i != net.IPv6len-net.IPv4len {
// Not the right place.
return nil
}
if i+net.IPv4len > net.IPv6len {
// Not enough room.
return nil
}
ip4 := parseIPv4(s)
if ip4 == nil {
return nil
}
ip[i] = ip4[12]
ip[i+1] = ip4[13]
ip[i+2] = ip4[14]
ip[i+3] = ip4[15]
s = ""
i += net.IPv4len
break
}
// Save this 16-bit chunk.
ip[i] = byte(n >> 8)
ip[i+1] = byte(n)
i += 2
// Stop at end of string.
s = s[c:]
if len(s) == 0 {
break
}
// Otherwise must be followed by colon and more.
if s[0] != ':' || len(s) == 1 {
return nil
}
s = s[1:]
// Look for ellipsis.
if s[0] == ':' {
if ellipsis >= 0 { // already have one
return nil
}
ellipsis = i
s = s[1:]
if len(s) == 0 { // can be at end
break
}
}
}
// Must have used entire string.
if len(s) != 0 {
return nil
}
// If didn't parse enough, expand ellipsis.
if i < net.IPv6len {
if ellipsis < 0 {
return nil
}
n := net.IPv6len - i
for j := i - 1; j >= ellipsis; j-- {
ip[j+n] = ip[j]
}
for j := ellipsis + n - 1; j >= ellipsis; j-- {
ip[j] = 0
}
} else if ellipsis >= 0 {
// Ellipsis must represent at least one 0 group.
return nil
}
return ip
}

View File

@@ -1,49 +0,0 @@
//go:build !windows && !darwin
// +build !windows,!darwin
package route
import (
"net"
"os/exec"
"strings"
)
func GetRouteTable() (map[string][]*net.IPNet, error) {
output, err := exec.Command("route", "-n").CombinedOutput()
if err != nil {
return nil, err
}
split := strings.Split(string(output), "\n")
routeTable := make(map[string][]*net.IPNet)
for _, i := range split {
fields := strings.Fields(i)
if len(fields) >= 8 {
dst := net.ParseIP(fields[0])
mask := make(net.IPMask, net.IPv4len)
copy(mask, net.ParseIP(fields[2]))
eth := fields[7]
if v, ok := routeTable[eth]; ok {
routeTable[eth] = append(v, &net.IPNet{IP: dst, Mask: mask})
} else {
routeTable[eth] = []*net.IPNet{{IP: dst, Mask: mask}}
}
}
}
return routeTable, nil
}
func DisableDevice(list []string) error {
for _, dev := range list {
if err := exec.Command("sudo", "ifconfig", dev, "down").Run(); err != nil {
return err
} else {
// todo: optimize code
//rollbackFuncList = append(rollbackFuncList, func() {
// _ = exec.Command("sudo", "ifconfig", dev, "up").Run()
//})
}
}
return nil
}

View File

@@ -1,16 +0,0 @@
//go:build windows
// +build windows
package route
import (
"net"
)
func GetRouteTable() (map[string][]*net.IPNet, error) {
return make(map[string][]*net.IPNet), nil
}
func DisableDevice(list []string) error {
return nil
}

View File

@@ -6,6 +6,7 @@ import (
"os"
"time"
"github.com/containernetworking/cni/pkg/types"
log "github.com/sirupsen/logrus"
"github.com/songgao/water"
@@ -17,7 +18,7 @@ type Config struct {
Name string
Addr string
MTU int
Routes []IPRoute
Routes []types.Route
Gateway string
}
@@ -109,14 +110,8 @@ func (c *tunConn) SetWriteDeadline(time.Time) error {
return &net.OpError{Op: "set", Net: "tun", Source: nil, Addr: nil, Err: errors.New("write deadline not supported")}
}
// IPRoute is an IP routing entry.
type IPRoute struct {
Dest *net.IPNet
Gateway net.IP
}
// AddRoutes for outer called
func AddRoutes(routes ...IPRoute) error {
func AddRoutes(routes ...types.Route) error {
env := os.Getenv(config.EnvTunNameOrLUID)
return addTunRoutes(env, routes...)
}

View File

@@ -10,6 +10,7 @@ import (
"os/exec"
"strings"
"github.com/containernetworking/cni/pkg/types"
log "github.com/sirupsen/logrus"
"github.com/songgao/water"
@@ -61,16 +62,17 @@ func createTun(cfg Config) (conn net.Conn, itf *net.Interface, err error) {
return
}
func addTunRoutes(ifName string, routes ...IPRoute) error {
func addTunRoutes(ifName string, routes ...types.Route) error {
for _, route := range routes {
if route.Dest == nil {
if route.Dst.String() == "" {
continue
}
cmd := fmt.Sprintf("route add -net %s -interface %s", route.Dest.String(), ifName)
cmd := fmt.Sprintf("route add -net %s -interface %s", route.Dst.String(), ifName)
log.Debugf("[tun] %s", cmd)
args := strings.Split(cmd, " ")
if er := exec.Command(args[0], args[1:]...).Run(); er != nil {
return fmt.Errorf("%s: %v", cmd, er)
err := exec.Command(args[0], args[1:]...).Run()
if err != nil {
return fmt.Errorf("%s: %v", cmd, err)
}
}
return nil

View File

@@ -10,6 +10,7 @@ import (
"os"
"syscall"
"github.com/containernetworking/cni/pkg/types"
"github.com/docker/libcontainer/netlink"
"github.com/milosgajdos/tenus"
log "github.com/sirupsen/logrus"
@@ -85,14 +86,14 @@ func createTun(cfg Config) (conn net.Conn, itf *net.Interface, err error) {
return
}
func addTunRoutes(ifName string, routes ...IPRoute) error {
func addTunRoutes(ifName string, routes ...types.Route) error {
for _, route := range routes {
if route.Dest == nil {
if route.Dst.String() == "" {
continue
}
cmd := fmt.Sprintf("ip route add %s dev %s", route.Dest.String(), ifName)
cmd := fmt.Sprintf("ip route add %s dev %s", route.Dst.String(), ifName)
log.Debugf("[tun] %s", cmd)
if err := netlink.AddRoute(route.Dest.String(), "", "", ifName); err != nil && !errors.Is(err, syscall.EEXIST) {
if err := netlink.AddRoute(route.Dst.String(), "", "", ifName); err != nil && !errors.Is(err, syscall.EEXIST) {
return fmt.Errorf("%s: %v", cmd, err)
}
}

View File

@@ -9,6 +9,7 @@ import (
"os/exec"
"strings"
"github.com/containernetworking/cni/pkg/types"
log "github.com/sirupsen/logrus"
"github.com/songgao/water"
@@ -61,12 +62,12 @@ func createTun(cfg Config) (conn net.Conn, itf *net.Interface, err error) {
return
}
func addTunRoutes(ifName string, routes ...IPRoute) error {
func addTunRoutes(ifName string, routes ...types.Route) error {
for _, route := range routes {
if route.Dest == nil {
if route.Dst.String() == "" {
continue
}
cmd := fmt.Sprintf("route add -net %s -interface %s", route.Dest.String(), ifName)
cmd := fmt.Sprintf("route add -net %s -interface %s", route.Dst.String(), ifName)
log.Debugf("[tun] %s", cmd)
args := strings.Split(cmd, " ")
if er := exec.Command(args[0], args[1:]...).Run(); er != nil {

View File

@@ -11,6 +11,7 @@ import (
"strconv"
"time"
"github.com/containernetworking/cni/pkg/types"
"github.com/pkg/errors"
"golang.org/x/sys/windows"
wireguardtun "golang.zx2c4.com/wireguard/tun"
@@ -58,7 +59,7 @@ func createTun(cfg Config) (net.Conn, *net.Interface, error) {
return &winTunConn{ifce: tunDevice, addr: &net.IPAddr{IP: ip}}, iface, nil
}
func addTunRoutes(luid string, routes ...IPRoute) error {
func addTunRoutes(luid string, routes ...types.Route) error {
parseUint, err := strconv.ParseUint(luid, 10, 64)
if err != nil {
return err
@@ -66,21 +67,21 @@ func addTunRoutes(luid string, routes ...IPRoute) error {
ifName := winipcfg.LUID(parseUint)
_ = ifName.FlushRoutes(windows.AF_INET)
for _, route := range routes {
if route.Dest == nil {
if route.Dst.String() == "" {
continue
}
var gw string
if gw != "" {
route.Gateway = net.ParseIP(gw)
route.GW = net.ParseIP(gw)
} else {
route.Gateway = net.IPv4(0, 0, 0, 0)
route.GW = net.IPv4(0, 0, 0, 0)
}
prefix, err := netip.ParsePrefix(route.Dest.String())
prefix, err := netip.ParsePrefix(route.Dst.String())
if err != nil {
return err
}
var addr netip.Addr
addr, err = netip.ParseAddr(route.Gateway.String())
addr, err = netip.ParseAddr(route.GW.String())
if err != nil {
return err
}