mirror of
https://github.com/kubenetworks/kubevpn.git
synced 2025-10-24 07:43:17 +08:00
feat: feat: optimize code and remove detect conflict interface
This commit is contained in:
3
go.mod
3
go.mod
@@ -12,7 +12,6 @@ require (
|
|||||||
github.com/milosgajdos/tenus v0.0.3
|
github.com/milosgajdos/tenus v0.0.3
|
||||||
github.com/moby/term v0.0.0-20221205130635-1aeaba878587
|
github.com/moby/term v0.0.0-20221205130635-1aeaba878587
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/shadowsocks/go-shadowsocks2 v0.1.5
|
|
||||||
github.com/sirupsen/logrus v1.9.0
|
github.com/sirupsen/logrus v1.9.0
|
||||||
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8
|
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8
|
||||||
github.com/spf13/cobra v1.6.1
|
github.com/spf13/cobra v1.6.1
|
||||||
@@ -88,13 +87,11 @@ require (
|
|||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
|
||||||
github.com/pmezard/go-difflib v1.0.0 // 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/rivo/uniseg v0.4.3 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
github.com/xlab/treeprint v1.1.0 // indirect
|
github.com/xlab/treeprint v1.1.0 // indirect
|
||||||
go.starlark.net v0.0.0-20230112144946-fae38c8a6d89 // 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/mod v0.7.0 // indirect
|
||||||
golang.org/x/sync v0.1.0 // indirect
|
golang.org/x/sync v0.1.0 // indirect
|
||||||
golang.org/x/term v0.4.0 // indirect
|
golang.org/x/term v0.4.0 // indirect
|
||||||
|
|||||||
9
go.sum
9
go.sum
@@ -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-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.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||||
github.com/prometheus/client_model v0.2.0/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.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||||
github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw=
|
github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw=
|
||||||
github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
|
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 h1:9TeeWRcjW2qd05I8Kf9knPkW4vLM/hYoa6z9ABvxje8=
|
||||||
github.com/schollz/progressbar/v3 v3.13.0/go.mod h1:ZBYnSuLAX2LU8P8UiKN/KgF2DY58AJC8yfVYLPC8Ly4=
|
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/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 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 h1:TG/diQgUe0pntT/2D9tmUCz4VNwm9MfrtPr0SU2qSX8=
|
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-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-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-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-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-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
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-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-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-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-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-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/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.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 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
|
||||||
golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
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-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.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||||
golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg=
|
golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg=
|
||||||
|
|||||||
@@ -3,10 +3,8 @@ package core
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net"
|
"net"
|
||||||
"time"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"k8s.io/client-go/util/retry"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
@@ -18,34 +16,22 @@ type Server struct {
|
|||||||
func (s *Server) Serve(ctx context.Context) error {
|
func (s *Server) Serve(ctx context.Context) error {
|
||||||
l := s.Listener
|
l := s.Listener
|
||||||
defer l.Close()
|
defer l.Close()
|
||||||
var tempDelay time.Duration
|
//go func() {
|
||||||
go func() {
|
// <-ctx.Done()
|
||||||
<-ctx.Done()
|
// l.Close()
|
||||||
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 {
|
||||||
}
|
select {
|
||||||
}()
|
case <-ctx.Done():
|
||||||
for ctx.Err() == nil {
|
return nil
|
||||||
conn, e := l.Accept()
|
default:
|
||||||
if e != nil {
|
conn, err := l.Accept()
|
||||||
if ne, ok := e.(net.Error); ok && ne.Timeout() {
|
if err != nil {
|
||||||
if tempDelay == 0 {
|
log.Warnf("server: accept error: %v", err)
|
||||||
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)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return e
|
|
||||||
}
|
|
||||||
tempDelay = 0
|
|
||||||
|
|
||||||
go s.Handler.Handle(ctx, conn)
|
go s.Handler.Handle(ctx, conn)
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/wencaiwulue/kubevpn/pkg/config"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type fakeUDPTunnelConnector struct {
|
type fakeUDPTunnelConnector struct {
|
||||||
@@ -33,19 +31,14 @@ func TCPHandler() Handler {
|
|||||||
|
|
||||||
func (h *fakeUdpHandler) Handle(ctx context.Context, tcpConn net.Conn) {
|
func (h *fakeUdpHandler) Handle(ctx context.Context, tcpConn net.Conn) {
|
||||||
defer tcpConn.Close()
|
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
|
// serve tunnel udp, tunnel <-> remote, handle tunnel udp request
|
||||||
udpConn, err := net.DialUDP("udp", nil, Server8422)
|
udpConn, err := net.DialUDP("udp", nil, Server8422)
|
||||||
if err != nil {
|
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
|
return
|
||||||
}
|
}
|
||||||
defer udpConn.Close()
|
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())
|
log.Debugf("[tcpserver] udp-tun %s <-> %s", tcpConn.RemoteAddr(), udpConn.LocalAddr())
|
||||||
_ = h.tunnelServerUDP(tcpConn, udpConn)
|
_ = h.tunnelServerUDP(tcpConn, udpConn)
|
||||||
log.Debugf("[tcpserver] udp-tun %s >-< %s", tcpConn.RemoteAddr(), udpConn.LocalAddr())
|
log.Debugf("[tcpserver] udp-tun %s >-< %s", tcpConn.RemoteAddr(), udpConn.LocalAddr())
|
||||||
@@ -73,10 +66,8 @@ func (h *fakeUdpHandler) tunnelServerUDP(tcpConn net.Conn, udpConn *net.UDPConn)
|
|||||||
errChan <- err
|
errChan <- err
|
||||||
return
|
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))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}()
|
}()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
@@ -98,10 +89,8 @@ func (h *fakeUdpHandler) tunnelServerUDP(tcpConn net.Conn, udpConn *net.UDPConn)
|
|||||||
errChan <- err
|
errChan <- err
|
||||||
return
|
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
|
return <-errChan
|
||||||
}
|
}
|
||||||
@@ -141,17 +130,3 @@ func (c *fakeUDPTunnelConn) WriteTo(b []byte, _ net.Addr) (int, error) {
|
|||||||
func (c *fakeUDPTunnelConn) Close() error {
|
func (c *fakeUDPTunnelConn) Close() error {
|
||||||
return c.Conn.Close()
|
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
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -3,21 +3,17 @@ package core
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"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/ipv4"
|
||||||
"golang.org/x/net/ipv6"
|
"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 {
|
func ipToTunRouteKey(ip net.IP) string {
|
||||||
return ip.To16().String()
|
return ip.String()
|
||||||
}
|
}
|
||||||
|
|
||||||
type tunHandler struct {
|
type tunHandler struct {
|
||||||
@@ -37,71 +33,55 @@ func TunHandler(chain *Chain, node *Node) Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *tunHandler) Handle(ctx context.Context, conn net.Conn) {
|
func (h *tunHandler) Handle(ctx context.Context, tun net.Conn) {
|
||||||
defer conn.Close()
|
defer tun.Close()
|
||||||
var err error
|
var err error
|
||||||
var raddr net.Addr
|
var remoteAddr net.Addr
|
||||||
if addr := h.node.Remote; addr != "" {
|
if addr := h.node.Remote; addr != "" {
|
||||||
raddr, err = net.ResolveUDPAddr("udp", addr)
|
remoteAddr, err = net.ResolveUDPAddr("udp", addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debugf("[tun] %s: remote addr: %v", conn.LocalAddr(), err)
|
log.Errorf("[tun] %s: remote addr: %v", tun.LocalAddr(), err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var tempDelay time.Duration
|
for {
|
||||||
for ctx.Err() == nil {
|
|
||||||
err = func() error {
|
err = func() error {
|
||||||
var err error
|
var err error
|
||||||
var pc net.PacketConn
|
var packetConn net.PacketConn
|
||||||
if raddr != nil && !h.chain.IsEmpty() {
|
if remoteAddr != nil && !h.chain.IsEmpty() {
|
||||||
cc, err := h.chain.DialContext(ctx)
|
cc, err := h.chain.DialContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var ok bool
|
var ok bool
|
||||||
pc, ok = cc.(net.PacketConn)
|
packetConn, ok = cc.(net.PacketConn)
|
||||||
if !ok {
|
if !ok {
|
||||||
err = errors.New("not a packet connection")
|
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
|
return err
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
laddr, _ := net.ResolveUDPAddr("udp", h.node.Addr)
|
var lc net.ListenConfig
|
||||||
pc, err = net.ListenUDP("udp", laddr)
|
packetConn, err = lc.ListenPacket(ctx, "udp", h.node.Addr)
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return h.transportTun(ctx, conn, pc, raddr)
|
return h.transportTun(ctx, tun, packetConn, remoteAddr)
|
||||||
}()
|
}()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debugf("[tun] %s: %v", conn.LocalAddr(), err)
|
log.Debugf("[tun] %s: %v", tun.LocalAddr(), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case <-h.chExit:
|
case <-h.chExit:
|
||||||
return
|
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
h.chExit <- struct{}{}
|
return
|
||||||
default:
|
default:
|
||||||
log.Debugf("next loop, err: %v", err)
|
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
|
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)
|
errChan := make(chan error, 2)
|
||||||
defer func() {
|
defer conn.Close()
|
||||||
if c, ok := conn.(interface{ CloseRead() error }); ok {
|
|
||||||
_ = c.CloseRead()
|
|
||||||
}
|
|
||||||
if c, ok := conn.(interface{ CloseWrite() error }); ok {
|
|
||||||
_ = c.CloseWrite()
|
|
||||||
}
|
|
||||||
_ = conn.Close()
|
|
||||||
}()
|
|
||||||
go func() {
|
go func() {
|
||||||
b := SPool.Get().([]byte)
|
b := SPool.Get().([]byte)
|
||||||
defer SPool.Put(b)
|
defer SPool.Put(b)
|
||||||
|
offset := 8
|
||||||
|
|
||||||
for ctx.Err() == nil {
|
for {
|
||||||
err := func() error {
|
err := func() error {
|
||||||
n, err := tun.Read(b[:])
|
n, err := tun.Read(b[offset:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
select {
|
select {
|
||||||
case h.chExit <- struct{}{}:
|
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.
|
// client side, deliver packet directly.
|
||||||
if raddr != nil {
|
if remoteAddr != nil {
|
||||||
_, err = conn.WriteTo(b[:n], raddr)
|
_, err = conn.WriteTo(b[:n], remoteAddr)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,25 +128,21 @@ func (h *tunHandler) transportTun(ctx context.Context, tun net.Conn, conn net.Pa
|
|||||||
if waterutil.IsIPv4(b[:n]) {
|
if waterutil.IsIPv4(b[:n]) {
|
||||||
header, err := ipv4.ParseHeader(b[:n])
|
header, err := ipv4.ParseHeader(b[:n])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debugf("[tun] %s: %v", tun.LocalAddr(), err)
|
log.Errorf("[tun] %s: %v", tun.LocalAddr(), err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if config.Debug {
|
|
||||||
log.Debugf("[tun] %s", header.String())
|
log.Debugf("[tun] %s", header.String())
|
||||||
}
|
|
||||||
src, dst = header.Src, header.Dst
|
src, dst = header.Src, header.Dst
|
||||||
} else if waterutil.IsIPv6(b[:n]) {
|
} else if waterutil.IsIPv6(b[:n]) {
|
||||||
header, err := ipv6.ParseHeader(b[:n])
|
header, err := ipv6.ParseHeader(b[:n])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debugf("[tun] %s: %v", tun.LocalAddr(), err)
|
log.Errorf("[tun] %s: %v", tun.LocalAddr(), err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if config.Debug {
|
|
||||||
log.Debugf("[tun] %s", header.String())
|
log.Debugf("[tun] %s", header.String())
|
||||||
}
|
|
||||||
src, dst = header.Src, header.Dst
|
src, dst = header.Src, header.Dst
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("[tun] unknown packet")
|
log.Errorf("[tun] unknown packet")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,15 +152,16 @@ func (h *tunHandler) transportTun(ctx context.Context, tun net.Conn, conn net.Pa
|
|||||||
return nil
|
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)
|
_, err = conn.WriteTo(b[:n], addr)
|
||||||
return err
|
return err
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errChan <- err
|
select {
|
||||||
|
case errChan <- err:
|
||||||
|
default:
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -201,15 +171,15 @@ func (h *tunHandler) transportTun(ctx context.Context, tun net.Conn, conn net.Pa
|
|||||||
b := LPool.Get().([]byte)
|
b := LPool.Get().([]byte)
|
||||||
defer LPool.Put(b)
|
defer LPool.Put(b)
|
||||||
|
|
||||||
for ctx.Err() == nil {
|
for {
|
||||||
err := func() error {
|
err := func() error {
|
||||||
n, addr, err := conn.ReadFrom(b[:])
|
n, srcAddr, err := conn.ReadFrom(b[:])
|
||||||
if err != nil && err != shadowaead.ErrShortPacket {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// client side, deliver packet to tun device.
|
// client side, deliver packet to tun device.
|
||||||
if raddr != nil {
|
if remoteAddr != nil {
|
||||||
_, err = tun.Write(b[:n])
|
_, err = tun.Write(b[:n])
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -218,42 +188,36 @@ func (h *tunHandler) transportTun(ctx context.Context, tun net.Conn, conn net.Pa
|
|||||||
if waterutil.IsIPv4(b[:n]) {
|
if waterutil.IsIPv4(b[:n]) {
|
||||||
header, err := ipv4.ParseHeader(b[:n])
|
header, err := ipv4.ParseHeader(b[:n])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debugf("[tun] %s: %v", tun.LocalAddr(), err)
|
log.Errorf("[tun] %s: %v", tun.LocalAddr(), err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if config.Debug {
|
|
||||||
log.Debugf("[tun] %s", header.String())
|
log.Debugf("[tun] %s", header.String())
|
||||||
}
|
|
||||||
src, dst = header.Src, header.Dst
|
src, dst = header.Src, header.Dst
|
||||||
} else if waterutil.IsIPv6(b[:n]) {
|
} else if waterutil.IsIPv6(b[:n]) {
|
||||||
header, err := ipv6.ParseHeader(b[:n])
|
header, err := ipv6.ParseHeader(b[:n])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debugf("[tun] %s: %v", tun.LocalAddr(), err)
|
log.Errorf("[tun] %s: %v", tun.LocalAddr(), err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if config.Debug {
|
|
||||||
log.Debugf("[tun] %s", header.String())
|
log.Debugf("[tun] %s", header.String())
|
||||||
}
|
|
||||||
src, dst = header.Src, header.Dst
|
src, dst = header.Src, header.Dst
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("[tun] unknown packet")
|
log.Errorf("[tun] unknown packet")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
routeKey := ipToTunRouteKey(src)
|
routeKey := ipToTunRouteKey(src)
|
||||||
if actual, loaded := h.routes.LoadOrStore(routeKey, addr); loaded {
|
if actual, loaded := h.routes.LoadOrStore(routeKey, srcAddr); loaded {
|
||||||
if actual.(net.Addr).String() != addr.String() {
|
if actual.(net.Addr).String() != srcAddr.String() {
|
||||||
log.Debugf("[tun] update route: %s -> %s (old %s)", src, addr, actual.(net.Addr))
|
log.Debugf("[tun] update route: %s -> %s (old %s)", src, srcAddr, actual.(net.Addr))
|
||||||
h.routes.Store(routeKey, addr)
|
h.routes.Store(routeKey, srcAddr)
|
||||||
}
|
}
|
||||||
} else {
|
} 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 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)
|
_, err = conn.WriteTo(b[:n], routeToAddr)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -269,7 +233,10 @@ func (h *tunHandler) transportTun(ctx context.Context, tun net.Conn, conn net.Pa
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
errChan <- err
|
select {
|
||||||
|
case errChan <- err:
|
||||||
|
default:
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/containernetworking/cni/pkg/types"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
@@ -30,7 +30,6 @@ import (
|
|||||||
"github.com/wencaiwulue/kubevpn/pkg/config"
|
"github.com/wencaiwulue/kubevpn/pkg/config"
|
||||||
"github.com/wencaiwulue/kubevpn/pkg/core"
|
"github.com/wencaiwulue/kubevpn/pkg/core"
|
||||||
"github.com/wencaiwulue/kubevpn/pkg/dns"
|
"github.com/wencaiwulue/kubevpn/pkg/dns"
|
||||||
"github.com/wencaiwulue/kubevpn/pkg/route"
|
|
||||||
"github.com/wencaiwulue/kubevpn/pkg/tun"
|
"github.com/wencaiwulue/kubevpn/pkg/tun"
|
||||||
"github.com/wencaiwulue/kubevpn/pkg/util"
|
"github.com/wencaiwulue/kubevpn/pkg/util"
|
||||||
)
|
)
|
||||||
@@ -133,7 +132,6 @@ func (c *ConnectOptions) DoConnect() (err error) {
|
|||||||
c.deleteFirewallRule(ctx)
|
c.deleteFirewallRule(ctx)
|
||||||
c.setupDNS()
|
c.setupDNS()
|
||||||
log.Info("dns service ok")
|
log.Info("dns service ok")
|
||||||
//c.detectConflictDevice()
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -144,7 +142,7 @@ func (c *ConnectOptions) portForward(ctx context.Context, port string) error {
|
|||||||
podInterface := c.clientset.CoreV1().Pods(c.Namespace)
|
podInterface := c.clientset.CoreV1().Pods(c.Namespace)
|
||||||
go func() {
|
go func() {
|
||||||
var first = pointer.Bool(true)
|
var first = pointer.Bool(true)
|
||||||
for ctx.Err() == nil {
|
for {
|
||||||
func() {
|
func() {
|
||||||
podList, err := c.GetRunningPodList()
|
podList, err := c.GetRunningPodList()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -261,7 +259,7 @@ func (c *ConnectOptions) startLocalTunServe(ctx context.Context, forwardAddress
|
|||||||
|
|
||||||
// Listen all pod, add route if needed
|
// Listen all pod, add route if needed
|
||||||
func (c *ConnectOptions) addRouteDynamic(ctx context.Context) {
|
func (c *ConnectOptions) addRouteDynamic(ctx context.Context) {
|
||||||
for ctx.Err() == nil {
|
for {
|
||||||
func() {
|
func() {
|
||||||
w, err := c.clientset.CoreV1().Pods(v1.NamespaceAll).Watch(ctx, metav1.ListOptions{Watch: true, TimeoutSeconds: pointer.Int64(30)})
|
w, err := c.clientset.CoreV1().Pods(v1.NamespaceAll).Watch(ctx, metav1.ListOptions{Watch: true, TimeoutSeconds: pointer.Int64(30)})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -299,7 +297,7 @@ func (c *ConnectOptions) addRouteDynamic(ctx context.Context) {
|
|||||||
return
|
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 {
|
if err != nil {
|
||||||
log.Debugf("[route] add route failed, pod: %s, ip: %s,err: %v", name, ip, err)
|
log.Debugf("[route] add route failed, pod: %s, ip: %s,err: %v", name, ip, err)
|
||||||
} else {
|
} else {
|
||||||
@@ -323,16 +321,6 @@ func (c *ConnectOptions) deleteFirewallRule(ctx context.Context) {
|
|||||||
go util.Heartbeats(ctx)
|
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() {
|
func (c *ConnectOptions) setupDNS() {
|
||||||
const port = 53
|
const port = 53
|
||||||
pod, err := c.GetRunningPodList()
|
pod, err := c.GetRunningPodList()
|
||||||
|
|||||||
@@ -148,7 +148,6 @@ func TestPatchAnnotation(t *testing.T) {
|
|||||||
|
|
||||||
func TestPing(t *testing.T) {
|
func TestPing(t *testing.T) {
|
||||||
ip := "10.233.98.197"
|
ip := "10.233.98.197"
|
||||||
ping, _ := Ping(ip)
|
|
||||||
pinger, err := probing.NewPinger(ip)
|
pinger, err := probing.NewPinger(ip)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@@ -159,5 +158,5 @@ func TestPing(t *testing.T) {
|
|||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
stats := pinger.Statistics() // get send/receive/duplicate/rtt stats
|
stats := pinger.Statistics() // get send/receive/duplicate/rtt stats
|
||||||
fmt.Println(ping)
|
fmt.Println(stats)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/containernetworking/cni/pkg/types"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/wencaiwulue/kubevpn/pkg/config"
|
"github.com/wencaiwulue/kubevpn/pkg/config"
|
||||||
@@ -12,6 +13,10 @@ import (
|
|||||||
"github.com/wencaiwulue/kubevpn/pkg/tun"
|
"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 {
|
type Route struct {
|
||||||
ServeNodes []string // -L tun
|
ServeNodes []string // -L tun
|
||||||
ChainNode string // -F tcp
|
ChainNode string // -F tcp
|
||||||
@@ -78,7 +83,7 @@ func (r *Route) GenerateServers() ([]core.Server, error) {
|
|||||||
return servers, nil
|
return servers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseIPRoutes(routeStringList string) (routes []tun.IPRoute) {
|
func parseIPRoutes(routeStringList string) (routes []types.Route) {
|
||||||
if len(routeStringList) == 0 {
|
if len(routeStringList) == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -86,7 +91,7 @@ func parseIPRoutes(routeStringList string) (routes []tun.IPRoute) {
|
|||||||
routeList := strings.Split(routeStringList, ",")
|
routeList := strings.Split(routeStringList, ",")
|
||||||
for _, route := range routeList {
|
for _, route := range routeList {
|
||||||
if _, ipNet, _ := net.ParseCIDR(strings.TrimSpace(route)); ipNet != nil {
|
if _, ipNet, _ := net.ParseCIDR(strings.TrimSpace(route)); ipNet != nil {
|
||||||
routes = append(routes, tun.IPRoute{Dest: ipNet})
|
routes = append(routes, types.Route{Dst: *ipNet})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -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()
|
|
||||||
}
|
|
||||||
@@ -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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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)
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/containernetworking/cni/pkg/types"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/songgao/water"
|
"github.com/songgao/water"
|
||||||
|
|
||||||
@@ -17,7 +18,7 @@ type Config struct {
|
|||||||
Name string
|
Name string
|
||||||
Addr string
|
Addr string
|
||||||
MTU int
|
MTU int
|
||||||
Routes []IPRoute
|
Routes []types.Route
|
||||||
Gateway string
|
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")}
|
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
|
// AddRoutes for outer called
|
||||||
func AddRoutes(routes ...IPRoute) error {
|
func AddRoutes(routes ...types.Route) error {
|
||||||
env := os.Getenv(config.EnvTunNameOrLUID)
|
env := os.Getenv(config.EnvTunNameOrLUID)
|
||||||
return addTunRoutes(env, routes...)
|
return addTunRoutes(env, routes...)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/containernetworking/cni/pkg/types"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/songgao/water"
|
"github.com/songgao/water"
|
||||||
|
|
||||||
@@ -61,16 +62,17 @@ func createTun(cfg Config) (conn net.Conn, itf *net.Interface, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func addTunRoutes(ifName string, routes ...IPRoute) error {
|
func addTunRoutes(ifName string, routes ...types.Route) error {
|
||||||
for _, route := range routes {
|
for _, route := range routes {
|
||||||
if route.Dest == nil {
|
if route.Dst.String() == "" {
|
||||||
continue
|
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)
|
log.Debugf("[tun] %s", cmd)
|
||||||
args := strings.Split(cmd, " ")
|
args := strings.Split(cmd, " ")
|
||||||
if er := exec.Command(args[0], args[1:]...).Run(); er != nil {
|
err := exec.Command(args[0], args[1:]...).Run()
|
||||||
return fmt.Errorf("%s: %v", cmd, er)
|
if err != nil {
|
||||||
|
return fmt.Errorf("%s: %v", cmd, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"github.com/containernetworking/cni/pkg/types"
|
||||||
"github.com/docker/libcontainer/netlink"
|
"github.com/docker/libcontainer/netlink"
|
||||||
"github.com/milosgajdos/tenus"
|
"github.com/milosgajdos/tenus"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
@@ -85,14 +86,14 @@ func createTun(cfg Config) (conn net.Conn, itf *net.Interface, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func addTunRoutes(ifName string, routes ...IPRoute) error {
|
func addTunRoutes(ifName string, routes ...types.Route) error {
|
||||||
for _, route := range routes {
|
for _, route := range routes {
|
||||||
if route.Dest == nil {
|
if route.Dst.String() == "" {
|
||||||
continue
|
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)
|
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)
|
return fmt.Errorf("%s: %v", cmd, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/containernetworking/cni/pkg/types"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/songgao/water"
|
"github.com/songgao/water"
|
||||||
|
|
||||||
@@ -61,12 +62,12 @@ func createTun(cfg Config) (conn net.Conn, itf *net.Interface, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func addTunRoutes(ifName string, routes ...IPRoute) error {
|
func addTunRoutes(ifName string, routes ...types.Route) error {
|
||||||
for _, route := range routes {
|
for _, route := range routes {
|
||||||
if route.Dest == nil {
|
if route.Dst.String() == "" {
|
||||||
continue
|
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)
|
log.Debugf("[tun] %s", cmd)
|
||||||
args := strings.Split(cmd, " ")
|
args := strings.Split(cmd, " ")
|
||||||
if er := exec.Command(args[0], args[1:]...).Run(); er != nil {
|
if er := exec.Command(args[0], args[1:]...).Run(); er != nil {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/containernetworking/cni/pkg/types"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"golang.org/x/sys/windows"
|
"golang.org/x/sys/windows"
|
||||||
wireguardtun "golang.zx2c4.com/wireguard/tun"
|
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
|
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)
|
parseUint, err := strconv.ParseUint(luid, 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@@ -66,21 +67,21 @@ func addTunRoutes(luid string, routes ...IPRoute) error {
|
|||||||
ifName := winipcfg.LUID(parseUint)
|
ifName := winipcfg.LUID(parseUint)
|
||||||
_ = ifName.FlushRoutes(windows.AF_INET)
|
_ = ifName.FlushRoutes(windows.AF_INET)
|
||||||
for _, route := range routes {
|
for _, route := range routes {
|
||||||
if route.Dest == nil {
|
if route.Dst.String() == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
var gw string
|
var gw string
|
||||||
if gw != "" {
|
if gw != "" {
|
||||||
route.Gateway = net.ParseIP(gw)
|
route.GW = net.ParseIP(gw)
|
||||||
} else {
|
} 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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var addr netip.Addr
|
var addr netip.Addr
|
||||||
addr, err = netip.ParseAddr(route.Gateway.String())
|
addr, err = netip.ParseAddr(route.GW.String())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user