Compare commits

...

12 Commits

Author SHA1 Message Date
naison
ef16641675 refactor: refactor code (#371) 2024-11-18 18:47:54 +08:00
naison
d9a9000d7b hotfix: fix can not ping itself tun IP on windows 2024-11-18 10:43:59 +00:00
naison
a1212f5144 feat: update krew index version to refs/tags/v2.3.1 (#370)
Co-authored-by: wencaiwulue <wencaiwulue@users.noreply.github.com>
2024-11-15 21:39:14 +08:00
kubenetworks
f4c22f3073 Update charts/index.yaml
Signed-off-by: kubenetworks <kubenetworks@users.noreply.github.com>
2024-11-15 13:36:37 +00:00
naison
2aa7812cb1 feat: use gvisor parse network packet in pod (#369) 2024-11-15 20:56:10 +08:00
naison
cad5d23d33 feat: update krew index version to refs/tags/v2.2.22 (#367)
Co-authored-by: wencaiwulue <wencaiwulue@users.noreply.github.com>
2024-10-30 16:52:55 +08:00
kubenetworks
85e8bd76d2 Update charts/index.yaml
Signed-off-by: kubenetworks <kubenetworks@users.noreply.github.com>
2024-10-30 08:46:09 +00:00
naison
a243842052 hotfix: fix port-forward retry bug (#366) 2024-10-30 10:30:48 +08:00
naison
6e052a5a0b feat: logs lines support '-' sign means starting log file lines (#365) 2024-10-30 09:10:20 +08:00
naison
f966cd29d7 feat: add number of lines to logs (#364) 2024-10-29 18:44:41 +08:00
naison
bfb7ac441d feat: update krew index version to refs/tags/v2.2.21 (#362)
Co-authored-by: wencaiwulue <wencaiwulue@users.noreply.github.com>
2024-10-25 22:41:23 +08:00
kubenetworks
0cc8b04bab Update charts/index.yaml
Signed-off-by: kubenetworks <kubenetworks@users.noreply.github.com>
2024-10-25 14:10:26 +00:00
37 changed files with 873 additions and 771 deletions

View File

@@ -1,6 +1,36 @@
apiVersion: v1
entries:
kubevpn:
- apiVersion: v2
appVersion: v2.3.1
created: "2024-11-15T13:36:37.056311943Z"
description: A Helm chart for KubeVPN
digest: 10c1200241309be4ec2eb88e9689ebbf96704c8fad270e6fda30047135aeccf2
name: kubevpn
type: application
urls:
- https://github.com/kubenetworks/kubevpn/releases/download/v2.3.1/kubevpn-2.3.1.tgz
version: 2.3.1
- apiVersion: v2
appVersion: v2.2.22
created: "2024-10-30T08:46:08.845218523Z"
description: A Helm chart for KubeVPN
digest: c2dc336383d7de2fb97cfd40a15e9f6c29a9a598484b88515a98bcaeb4925eda
name: kubevpn
type: application
urls:
- https://github.com/kubenetworks/kubevpn/releases/download/v2.2.22/kubevpn-2.2.22.tgz
version: 2.2.22
- apiVersion: v2
appVersion: v2.2.21
created: "2024-10-25T14:10:25.545716679Z"
description: A Helm chart for KubeVPN
digest: 98ae51247535525ff6a10b5f493d8bfc573af62759432f7aa54dd7eb6edeffd5
name: kubevpn
type: application
urls:
- https://github.com/kubenetworks/kubevpn/releases/download/v2.2.21/kubevpn-2.2.21.tgz
version: 2.2.21
- apiVersion: v2
appVersion: v2.2.20
created: "2024-10-20T04:00:07.263734809Z"
@@ -191,4 +221,4 @@ entries:
urls:
- https://github.com/kubenetworks/kubevpn/releases/download/v2.2.2/kubevpn-2.2.2.tgz
version: 2.2.2
generated: "2024-10-20T04:00:07.263848192Z"
generated: "2024-11-15T13:36:37.056473796Z"

View File

@@ -74,10 +74,6 @@ func CmdClone(f cmdutil.Factory) *cobra.Command {
kubevpn clone service/productpage --ssh-addr <HOST:PORT> --ssh-username <USERNAME> --gssapi-password <PASSWORD>
`)),
PreRunE: func(cmd *cobra.Command, args []string) (err error) {
// not support temporally
if options.Engine == config.EngineGvisor {
return fmt.Errorf(`not support type engine: %s, support ("%s"|"%s")`, config.EngineGvisor, config.EngineMix, config.EngineRaw)
}
util.InitLoggerForClient(false)
// startup daemon process and sudo process
return daemon.StartupDaemon(cmd.Context())
@@ -164,7 +160,7 @@ func CmdClone(f cmdutil.Factory) *cobra.Command {
cmd.Flags().BoolVar(&config.Debug, "debug", false, "Enable debug mode or not, true or false")
cmd.Flags().StringVar(&config.Image, "image", config.Image, "Use this image to startup container")
cmd.Flags().BoolVar(&transferImage, "transfer-image", false, "transfer image to remote registry, it will transfer image "+config.OriginImage+" to flags `--image` special image, default: "+config.Image)
cmd.Flags().StringVar((*string)(&options.Engine), "engine", string(config.EngineRaw), fmt.Sprintf(`transport engine ("%s"|"%s") %s: use gvisor and raw both (both performance and stable), %s: use raw mode (best stable)`, config.EngineMix, config.EngineRaw, config.EngineMix, config.EngineRaw))
cmd.Flags().StringVar((*string)(&options.Engine), "netstack", string(config.EngineSystem), fmt.Sprintf(`network stack ("%s"|"%s") %s: use gvisor (both performance and stable), %s: use raw mode (best stable)`, config.EngineGvisor, config.EngineSystem, config.EngineGvisor, config.EngineSystem))
cmd.Flags().StringVar(&options.TargetImage, "target-image", "", "Clone container use this image to startup container, if not special, use origin image")
cmd.Flags().StringVar(&options.TargetContainer, "target-container", "", "Clone container use special image to startup this container, if not special, use origin image")

View File

@@ -68,10 +68,6 @@ func CmdConnect(f cmdutil.Factory) *cobra.Command {
if err != nil {
return err
}
// not support temporally
if connect.Engine == config.EngineGvisor {
return fmt.Errorf(`not support type engine: %s, support ("%s"|"%s")`, config.EngineGvisor, config.EngineMix, config.EngineRaw)
}
return nil
},
RunE: func(cmd *cobra.Command, args []string) error {
@@ -166,7 +162,7 @@ func CmdConnect(f cmdutil.Factory) *cobra.Command {
cmd.Flags().BoolVar(&config.Debug, "debug", false, "enable debug mode or not, true or false")
cmd.Flags().StringVar(&config.Image, "image", config.Image, "use this image to startup container")
cmd.Flags().BoolVar(&transferImage, "transfer-image", false, "transfer image to remote registry, it will transfer image "+config.OriginImage+" to flags `--image` special image, default: "+config.Image)
cmd.Flags().StringVar((*string)(&connect.Engine), "engine", string(config.EngineRaw), fmt.Sprintf(`transport engine ("%s"|"%s") %s: use gvisor and raw both (both performance and stable), %s: use raw mode (best stable)`, config.EngineMix, config.EngineRaw, config.EngineMix, config.EngineRaw))
cmd.Flags().StringVar((*string)(&connect.Engine), "netstack", string(config.EngineSystem), fmt.Sprintf(`network stack ("%s"|"%s") %s: use gvisor (both performance and stable), %s: use raw mode (best stable)`, config.EngineGvisor, config.EngineSystem, config.EngineGvisor, config.EngineSystem))
cmd.Flags().BoolVar(&foreground, "foreground", false, "Hang up")
cmd.Flags().BoolVar(&lite, "lite", false, "connect to multiple cluster in lite mode. mode \"lite\": design for only connecting to multiple cluster network. mode \"full\": not only connect to cluster network, it also supports proxy workloads inbound traffic to local PC.")

View File

@@ -32,7 +32,7 @@ func CmdControlPlane(_ cmdutil.Factory) *cobra.Command {
`)),
RunE: func(cmd *cobra.Command, args []string) error {
util.InitLoggerForServer(config.Debug)
go util.StartupPProf(0)
go util.StartupPProfForServer(0)
go func(ctx context.Context) {
conf, err := miekgdns.ClientConfigFromFile(resolvconf.Path())
if err != nil {

View File

@@ -88,10 +88,6 @@ func CmdDev(f cmdutil.Factory) *cobra.Command {
return err
}
util.InitLoggerForClient(config.Debug)
// not support temporally
if options.Engine == config.EngineGvisor {
return fmt.Errorf(`not support type engine: %s, support ("%s"|"%s")`, config.EngineGvisor, config.EngineMix, config.EngineRaw)
}
if p := options.RunOptions.Platform; p != "" {
if _, err = platforms.Parse(p); err != nil {
@@ -144,7 +140,7 @@ func CmdDev(f cmdutil.Factory) *cobra.Command {
cmdutil.CheckErr(cmd.RegisterFlagCompletionFunc("container", completion.ContainerCompletionFunc(f)))
cmd.Flags().StringVar((*string)(&options.ConnectMode), "connect-mode", string(dev.ConnectModeHost), "Connect to kubernetes network in container or in host, eg: ["+string(dev.ConnectModeContainer)+"|"+string(dev.ConnectModeHost)+"]")
cmd.Flags().BoolVar(&transferImage, "transfer-image", false, "transfer image to remote registry, it will transfer image "+config.OriginImage+" to flags `--image` special image, default: "+config.Image)
cmd.Flags().StringVar((*string)(&options.Engine), "engine", string(config.EngineRaw), fmt.Sprintf(`transport engine ("%s"|"%s") %s: use gvisor and raw both (both performance and stable), %s: use raw mode (best stable)`, config.EngineMix, config.EngineRaw, config.EngineMix, config.EngineRaw))
cmd.Flags().StringVar((*string)(&options.Engine), "netstack", string(config.EngineSystem), fmt.Sprintf(`network stack ("%s"|"%s") %s: use gvisor (both performance and stable), %s: use raw mode (best stable)`, config.EngineGvisor, config.EngineSystem, config.EngineGvisor, config.EngineSystem))
// diy docker options
cmd.Flags().StringVar(&options.DevImage, "dev-image", "", "Use to startup docker container, Default is pod image")

View File

@@ -58,5 +58,6 @@ func CmdLogs(f cmdutil.Factory) *cobra.Command {
},
}
cmd.Flags().BoolVarP(&req.Follow, "follow", "f", false, "Specify if the logs should be streamed.")
cmd.Flags().Int32VarP(&req.Lines, "number", "N", 10, "Lines of recent log file to display.")
return cmd
}

View File

@@ -91,10 +91,6 @@ func CmdProxy(f cmdutil.Factory) *cobra.Command {
if err = daemon.StartupDaemon(cmd.Context()); err != nil {
return err
}
// not support temporally
if connect.Engine == config.EngineGvisor {
return fmt.Errorf(`not support type engine: %s, support ("%s"|"%s")`, config.EngineGvisor, config.EngineMix, config.EngineRaw)
}
return err
},
RunE: func(cmd *cobra.Command, args []string) error {
@@ -186,7 +182,7 @@ func CmdProxy(f cmdutil.Factory) *cobra.Command {
cmd.Flags().BoolVar(&config.Debug, "debug", false, "Enable debug mode or not, true or false")
cmd.Flags().StringVar(&config.Image, "image", config.Image, "Use this image to startup container")
cmd.Flags().BoolVar(&transferImage, "transfer-image", false, "transfer image to remote registry, it will transfer image "+config.OriginImage+" to flags `--image` special image, default: "+config.Image)
cmd.Flags().StringVar((*string)(&connect.Engine), "engine", string(config.EngineRaw), fmt.Sprintf(`transport engine ("%s"|"%s") %s: use gvisor and raw both (both performance and stable), %s: use raw mode (best stable)`, config.EngineMix, config.EngineRaw, config.EngineMix, config.EngineRaw))
cmd.Flags().StringVar((*string)(&connect.Engine), "netstack", string(config.EngineSystem), fmt.Sprintf(`network stack ("%s"|"%s") %s: use gvisor (both performance and stable), %s: use raw mode (best stable)`, config.EngineGvisor, config.EngineSystem, config.EngineGvisor, config.EngineSystem))
cmd.Flags().BoolVar(&foreground, "foreground", false, "foreground hang up")
handler.AddExtraRoute(cmd.Flags(), extraRoute)

View File

@@ -34,7 +34,7 @@ func CmdServe(_ cmdutil.Factory) *cobra.Command {
PreRun: func(*cobra.Command, []string) {
util.InitLoggerForServer(config.Debug)
runtime.GOMAXPROCS(0)
go util.StartupPProf(0)
go util.StartupPProfForServer(6060)
},
RunE: func(cmd *cobra.Command, args []string) error {
rand.Seed(time.Now().UnixNano())

View File

@@ -18,7 +18,7 @@ func CmdSyncthing(_ cmdutil.Factory) *cobra.Command {
Short: i18n.T("Syncthing"),
Long: templates.LongDesc(i18n.T(`Syncthing`)),
RunE: func(cmd *cobra.Command, args []string) (err error) {
go util.StartupPProf(0)
go util.StartupPProfForServer(0)
return syncthing.StartServer(cmd.Context(), detach, dir)
},
Hidden: true,

View File

@@ -23,7 +23,7 @@ func CmdWebhook(f cmdutil.Factory) *cobra.Command {
Args: cobra.MaximumNArgs(0),
PreRun: func(cmd *cobra.Command, args []string) {
util.InitLoggerForServer(true)
go util.StartupPProf(0)
go util.StartupPProfForServer(0)
},
RunE: func(cmd *cobra.Command, args []string) error {
return webhook.Main(f)

View File

@@ -169,8 +169,7 @@ type Engine string
const (
EngineGvisor Engine = "gvisor"
EngineMix Engine = "mix"
EngineRaw Engine = "raw"
EngineSystem Engine = "system"
)
const Slogan = "Now you can access resources in the kubernetes cluster !"

View File

@@ -0,0 +1,27 @@
package core
import (
"context"
log "github.com/sirupsen/logrus"
"gvisor.dev/gvisor/pkg/tcpip/stack"
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
)
func ICMPForwarder(s *stack.Stack, ctx context.Context) func(stack.TransportEndpointID, *stack.PacketBuffer) bool {
return func(id stack.TransportEndpointID, buffer *stack.PacketBuffer) bool {
log.Debugf("[TUN-ICMP] LocalPort: %d, LocalAddress: %s, RemotePort: %d, RemoteAddress %s",
id.LocalPort, id.LocalAddress.String(), id.RemotePort, id.RemoteAddress.String(),
)
ctx1, cancelFunc := context.WithCancel(ctx)
defer cancelFunc()
ok, err := util.PingOnce(ctx1, id.RemoteAddress.String(), id.LocalAddress.String())
if err != nil {
log.Debugf("[TUN-ICMP] Failed to ping dst %s from src %s",
id.LocalAddress.String(), id.RemoteAddress.String(),
)
}
return ok
}
}

View File

@@ -16,6 +16,7 @@ import (
)
func NewStack(ctx context.Context, tun stack.LinkEndpoint) *stack.Stack {
nicID := tcpip.NICID(1)
s := stack.New(stack.Options{
NetworkProtocols: []stack.NetworkProtocolFactory{
ipv4.NewProtocol,
@@ -33,26 +34,28 @@ func NewStack(ctx context.Context, tun stack.LinkEndpoint) *stack.Stack {
RawFactory: raw.EndpointFactory{},
})
// set handler for TCP UDP ICMP
s.SetTransportProtocolHandler(tcp.ProtocolNumber, TCPForwarder(s))
s.SetTransportProtocolHandler(udp.ProtocolNumber, UDPForwarder(s))
s.SetTransportProtocolHandler(tcp.ProtocolNumber, TCPForwarder(s, ctx))
s.SetTransportProtocolHandler(udp.ProtocolNumber, UDPForwarder(s, ctx))
s.SetTransportProtocolHandler(header.ICMPv4ProtocolNumber, ICMPForwarder(s, ctx))
s.SetTransportProtocolHandler(header.ICMPv6ProtocolNumber, ICMPForwarder(s, ctx))
s.SetRouteTable([]tcpip.Route{
{
Destination: header.IPv4EmptySubnet,
NIC: 1,
NIC: nicID,
},
{
Destination: header.IPv6EmptySubnet,
NIC: 1,
NIC: nicID,
},
})
s.CreateNICWithOptions(1, packetsocket.New(tun), stack.NICOptions{
s.CreateNICWithOptions(nicID, packetsocket.New(tun), stack.NICOptions{
Disabled: false,
Context: ctx,
})
s.SetPromiscuousMode(1, true)
s.SetSpoofing(1, true)
s.SetPromiscuousMode(nicID, true)
s.SetSpoofing(nicID, true)
// Enable SACK Recovery.
{

View File

@@ -5,8 +5,10 @@ import (
"context"
"encoding/binary"
"errors"
"fmt"
"io"
"net"
"time"
log "github.com/sirupsen/logrus"
"gvisor.dev/gvisor/pkg/tcpip"
@@ -18,10 +20,7 @@ import (
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
)
var GvisorTCPForwardAddr string
func TCPForwarder(s *stack.Stack) func(stack.TransportEndpointID, *stack.PacketBuffer) bool {
GvisorTCPForwardAddr := GvisorTCPForwardAddr
func TCPForwarder(s *stack.Stack, ctx context.Context) func(stack.TransportEndpointID, *stack.PacketBuffer) bool {
return tcp.NewForwarder(s, 0, 100000, func(request *tcp.ForwarderRequest) {
defer request.Complete(false)
id := request.ID()
@@ -29,24 +28,14 @@ func TCPForwarder(s *stack.Stack) func(stack.TransportEndpointID, *stack.PacketB
id.LocalPort, id.LocalAddress.String(), id.RemotePort, id.RemoteAddress.String(),
)
node, err := ParseNode(GvisorTCPForwardAddr)
// 2, dial proxy
host := id.LocalAddress.String()
port := fmt.Sprintf("%d", id.LocalPort)
var remote net.Conn
var d = net.Dialer{Timeout: time.Second * 5}
remote, err := d.DialContext(ctx, "tcp", net.JoinHostPort(host, port))
if err != nil {
log.Errorf("[TUN-TCP] Failed to parse gvisor tcp forward addr %s: %v", GvisorTCPForwardAddr, err)
return
}
node.Client = &Client{
Connector: GvisorTCPTunnelConnector(),
Transporter: TCPTransporter(),
}
forwardChain := NewChain(5, node)
remote, err := forwardChain.dial(context.Background())
if err != nil {
log.Debugf("[TUN-TCP] Failed to dial remote conn: %v", err)
return
}
if err = WriteProxyInfo(remote, id); err != nil {
log.Debugf("[TUN-TCP] Failed to write proxy info: %v", err)
log.Errorf("[TUN-TCP] Failed to connect addr %s: %v", net.JoinHostPort(host, port), err)
return
}

View File

@@ -2,94 +2,62 @@ package core
import (
"context"
"errors"
"fmt"
"io"
"net"
"time"
"sync"
log "github.com/sirupsen/logrus"
"gvisor.dev/gvisor/pkg/tcpip"
"gvisor.dev/gvisor/pkg/tcpip/link/channel"
"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
)
type gvisorTCPTunnelConnector struct {
type gvisorTCPHandler struct {
// map[srcIP]net.Conn
routeMapTCP *sync.Map
packetChan chan *datagramPacket
}
func GvisorTCPTunnelConnector() Connector {
return &gvisorTCPTunnelConnector{}
}
func (c *gvisorTCPTunnelConnector) ConnectContext(ctx context.Context, conn net.Conn) (net.Conn, error) {
switch con := conn.(type) {
case *net.TCPConn:
err := con.SetNoDelay(true)
if err != nil {
return nil, err
}
err = con.SetKeepAlive(true)
if err != nil {
return nil, err
}
err = con.SetKeepAlivePeriod(15 * time.Second)
if err != nil {
return nil, err
}
}
return conn, nil
}
type gvisorTCPHandler struct{}
func GvisorTCPHandler() Handler {
return &gvisorTCPHandler{}
return &gvisorTCPHandler{
routeMapTCP: RouteMapTCP,
packetChan: TCPPacketChan,
}
}
func (h *gvisorTCPHandler) Handle(ctx context.Context, tcpConn net.Conn) {
defer tcpConn.Close()
log.Debugf("[TUN-TCP] %s -> %s", tcpConn.RemoteAddr(), tcpConn.LocalAddr())
// 1, get proxy info
endpointID, err := ParseProxyInfo(tcpConn)
if err != nil {
log.Errorf("[TUN-TCP] Failed to parse proxy info: %v", err)
return
}
log.Debugf("[TUN-TCP] LocalPort: %d, LocalAddress: %s, RemotePort: %d, RemoteAddress %s",
endpointID.LocalPort, endpointID.LocalAddress.String(), endpointID.RemotePort, endpointID.RemoteAddress.String(),
)
// 2, dial proxy
host := endpointID.LocalAddress.String()
port := fmt.Sprintf("%d", endpointID.LocalPort)
var remote net.Conn
remote, err = net.DialTimeout("tcp", net.JoinHostPort(host, port), time.Second*5)
if err != nil {
log.Errorf("[TUN-TCP] Failed to connect addr %s: %v", net.JoinHostPort(host, port), err)
return
}
cancel, cancelFunc := context.WithCancel(ctx)
defer cancelFunc()
log.Debugf("[TCP] %s -> %s", tcpConn.RemoteAddr(), tcpConn.LocalAddr())
h.handle(cancel, tcpConn)
}
func (h *gvisorTCPHandler) handle(ctx context.Context, tcpConn net.Conn) {
endpoint := channel.New(tcp.DefaultReceiveBufferSize, uint32(config.DefaultMTU), tcpip.GetRandMacAddr())
errChan := make(chan error, 2)
go func() {
i := config.LPool.Get().([]byte)[:]
defer config.LPool.Put(i[:])
written, err2 := io.CopyBuffer(remote, tcpConn, i)
log.Debugf("[TUN-TCP] Write length %d data to remote", written)
errChan <- err2
h.readFromTCPConnWriteToEndpoint(ctx, tcpConn, endpoint)
util.SafeClose(errChan)
}()
go func() {
i := config.LPool.Get().([]byte)[:]
defer config.LPool.Put(i[:])
written, err2 := io.CopyBuffer(tcpConn, remote, i)
log.Debugf("[TUN-TCP] Read length %d data from remote", written)
errChan <- err2
h.readFromEndpointWriteToTCPConn(ctx, tcpConn, endpoint)
util.SafeClose(errChan)
}()
err = <-errChan
if err != nil && !errors.Is(err, io.EOF) {
log.Debugf("[TUN-TCP] Disconnect: %s >-<: %s: %v", tcpConn.LocalAddr(), remote.RemoteAddr(), err)
stack := NewStack(ctx, endpoint)
defer stack.Destroy()
select {
case <-errChan:
return
case <-ctx.Done():
return
}
}
func GvisorTCPListener(addr string) (net.Listener, error) {
log.Debugf("Gvisor tcp listen addr %s", addr)
log.Debugf("Gvisor TCP listening addr: %s", addr)
laddr, err := net.ResolveTCPAddr("tcp", addr)
if err != nil {
return nil, err

View File

@@ -3,6 +3,7 @@ package core
import (
"context"
"errors"
"io"
"net"
"os"
@@ -15,112 +16,26 @@ import (
"gvisor.dev/gvisor/pkg/tcpip/header"
"gvisor.dev/gvisor/pkg/tcpip/link/channel"
"gvisor.dev/gvisor/pkg/tcpip/stack"
"gvisor.dev/gvisor/pkg/tcpip/transport/tcp"
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
)
func NewTunEndpoint(ctx context.Context, tun net.Conn, mtu uint32, engine config.Engine, in chan<- *DataElem, out chan *DataElem) stack.LinkEndpoint {
addr, _ := tcpip.ParseMACAddress("02:03:03:04:05:06")
endpoint := channel.New(tcp.DefaultReceiveBufferSize, mtu, addr)
func (h *gvisorTCPHandler) readFromEndpointWriteToTCPConn(ctx context.Context, conn net.Conn, endpoint *channel.Endpoint) {
tcpConn, _ := newGvisorFakeUDPTunnelConnOverTCP(ctx, conn)
for {
select {
case <-ctx.Done():
return
default:
}
go func() {
for {
select {
case <-ctx.Done():
return
default:
}
read := endpoint.ReadContext(ctx)
if read != nil {
bb := read.ToView().AsSlice()
i := config.LPool.Get().([]byte)[:]
n := copy(i, bb)
bb = nil
util.SafeWrite(out, NewDataElem(i[:], n, nil, nil))
}
}
}()
// tun --> dispatcher
go func() {
// full(all use gvisor), mix(cluster network use gvisor), raw(not use gvisor)
for {
bytes := config.LPool.Get().([]byte)[:]
read, err := tun.Read(bytes[:])
pktBuffer := endpoint.ReadContext(ctx)
if pktBuffer != nil {
buf := pktBuffer.ToView().AsSlice()
_, err := tcpConn.Write(buf)
if err != nil {
if errors.Is(err, os.ErrClosed) {
return
}
// if context is done
if ctx.Err() != nil {
log.Errorf("[TUN] Failed to read from tun: %v, context is done", err)
return
}
log.Errorf("[TUN] Failed to read from tun: %v", err)
continue
}
if read == 0 {
log.Warnf("[TUN] Read from tun length is %d", read)
continue
}
// Try to determine network protocol number, default zero.
var protocol tcpip.NetworkProtocolNumber
var ipProtocol int
var src, dst net.IP
// TUN interface with IFF_NO_PI enabled, thus
// we need to determine protocol from version field
version := bytes[0] >> 4
if version == 4 {
protocol = header.IPv4ProtocolNumber
ipHeader, err := ipv4.ParseHeader(bytes[:read])
if err != nil {
log.Errorf("Failed to parse IPv4 header: %v", err)
continue
}
ipProtocol = ipHeader.Protocol
src = ipHeader.Src
dst = ipHeader.Dst
} else if version == 6 {
protocol = header.IPv6ProtocolNumber
ipHeader, err := ipv6.ParseHeader(bytes[:read])
if err != nil {
log.Errorf("Failed to parse IPv6 header: %s", err.Error())
continue
}
ipProtocol = ipHeader.NextHeader
src = ipHeader.Src
dst = ipHeader.Dst
} else {
log.Debugf("[TUN-GVISOR] Unknown packet version %d", version)
continue
}
// only tcp and udp needs to distinguish transport engine
// gvisor: all network use gvisor
// mix: cluster network use gvisor, diy network use raw
// raw: all network use raw
if (ipProtocol == int(layers.IPProtocolUDP) || ipProtocol == int(layers.IPProtocolUDPLite) || ipProtocol == int(layers.IPProtocolTCP)) &&
(engine == config.EngineGvisor || (engine == config.EngineMix && (!config.CIDR.Contains(dst) && !config.CIDR6.Contains(dst)))) {
pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
ReserveHeaderBytes: 0,
Payload: buffer.MakeWithData(bytes[:read]),
})
//defer pkt.DecRef()
config.LPool.Put(bytes[:])
endpoint.InjectInbound(protocol, pkt)
log.Tracef("[TUN-%s] IP-Protocol: %s, SRC: %s, DST: %s, Length: %d", layers.IPProtocol(ipProtocol).String(), layers.IPProtocol(ipProtocol).String(), src.String(), dst, read)
} else {
log.Tracef("[TUN-RAW] IP-Protocol: %s, SRC: %s, DST: %s, Length: %d", layers.IPProtocol(ipProtocol).String(), src.String(), dst, read)
util.SafeWrite(in, NewDataElem(bytes[:], read, src, dst))
}
}
}()
go func() {
for elem := range out {
_, err := tun.Write(elem.Data()[:elem.Length()])
config.LPool.Put(elem.Data()[:])
if err != nil {
if errors.Is(err, os.ErrClosed) {
if errors.Is(err, os.ErrClosed) || errors.Is(err, io.EOF) {
return
}
// if context is done
@@ -129,9 +44,99 @@ func NewTunEndpoint(ctx context.Context, tun net.Conn, mtu uint32, engine config
return
}
log.Errorf("[TUN] Failed to write data to tun device: %v", err)
continue
}
}
}()
return endpoint
}
}
// tun --> dispatcher
func (h *gvisorTCPHandler) readFromTCPConnWriteToEndpoint(ctx context.Context, conn net.Conn, endpoint *channel.Endpoint) {
tcpConn, _ := newGvisorFakeUDPTunnelConnOverTCP(ctx, conn)
for {
bytes := config.LPool.Get().([]byte)[:]
read, err := tcpConn.Read(bytes[:])
if err != nil {
if errors.Is(err, os.ErrClosed) || errors.Is(err, io.EOF) {
return
}
// if context is done
if ctx.Err() != nil {
log.Errorf("[TUN] Failed to read from tun: %v, context is done", err)
return
}
log.Errorf("[TUN] Failed to read from tcp conn: %v", err)
config.LPool.Put(bytes[:])
continue
}
if read == 0 {
log.Warnf("[TUN] Read from tcp conn length is %d", read)
config.LPool.Put(bytes[:])
continue
}
// Try to determine network protocol number, default zero.
var protocol tcpip.NetworkProtocolNumber
var ipProtocol int
var src, dst net.IP
// TUN interface with IFF_NO_PI enabled, thus
// we need to determine protocol from version field
if util.IsIPv4(bytes) {
protocol = header.IPv4ProtocolNumber
ipHeader, err := ipv4.ParseHeader(bytes[:read])
if err != nil {
log.Errorf("Failed to parse IPv4 header: %v", err)
config.LPool.Put(bytes[:])
continue
}
ipProtocol = ipHeader.Protocol
src = ipHeader.Src
dst = ipHeader.Dst
} else if util.IsIPv6(bytes) {
protocol = header.IPv6ProtocolNumber
ipHeader, err := ipv6.ParseHeader(bytes[:read])
if err != nil {
log.Errorf("Failed to parse IPv6 header: %s", err.Error())
config.LPool.Put(bytes[:])
continue
}
ipProtocol = ipHeader.NextHeader
src = ipHeader.Src
dst = ipHeader.Dst
} else {
log.Debugf("[TUN-GVISOR] Unknown packet")
config.LPool.Put(bytes[:])
continue
}
h.addRoute(src, conn)
// inner ip like 223.254.0.100/102/103 connect each other
if config.CIDR.Contains(dst) || config.CIDR6.Contains(dst) {
log.Tracef("[TUN-RAW] Forward to TUN device, SRC: %s, DST: %s, Length: %d", src.String(), dst.String(), read)
util.SafeWrite(h.packetChan, &datagramPacket{
DataLength: uint16(read),
Data: bytes[:],
})
continue
}
pkt := stack.NewPacketBuffer(stack.PacketBufferOptions{
ReserveHeaderBytes: 0,
Payload: buffer.MakeWithData(bytes[:read]),
})
//defer pkt.DecRef()
config.LPool.Put(bytes[:])
endpoint.InjectInbound(protocol, pkt)
log.Tracef("[TUN-%s] Write to Gvisor IP-Protocol: %s, SRC: %s, DST: %s, Length: %d", layers.IPProtocol(ipProtocol).String(), layers.IPProtocol(ipProtocol).String(), src.String(), dst, read)
}
}
func (h *gvisorTCPHandler) addRoute(src net.IP, tcpConn net.Conn) {
value, loaded := h.routeMapTCP.LoadOrStore(src.String(), tcpConn)
if loaded {
if tcpConn != value.(net.Conn) {
h.routeMapTCP.Store(src.String(), tcpConn)
log.Debugf("[TCP] Replace route map TCP: %s -> %s-%s", src, tcpConn.LocalAddr(), tcpConn.RemoteAddr())
}
} else {
log.Debugf("[TCP] Add new route map TCP: %s -> %s-%s", src, tcpConn.LocalAddr(), tcpConn.RemoteAddr())
}
}

View File

@@ -4,6 +4,7 @@ import (
"context"
"errors"
"io"
"net"
log "github.com/sirupsen/logrus"
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
@@ -14,10 +15,7 @@ import (
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
)
var GvisorUDPForwardAddr string
func UDPForwarder(s *stack.Stack) func(id stack.TransportEndpointID, pkt *stack.PacketBuffer) bool {
GvisorUDPForwardAddr := GvisorUDPForwardAddr
func UDPForwarder(s *stack.Stack, ctx context.Context) func(id stack.TransportEndpointID, pkt *stack.PacketBuffer) bool {
return udp.NewForwarder(s, func(request *udp.ForwarderRequest) {
endpointID := request.ID()
log.Debugf("[TUN-UDP] LocalPort: %d, LocalAddress: %s, RemotePort: %d, RemoteAddress %s",
@@ -30,30 +28,14 @@ func UDPForwarder(s *stack.Stack) func(id stack.TransportEndpointID, pkt *stack.
return
}
node, err := ParseNode(GvisorUDPForwardAddr)
// 2, dial proxy
addr := &net.UDPAddr{
IP: endpointID.LocalAddress.AsSlice(),
Port: int(endpointID.LocalPort),
}
remote, err := net.DialUDP("udp", nil, addr)
if err != nil {
log.Debugf("[TUN-UDP] Failed to parse gviosr udp forward addr %s: %v", GvisorUDPForwardAddr, err)
return
}
node.Client = &Client{
Connector: GvisorUDPOverTCPTunnelConnector(endpointID),
Transporter: TCPTransporter(),
}
forwardChain := NewChain(5, node)
ctx := context.Background()
c, err := forwardChain.getConn(ctx)
if err != nil {
log.Debugf("[TUN-UDP] Failed to get conn: %v", err)
return
}
if err = WriteProxyInfo(c, endpointID); err != nil {
log.Debugf("[TUN-UDP] Failed to write proxy info: %v", err)
return
}
remote, err := node.Client.ConnectContext(ctx, c)
if err != nil {
log.Debugf("[TUN-UDP] Failed to connect: %v", err)
log.Errorf("[TUN-UDP] Failed to connect addr %s: %v", addr.String(), err)
return
}
conn := gonet.NewUDPConn(w, endpoint)

View File

@@ -7,40 +7,9 @@ import (
"time"
log "github.com/sirupsen/logrus"
"gvisor.dev/gvisor/pkg/tcpip/stack"
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
)
type gvisorUDPOverTCPTunnelConnector struct {
Id stack.TransportEndpointID
}
func GvisorUDPOverTCPTunnelConnector(endpointID stack.TransportEndpointID) Connector {
return &gvisorUDPOverTCPTunnelConnector{
Id: endpointID,
}
}
func (c *gvisorUDPOverTCPTunnelConnector) ConnectContext(ctx context.Context, conn net.Conn) (net.Conn, error) {
switch con := conn.(type) {
case *net.TCPConn:
err := con.SetNoDelay(true)
if err != nil {
return nil, err
}
err = con.SetKeepAlive(true)
if err != nil {
return nil, err
}
err = con.SetKeepAlivePeriod(15 * time.Second)
if err != nil {
return nil, err
}
}
return newGvisorFakeUDPTunnelConnOverTCP(ctx, conn)
}
type gvisorUDPHandler struct{}
func GvisorUDPHandler() Handler {
@@ -116,7 +85,7 @@ func (c *gvisorFakeUDPTunnelConn) Close() error {
}
func GvisorUDPListener(addr string) (net.Listener, error) {
log.Debugf("Gvisor UDP over TCP listen addr %s", addr)
log.Debugf("Gvisor UDP over TCP listening addr: %s", addr)
laddr, err := net.ResolveTCPAddr("tcp", addr)
if err != nil {
return nil, err

View File

@@ -86,12 +86,8 @@ func (h *fakeUdpHandler) Handle(ctx context.Context, tcpConn net.Conn) {
}
var src net.IP
bb := dgram.Data[:dgram.DataLength]
if util.IsIPv4(bb) {
src = net.IPv4(bb[12], bb[13], bb[14], bb[15])
} else if util.IsIPv6(bb) {
src = bb[8:24]
} else {
src, _, err = util.ParseIP(dgram.Data[:dgram.DataLength])
if err != nil {
log.Errorf("[TCP] Unknown packet")
continue
}

View File

@@ -2,15 +2,10 @@ package core
import (
"context"
"fmt"
"math"
"math/rand"
"net"
"sync"
"time"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
log "github.com/sirupsen/logrus"
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
@@ -62,14 +57,6 @@ func (n *RouteMap) RouteTo(ip net.IP) net.Addr {
return n.routes[ip.String()]
}
func (n *RouteMap) Range(f func(key string, value net.Addr)) {
n.lock.RLock()
defer n.lock.RUnlock()
for k, v := range n.routes {
f(k, v)
}
}
// TunHandler creates a handler for tun tunnel.
func TunHandler(chain *Chain, node *Node) Handler {
return &tunHandler{
@@ -89,25 +76,11 @@ func (h *tunHandler) Handle(ctx context.Context, tun net.Conn) {
}
}
func (h *tunHandler) printRoute(ctx context.Context) {
ticker := time.NewTicker(time.Second * 5)
defer ticker.Stop()
for ctx.Err() == nil {
select {
case <-ticker.C:
h.routeMapUDP.Range(func(key string, value net.Addr) {
log.Debugf("To: %s, route: %s", key, value.String())
})
}
}
}
type Device struct {
tun net.Conn
tunInboundRaw chan *DataElem
tunInbound chan *DataElem
tunOutbound chan *DataElem
tunInbound chan *DataElem
tunOutbound chan *DataElem
// your main logic
tunInboundHandler func(tunInbound <-chan *DataElem, tunOutbound chan<- *DataElem)
@@ -120,18 +93,28 @@ func (d *Device) readFromTun() {
b := config.LPool.Get().([]byte)[:]
n, err := d.tun.Read(b[:])
if err != nil {
select {
case d.chExit <- err:
default:
}
log.Errorf("[TUN] Failed to read from tun: %v", err)
util.SafeWrite(d.chExit, err)
return
}
if n != 0 {
util.SafeWrite(d.tunInboundRaw, &DataElem{
data: b[:],
length: n,
})
if n == 0 {
log.Errorf("[TUN] Read packet length 0")
continue
}
src, dst, err := util.ParseIP(b[:n])
if err != nil {
log.Errorf("[TUN] Unknown packet")
continue
}
log.Debugf("[TUN] SRC: %s --> DST: %s, length: %d", src, dst, n)
util.SafeWrite(d.tunInbound, &DataElem{
data: b[:],
length: n,
src: src,
dst: dst,
})
}
}
@@ -140,57 +123,26 @@ func (d *Device) writeToTun() {
_, err := d.tun.Write(e.data[:e.length])
config.LPool.Put(e.data[:])
if err != nil {
select {
case d.chExit <- err:
default:
}
util.SafeWrite(d.chExit, err)
return
}
}
}
func (d *Device) parseIPHeader(ctx context.Context) {
for e := range d.tunInboundRaw {
select {
case <-ctx.Done():
return
default:
}
if util.IsIPv4(e.data[:e.length]) {
// ipv4.ParseHeader
b := e.data[:e.length]
e.src = net.IPv4(b[12], b[13], b[14], b[15])
e.dst = net.IPv4(b[16], b[17], b[18], b[19])
} else if util.IsIPv6(e.data[:e.length]) {
// ipv6.ParseHeader
e.src = e.data[:e.length][8:24]
e.dst = e.data[:e.length][24:40]
} else {
log.Errorf("[TUN] Unknown packet")
continue
}
log.Debugf("[TUN] %s --> %s, length: %d", e.src, e.dst, e.length)
util.SafeWrite(d.tunInbound, e)
}
}
func (d *Device) Close() {
d.tun.Close()
util.SafeClose(d.tunInbound)
util.SafeClose(d.tunOutbound)
util.SafeClose(d.tunInboundRaw)
util.SafeClose(TCPPacketChan)
}
func heartbeats(ctx context.Context, tun net.Conn) {
conn, err := util.GetTunDeviceByConn(tun)
tunIfi, err := util.GetTunDeviceByConn(tun)
if err != nil {
log.Errorf("Failed to get tun device: %s", err.Error())
return
}
srcIPv4, srcIPv6, err := util.GetLocalTunIP(conn.Name)
srcIPv4, srcIPv6, err := util.GetTunDeviceIP(tunIfi.Name)
if err != nil {
return
}
@@ -200,10 +152,17 @@ func heartbeats(ctx context.Context, tun net.Conn) {
if config.RouterIP6.To4().Equal(srcIPv6) {
return
}
if config.DockerRouterIP.To4().Equal(srcIPv4) {
return
}
var dstIPv4, dstIPv6 = net.IPv4zero, net.IPv6zero
if config.CIDR.Contains(srcIPv4) {
dstIPv4, dstIPv6 = config.RouterIP, config.RouterIP6
} else if config.DockerCIDR.Contains(srcIPv4) {
dstIPv4 = config.RouterIP
}
if config.CIDR6.Contains(srcIPv6) {
dstIPv6 = config.RouterIP6
}
if config.DockerCIDR.Contains(srcIPv4) {
dstIPv4 = config.DockerRouterIP
}
@@ -220,72 +179,17 @@ func heartbeats(ctx context.Context, tun net.Conn) {
var src, dst net.IP
src, dst = srcIPv4, dstIPv4
if !dst.IsUnspecified() {
_, _ = util.Ping(ctx, src.String(), dst.String())
go util.Ping(ctx, src.String(), dst.String())
}
src, dst = srcIPv6, dstIPv6
if !dst.IsUnspecified() {
_, _ = util.Ping(ctx, src.String(), dst.String())
go util.Ping(ctx, src.String(), dst.String())
}
}
}
func genICMPPacket(src net.IP, dst net.IP) ([]byte, error) {
buf := gopacket.NewSerializeBuffer()
var id uint16
for _, b := range src {
id += uint16(b)
}
icmpLayer := layers.ICMPv4{
TypeCode: layers.CreateICMPv4TypeCode(layers.ICMPv4TypeEchoRequest, 0),
Id: id,
Seq: uint16(rand.Intn(math.MaxUint16 + 1)),
}
ipLayer := layers.IPv4{
Version: 4,
SrcIP: src,
DstIP: dst,
Protocol: layers.IPProtocolICMPv4,
Flags: layers.IPv4DontFragment,
TTL: 64,
IHL: 5,
Id: uint16(rand.Intn(math.MaxUint16 + 1)),
}
opts := gopacket.SerializeOptions{
FixLengths: true,
ComputeChecksums: true,
}
err := gopacket.SerializeLayers(buf, opts, &ipLayer, &icmpLayer)
if err != nil {
return nil, fmt.Errorf("failed to serialize icmp packet, err: %v", err)
}
return buf.Bytes(), nil
}
func genICMPPacketIPv6(src net.IP, dst net.IP) ([]byte, error) {
buf := gopacket.NewSerializeBuffer()
icmpLayer := layers.ICMPv6{
TypeCode: layers.CreateICMPv6TypeCode(layers.ICMPv6TypeEchoRequest, 0),
}
ipLayer := layers.IPv6{
Version: 6,
SrcIP: src,
DstIP: dst,
NextHeader: layers.IPProtocolICMPv6,
HopLimit: 255,
}
opts := gopacket.SerializeOptions{
FixLengths: true,
}
err := gopacket.SerializeLayers(buf, opts, &ipLayer, &icmpLayer)
if err != nil {
return nil, fmt.Errorf("failed to serialize icmp6 packet, err: %v", err)
}
return buf.Bytes(), nil
}
func (d *Device) Start(ctx context.Context) {
go d.readFromTun()
go d.parseIPHeader(ctx)
go d.tunInboundHandler(d.tunInbound, d.tunOutbound)
go d.writeToTun()
go heartbeats(ctx, d.tun)
@@ -304,14 +208,11 @@ func (d *Device) SetTunInboundHandler(handler func(tunInbound <-chan *DataElem,
}
func (h *tunHandler) HandleServer(ctx context.Context, tun net.Conn) {
go h.printRoute(ctx)
device := &Device{
tun: tun,
tunInboundRaw: make(chan *DataElem, MaxSize),
tunInbound: make(chan *DataElem, MaxSize),
tunOutbound: make(chan *DataElem, MaxSize),
chExit: h.chExit,
tun: tun,
tunInbound: make(chan *DataElem, MaxSize),
tunOutbound: make(chan *DataElem, MaxSize),
chExit: h.chExit,
}
device.SetTunInboundHandler(func(tunInbound <-chan *DataElem, tunOutbound chan<- *DataElem) {
for ctx.Err() == nil {
@@ -320,7 +221,7 @@ func (h *tunHandler) HandleServer(ctx context.Context, tun net.Conn) {
log.Errorf("[UDP] Failed to listen %s: %v", h.node.Addr, err)
return
}
err = transportTun(ctx, tunInbound, tunOutbound, packetConn, h.routeMapUDP, h.routeMapTCP)
err = transportTunServer(ctx, tunInbound, tunOutbound, packetConn, h.routeMapUDP, h.routeMapTCP)
if err != nil {
log.Errorf("[TUN] %s: %v", tun.LocalAddr(), err)
}
@@ -366,8 +267,7 @@ type udpElem struct {
type Peer struct {
conn net.PacketConn
connInbound chan *udpElem
parsedConnInfo chan *udpElem
connInbound chan *udpElem
tunInbound <-chan *DataElem
tunOutbound chan<- *DataElem
@@ -390,80 +290,55 @@ func (p *Peer) sendErr(err error) {
func (p *Peer) readFromConn() {
for {
b := config.LPool.Get().([]byte)[:]
n, srcAddr, err := p.conn.ReadFrom(b[:])
n, from, err := p.conn.ReadFrom(b[:])
if err != nil {
p.sendErr(err)
return
}
src, dst, err := util.ParseIP(b[:n])
if err != nil {
log.Errorf("[TUN] Unknown packet: %v", err)
continue
}
if _, loaded := p.routeMapUDP.LoadOrStore(src, from); loaded {
log.Debugf("[TUN] Find route: %s -> %s", src, from)
} else {
log.Debugf("[TUN] Add new route: %s -> %s", src, from)
}
p.connInbound <- &udpElem{
from: srcAddr,
from: from,
data: b[:],
length: n,
src: src,
dst: dst,
}
}
}
func (p *Peer) readFromTCPConn() {
for packet := range TCPPacketChan {
src, dst, err := util.ParseIP(packet.Data)
if err != nil {
log.Errorf("[TUN] Unknown packet")
continue
}
u := &udpElem{
data: packet.Data[:],
length: int(packet.DataLength),
}
b := packet.Data
if util.IsIPv4(packet.Data) {
// ipv4.ParseHeader
u.src = net.IPv4(b[12], b[13], b[14], b[15])
u.dst = net.IPv4(b[16], b[17], b[18], b[19])
} else if util.IsIPv6(packet.Data) {
// ipv6.ParseHeader
u.src = b[8:24]
u.dst = b[24:40]
} else {
log.Errorf("[TUN] Unknown packet")
continue
src: src,
dst: dst,
}
log.Debugf("[TCP] udp-tun %s >>> %s length: %d", u.src, u.dst, u.length)
p.parsedConnInfo <- u
}
}
func (p *Peer) parseHeader() {
var firstIPv4, firstIPv6 = true, true
for e := range p.connInbound {
b := e.data[:e.length]
if util.IsIPv4(e.data[:e.length]) {
// ipv4.ParseHeader
e.src = net.IPv4(b[12], b[13], b[14], b[15])
e.dst = net.IPv4(b[16], b[17], b[18], b[19])
} else if util.IsIPv6(e.data[:e.length]) {
// ipv6.ParseHeader
e.src = b[:e.length][8:24]
e.dst = b[:e.length][24:40]
} else {
log.Errorf("[TUN] Unknown packet")
continue
}
if firstIPv4 || firstIPv6 {
if util.IsIPv4(e.data[:e.length]) {
firstIPv4 = false
} else {
firstIPv6 = false
}
if _, loaded := p.routeMapUDP.LoadOrStore(e.src, e.from); loaded {
log.Debugf("[TUN] Find route: %s -> %s", e.src, e.from)
} else {
log.Debugf("[TUN] Add new route: %s -> %s", e.src, e.from)
}
}
p.parsedConnInfo <- e
p.connInbound <- u
}
}
func (p *Peer) routePeer() {
for e := range p.parsedConnInfo {
for e := range p.connInbound {
if routeToAddr := p.routeMapUDP.RouteTo(e.dst); routeToAddr != nil {
log.Debugf("[TUN] Find route: %s -> %s", e.dst, routeToAddr)
log.Debugf("[TCP] Find route: %s -> %s", e.dst, routeToAddr)
_, err := p.conn.WriteTo(e.data[:e.length], routeToAddr)
config.LPool.Put(e.data[:])
if err != nil {
@@ -471,6 +346,7 @@ func (p *Peer) routePeer() {
return
}
} else if conn, ok := p.routeMapTCP.Load(e.dst.String()); ok {
log.Debugf("[TCP] Find TCP route to dst: %s -> %s", e.dst.String(), conn.(net.Conn).RemoteAddr())
dgram := newDatagramPacket(e.data[:e.length])
if err := dgram.Write(conn.(net.Conn)); err != nil {
log.Errorf("[TCP] udp-tun %s <- %s : %s", conn.(net.Conn).RemoteAddr(), dgram.Addr(), err)
@@ -479,6 +355,7 @@ func (p *Peer) routePeer() {
}
config.LPool.Put(e.data[:])
} else {
log.Debugf("[TCP] Not found route to dst: %s, write to TUN device", e.dst.String())
p.tunOutbound <- &DataElem{
data: e.data,
length: e.length,
@@ -501,17 +378,18 @@ func (p *Peer) routeTUN() {
return
}
} else if conn, ok := p.routeMapTCP.Load(e.dst.String()); ok {
log.Debugf("[TUN] Find TCP route to dst: %s -> %s", e.dst.String(), conn.(net.Conn).RemoteAddr())
dgram := newDatagramPacket(e.data[:e.length])
err := dgram.Write(conn.(net.Conn))
config.LPool.Put(e.data[:])
if err != nil {
log.Errorf("[TCP] udp-tun %s <- %s : %s", conn.(net.Conn).RemoteAddr(), dgram.Addr(), err)
log.Errorf("[TUN] udp-tun %s <- %s : %s", conn.(net.Conn).RemoteAddr(), dgram.Addr(), err)
p.sendErr(err)
return
}
} else {
log.Errorf("[TUN] No route for %s -> %s, drop it", e.src, e.dst)
config.LPool.Put(e.data[:])
log.Errorf("[TUN] No route for %s -> %s", e.src, e.dst)
}
}
}
@@ -519,7 +397,6 @@ func (p *Peer) routeTUN() {
func (p *Peer) Start() {
go p.readFromConn()
go p.readFromTCPConn()
go p.parseHeader()
go p.routePeer()
go p.routeTUN()
}
@@ -528,16 +405,15 @@ func (p *Peer) Close() {
p.conn.Close()
}
func transportTun(ctx context.Context, tunInbound <-chan *DataElem, tunOutbound chan<- *DataElem, packetConn net.PacketConn, routeMapUDP *RouteMap, routeMapTCP *sync.Map) error {
func transportTunServer(ctx context.Context, tunInbound <-chan *DataElem, tunOutbound chan<- *DataElem, packetConn net.PacketConn, routeMapUDP *RouteMap, routeMapTCP *sync.Map) error {
p := &Peer{
conn: packetConn,
connInbound: make(chan *udpElem, MaxSize),
parsedConnInfo: make(chan *udpElem, MaxSize),
tunInbound: tunInbound,
tunOutbound: tunOutbound,
routeMapUDP: routeMapUDP,
routeMapTCP: routeMapTCP,
errChan: make(chan error, 2),
conn: packetConn,
connInbound: make(chan *udpElem, MaxSize),
tunInbound: tunInbound,
tunOutbound: tunOutbound,
routeMapUDP: routeMapUDP,
routeMapTCP: routeMapTCP,
errChan: make(chan error, 2),
}
defer p.Close()

View File

@@ -22,10 +22,6 @@ func (h *tunHandler) HandleClient(ctx context.Context, tun net.Conn) {
}
in := make(chan *DataElem, MaxSize)
out := make(chan *DataElem, MaxSize)
engine := h.node.Get(config.ConfigKubeVPNTransportEngine)
endpoint := NewTunEndpoint(ctx, tun, uint32(config.DefaultMTU), config.Engine(engine), in, out)
stack := NewStack(ctx, endpoint)
defer stack.Destroy()
defer util.SafeClose(in)
defer util.SafeClose(out)
@@ -93,7 +89,7 @@ func transportTunClient(ctx context.Context, tunInbound <-chan *DataElem, tunOut
_, err := packetConn.WriteTo(e.data[:e.length], remoteAddr)
config.LPool.Put(e.data[:])
if err != nil {
errChan <- errors.Wrap(err, fmt.Sprintf("failed to write packet to remote %s", remoteAddr))
util.SafeWrite(errChan, errors.Wrap(err, fmt.Sprintf("failed to write packet to remote %s", remoteAddr)))
return
}
}
@@ -104,7 +100,7 @@ func transportTunClient(ctx context.Context, tunInbound <-chan *DataElem, tunOut
b := config.LPool.Get().([]byte)[:]
n, _, err := packetConn.ReadFrom(b[:])
if err != nil {
errChan <- errors.Wrap(err, fmt.Sprintf("failed to read packet from remote %s", remoteAddr))
util.SafeWrite(errChan, errors.Wrap(err, fmt.Sprintf("failed to read packet from remote %s", remoteAddr)))
return
}
util.SafeWrite(tunOutbound, &DataElem{data: b[:], length: n})
@@ -131,6 +127,8 @@ type ClientDevice struct {
func (d *ClientDevice) Start(ctx context.Context) {
go d.tunInboundHandler(d.tunInbound, d.tunOutbound)
go heartbeats(ctx, d.tun)
go d.readFromTun()
go d.writeToTun()
select {
case err := <-d.chExit:
@@ -144,3 +142,36 @@ func (d *ClientDevice) Start(ctx context.Context) {
func (d *ClientDevice) SetTunInboundHandler(handler func(tunInbound <-chan *DataElem, tunOutbound chan<- *DataElem)) {
d.tunInboundHandler = handler
}
func (d *ClientDevice) readFromTun() {
for {
b := config.LPool.Get().([]byte)[:]
n, err := d.tun.Read(b[:])
if err != nil {
util.SafeWrite(d.chExit, err)
return
}
if n != 0 {
// Try to determine network protocol number, default zero.
var src, dst net.IP
src, dst, err = util.ParseIP(b[:n])
if err != nil {
log.Debugf("[TUN-GVISOR] Unknown packet: %v", err)
continue
}
log.Tracef("[TUN-RAW] SRC: %s, DST: %s, Length: %d", src.String(), dst, n)
util.SafeWrite(d.tunInbound, NewDataElem(b[:], n, src, dst))
}
}
}
func (d *ClientDevice) writeToTun() {
for e := range d.tunOutbound {
_, err := d.tun.Write(e.data[:e.length])
config.LPool.Put(e.data[:])
if err != nil {
util.SafeWrite(d.chExit, err)
return
}
}
}

View File

@@ -1,8 +1,10 @@
package action
import (
"bufio"
"io"
"log"
"os"
"github.com/hpcloud/tail"
@@ -11,6 +13,19 @@ import (
func (svr *Server) Logs(req *rpc.LogRequest, resp rpc.Daemon_LogsServer) error {
path := GetDaemonLogPath()
lines, err2 := countLines(path)
if err2 != nil {
return err2
}
// only show latest N lines
if req.Lines < 0 {
lines = -req.Lines
} else {
lines -= req.Lines
}
config := tail.Config{Follow: req.Follow, ReOpen: false, MustExist: true, Logger: log.New(io.Discard, "", log.LstdFlags)}
if !req.Follow {
// FATAL -- cannot set ReOpen without Follow.
@@ -32,6 +47,11 @@ func (svr *Server) Logs(req *rpc.LogRequest, resp rpc.Daemon_LogsServer) error {
if line.Err != nil {
return err
}
if lines--; lines >= 0 {
continue
}
err = resp.Send(&rpc.LogResponse{Message: line.Text})
if err != nil {
return err
@@ -39,3 +59,24 @@ func (svr *Server) Logs(req *rpc.LogRequest, resp rpc.Daemon_LogsServer) error {
}
}
}
func countLines(filename string) (int32, error) {
file, err := os.Open(filename)
if err != nil {
return 0, err
}
defer file.Close()
scanner := bufio.NewScanner(file)
lineCount := int32(0)
for scanner.Scan() {
lineCount++
}
if err = scanner.Err(); err != nil {
return 0, err
}
return lineCount, nil
}

View File

@@ -1,6 +1,7 @@
package action
import (
"context"
"io"
"io/fs"
"os"
@@ -45,6 +46,9 @@ func (svr *Server) Quit(req *rpc.QuitRequest, resp rpc.Daemon_QuitServer) error
if svr.IsSudo {
_ = dns.CleanupHosts()
_ = os.RemoveAll("/etc/resolver")
if util.FindAllowFirewallRule(context.Background()) {
util.DeleteAllowFirewallRule(context.Background())
}
}
// last step is to quit GRPC server

View File

@@ -126,7 +126,7 @@ func (w *wsHandler) handle(c context.Context) {
log.Info("Connected tunnel")
go func() {
for ctx.Err() == nil {
_, _ = util.Ping(ctx, clientIP.IP.String(), ip.String())
util.Ping(ctx, clientIP.IP.String(), ip.String())
time.Sleep(time.Second * 5)
}
}()

View File

@@ -2014,7 +2014,8 @@ type LogRequest struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Follow bool `protobuf:"varint,1,opt,name=Follow,proto3" json:"Follow,omitempty"`
Follow bool `protobuf:"varint,1,opt,name=Follow,proto3" json:"Follow,omitempty"`
Lines int32 `protobuf:"varint,2,opt,name=Lines,proto3" json:"Lines,omitempty"`
}
func (x *LogRequest) Reset() {
@@ -2056,6 +2057,13 @@ func (x *LogRequest) GetFollow() bool {
return false
}
func (x *LogRequest) GetLines() int32 {
if x != nil {
return x.Lines
}
return 0
}
type LogResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -3025,147 +3033,148 @@ var file_daemon_proto_rawDesc = []byte{
0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x49,
0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72,
0x49, 0x44, 0x22, 0x16, 0x0a, 0x14, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x6d, 0x6f,
0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x0a, 0x0a, 0x4c, 0x6f,
0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3a, 0x0a, 0x0a, 0x4c, 0x6f,
0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x46, 0x6f, 0x6c, 0x6c,
0x6f, 0x77, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x46, 0x6f, 0x6c, 0x6c, 0x6f, 0x77,
0x22, 0x27, 0x0a, 0x0b, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x0d, 0x0a, 0x0b, 0x4c, 0x69, 0x73,
0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x28, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61,
0x67, 0x65, 0x22, 0x46, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20,
0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1a,
0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x22, 0x29, 0x0a, 0x0b, 0x47, 0x65,
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x74,
0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x08, 0x6d, 0x65, 0x74,
0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x36, 0x0a, 0x0e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a, 0x0d, 0x43, 0x6c, 0x69, 0x65, 0x6e,
0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d,
0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x33, 0x0a,
0x0f, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x12, 0x20, 0x0a, 0x0b, 0x4e, 0x65, 0x65, 0x64, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x18,
0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x4e, 0x65, 0x65, 0x64, 0x55, 0x70, 0x67, 0x72, 0x61,
0x64, 0x65, 0x22, 0x7e, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x4b, 0x75, 0x62,
0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09,
0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x26, 0x0a, 0x07, 0x53, 0x73,
0x68, 0x4a, 0x75, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x72, 0x70,
0x63, 0x2e, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x52, 0x07, 0x53, 0x73, 0x68, 0x4a, 0x75,
0x6d, 0x70, 0x22, 0x29, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0xc7, 0x02,
0x0a, 0x07, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x41, 0x64, 0x64,
0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x41, 0x64, 0x64, 0x72, 0x12, 0x12, 0x0a,
0x04, 0x55, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x55, 0x73, 0x65,
0x72, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x03, 0x20,
0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x18, 0x0a,
0x07, 0x4b, 0x65, 0x79, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07,
0x4b, 0x65, 0x79, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x4a, 0x75, 0x6d, 0x70, 0x18,
0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4a, 0x75, 0x6d, 0x70, 0x12, 0x20, 0x0a, 0x0b, 0x43,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09,
0x52, 0x0b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x6c, 0x69, 0x61, 0x73, 0x12, 0x2a, 0x0a,
0x10, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69,
0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b,
0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x2a, 0x0a, 0x10, 0x47, 0x53, 0x53,
0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x74, 0x61, 0x62, 0x43, 0x6f, 0x6e, 0x66, 0x18, 0x08, 0x20,
0x01, 0x28, 0x09, 0x52, 0x10, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x74, 0x61,
0x62, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x26, 0x0a, 0x0e, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49, 0x50,
0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x47,
0x53, 0x53, 0x41, 0x50, 0x49, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x12, 0x28, 0x0a,
0x0f, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49, 0x43, 0x61, 0x63, 0x68, 0x65, 0x46, 0x69, 0x6c, 0x65,
0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49, 0x43, 0x61,
0x63, 0x68, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x22, 0x6e, 0x0a, 0x0a, 0x45, 0x78, 0x74, 0x72, 0x61,
0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x45, 0x78, 0x74, 0x72, 0x61, 0x43, 0x49,
0x44, 0x52, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x45, 0x78, 0x74, 0x72, 0x61, 0x43,
0x49, 0x44, 0x52, 0x12, 0x20, 0x0a, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x44, 0x6f, 0x6d, 0x61,
0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x44,
0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x4e, 0x6f,
0x64, 0x65, 0x49, 0x50, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x45, 0x78, 0x74, 0x72,
0x61, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x50, 0x22, 0x11, 0x0a, 0x0f, 0x49, 0x64, 0x65, 0x6e, 0x74,
0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x22, 0x0a, 0x10, 0x49, 0x64,
0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e,
0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x49, 0x44, 0x32, 0xa6,
0x09, 0x0a, 0x06, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x12, 0x38, 0x0a, 0x07, 0x43, 0x6f, 0x6e,
0x6e, 0x65, 0x63, 0x74, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e,
0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x00, 0x30, 0x01, 0x12, 0x3c, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x46, 0x6f,
0x72, 0x6b, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f,
0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30,
0x01, 0x12, 0x41, 0x0a, 0x0a, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12,
0x16, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69,
0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x30, 0x01, 0x12, 0x36, 0x0a, 0x05, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x12, 0x13, 0x2e,
0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x32, 0x0a, 0x05,
0x4c, 0x65, 0x61, 0x76, 0x65, 0x12, 0x11, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x65, 0x61, 0x76,
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c,
0x65, 0x61, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01,
0x12, 0x32, 0x0a, 0x05, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x12, 0x11, 0x2e, 0x72, 0x70, 0x63, 0x2e,
0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x72,
0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x30, 0x01, 0x12, 0x35, 0x0a, 0x06, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12, 0x12,
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x3c, 0x0a, 0x09, 0x43,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x64, 0x64, 0x12, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43,
0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x16, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x64, 0x64, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x45, 0x0a, 0x0c, 0x43, 0x6f, 0x6e,
0x66, 0x69, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12, 0x18, 0x2e, 0x72, 0x70, 0x63, 0x2e,
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
0x12, 0x39, 0x0a, 0x08, 0x53, 0x73, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x14, 0x2e, 0x72,
0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x53, 0x74, 0x61, 0x72,
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x07, 0x53,
0x73, 0x68, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68,
0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70,
0x63, 0x2e, 0x53, 0x73, 0x68, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0a, 0x53, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
0x74, 0x12, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x72, 0x70, 0x63, 0x2e,
0x53, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x2d, 0x0a, 0x04, 0x4c, 0x6f, 0x67, 0x73,
0x12, 0x0f, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x2d, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12,
0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x11, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x2a, 0x0a, 0x03, 0x47, 0x65, 0x74, 0x12, 0x0f, 0x2e,
0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10,
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x00, 0x12, 0x36, 0x0a, 0x07, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x12, 0x13, 0x2e,
0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x33, 0x0a, 0x06, 0x53, 0x74,
0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75,
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53,
0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
0x36, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63,
0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x32, 0x0a, 0x05, 0x52, 0x65, 0x73, 0x65, 0x74,
0x12, 0x11, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x71, 0x75,
0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x73, 0x65, 0x74, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x2f, 0x0a, 0x04, 0x51,
0x75, 0x69, 0x74, 0x12, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x69, 0x74, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x51, 0x75, 0x69, 0x74,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x39, 0x0a, 0x08,
0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x12, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49,
0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15,
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x07, 0x5a, 0x05, 0x2e, 0x3b, 0x72, 0x70, 0x63,
0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x12, 0x14, 0x0a, 0x05, 0x4c, 0x69, 0x6e, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52,
0x05, 0x4c, 0x69, 0x6e, 0x65, 0x73, 0x22, 0x27, 0x0a, 0x0b, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22,
0x0d, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x28,
0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18,
0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x22, 0x46, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70,
0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73,
0x70, 0x61, 0x63, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
0x22, 0x29, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x1a, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x03, 0x28,
0x09, 0x52, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x36, 0x0a, 0x0e, 0x55,
0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x24, 0x0a,
0x0d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01,
0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x56, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x22, 0x33, 0x0a, 0x0f, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x4e, 0x65, 0x65, 0x64, 0x55, 0x70,
0x67, 0x72, 0x61, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x4e, 0x65, 0x65,
0x64, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x22, 0x7e, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x65,
0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x28, 0x0a, 0x0f, 0x4b, 0x75, 0x62, 0x65,
0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28,
0x09, 0x52, 0x0f, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x42, 0x79, 0x74,
0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18,
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65,
0x12, 0x26, 0x0a, 0x07, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28,
0x0b, 0x32, 0x0c, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x52,
0x07, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x22, 0x29, 0x0a, 0x0d, 0x52, 0x65, 0x73, 0x65,
0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73,
0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73,
0x61, 0x67, 0x65, 0x22, 0xc7, 0x02, 0x0a, 0x07, 0x53, 0x73, 0x68, 0x4a, 0x75, 0x6d, 0x70, 0x12,
0x12, 0x0a, 0x04, 0x41, 0x64, 0x64, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x41,
0x64, 0x64, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x04, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x50, 0x61, 0x73, 0x73, 0x77,
0x6f, 0x72, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x50, 0x61, 0x73, 0x73, 0x77,
0x6f, 0x72, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x4b, 0x65, 0x79, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x04,
0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x4b, 0x65, 0x79, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a,
0x04, 0x4a, 0x75, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x4a, 0x75, 0x6d,
0x70, 0x12, 0x20, 0x0a, 0x0b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x6c, 0x69, 0x61, 0x73,
0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x6c,
0x69, 0x61, 0x73, 0x12, 0x2a, 0x0a, 0x10, 0x52, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x75, 0x62,
0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x52,
0x65, 0x6d, 0x6f, 0x74, 0x65, 0x4b, 0x75, 0x62, 0x65, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
0x2a, 0x0a, 0x10, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x74, 0x61, 0x62, 0x43,
0x6f, 0x6e, 0x66, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x10, 0x47, 0x53, 0x53, 0x41, 0x50,
0x49, 0x4b, 0x65, 0x79, 0x74, 0x61, 0x62, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x26, 0x0a, 0x0e, 0x47,
0x53, 0x53, 0x41, 0x50, 0x49, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x18, 0x09, 0x20,
0x01, 0x28, 0x09, 0x52, 0x0e, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49, 0x50, 0x61, 0x73, 0x73, 0x77,
0x6f, 0x72, 0x64, 0x12, 0x28, 0x0a, 0x0f, 0x47, 0x53, 0x53, 0x41, 0x50, 0x49, 0x43, 0x61, 0x63,
0x68, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, 0x47, 0x53,
0x53, 0x41, 0x50, 0x49, 0x43, 0x61, 0x63, 0x68, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x22, 0x6e, 0x0a,
0x0a, 0x45, 0x78, 0x74, 0x72, 0x61, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x45,
0x78, 0x74, 0x72, 0x61, 0x43, 0x49, 0x44, 0x52, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09,
0x45, 0x78, 0x74, 0x72, 0x61, 0x43, 0x49, 0x44, 0x52, 0x12, 0x20, 0x0a, 0x0b, 0x45, 0x78, 0x74,
0x72, 0x61, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0b,
0x45, 0x78, 0x74, 0x72, 0x61, 0x44, 0x6f, 0x6d, 0x61, 0x69, 0x6e, 0x12, 0x20, 0x0a, 0x0b, 0x45,
0x78, 0x74, 0x72, 0x61, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x50, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08,
0x52, 0x0b, 0x45, 0x78, 0x74, 0x72, 0x61, 0x4e, 0x6f, 0x64, 0x65, 0x49, 0x50, 0x22, 0x11, 0x0a,
0x0f, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x22, 0x22, 0x0a, 0x10, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x0e, 0x0a, 0x02, 0x49, 0x44, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x02, 0x49, 0x44, 0x32, 0xa6, 0x09, 0x0a, 0x06, 0x44, 0x61, 0x65, 0x6d, 0x6f, 0x6e, 0x12,
0x38, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63,
0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x3c, 0x0a, 0x0b, 0x43, 0x6f, 0x6e,
0x6e, 0x65, 0x63, 0x74, 0x46, 0x6f, 0x72, 0x6b, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43,
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e,
0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x41, 0x0a, 0x0a, 0x44, 0x69, 0x73, 0x63, 0x6f,
0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x63,
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e,
0x72, 0x70, 0x63, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x36, 0x0a, 0x05, 0x50, 0x72,
0x6f, 0x78, 0x79, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63,
0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43,
0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
0x30, 0x01, 0x12, 0x32, 0x0a, 0x05, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x12, 0x11, 0x2e, 0x72, 0x70,
0x63, 0x2e, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12,
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x32, 0x0a, 0x05, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x12,
0x11, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65,
0x73, 0x74, 0x1a, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6c, 0x6f, 0x6e, 0x65, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x35, 0x0a, 0x06, 0x52, 0x65,
0x6d, 0x6f, 0x76, 0x65, 0x12, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x6d, 0x6f, 0x76,
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52,
0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30,
0x01, 0x12, 0x3c, 0x0a, 0x09, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x64, 0x64, 0x12, 0x15,
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x41, 0x64, 0x64, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x66,
0x69, 0x67, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
0x45, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12,
0x18, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x6d, 0x6f,
0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x70, 0x63, 0x2e,
0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70,
0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x08, 0x53, 0x73, 0x68, 0x53, 0x74, 0x61,
0x72, 0x74, 0x12, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x53, 0x74, 0x61, 0x72,
0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53,
0x73, 0x68, 0x53, 0x74, 0x61, 0x72, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22,
0x00, 0x12, 0x36, 0x0a, 0x07, 0x53, 0x73, 0x68, 0x53, 0x74, 0x6f, 0x70, 0x12, 0x13, 0x2e, 0x72,
0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x53, 0x74, 0x6f, 0x70, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x53, 0x74, 0x6f, 0x70, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x43, 0x0a, 0x0a, 0x53, 0x73, 0x68,
0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x16, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73,
0x68, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x17, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x73, 0x68, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x12, 0x2d,
0x0a, 0x04, 0x4c, 0x6f, 0x67, 0x73, 0x12, 0x0f, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f,
0x67, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30, 0x01, 0x12, 0x2d, 0x0a,
0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69, 0x73, 0x74,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x69,
0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x2a, 0x0a, 0x03,
0x47, 0x65, 0x74, 0x12, 0x0f, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x47, 0x65, 0x74, 0x52, 0x65,
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x07, 0x55, 0x70, 0x67, 0x72,
0x61, 0x64, 0x65, 0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x70, 0x67, 0x72, 0x61, 0x64,
0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x55,
0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
0x12, 0x33, 0x0a, 0x06, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x2e, 0x72, 0x70, 0x63,
0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13,
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x36, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
0x12, 0x13, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x65, 0x72, 0x73,
0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x32, 0x0a,
0x05, 0x52, 0x65, 0x73, 0x65, 0x74, 0x12, 0x11, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x73,
0x65, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x72, 0x70, 0x63, 0x2e,
0x52, 0x65, 0x73, 0x65, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x30,
0x01, 0x12, 0x2f, 0x0a, 0x04, 0x51, 0x75, 0x69, 0x74, 0x12, 0x10, 0x2e, 0x72, 0x70, 0x63, 0x2e,
0x51, 0x75, 0x69, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x72, 0x70,
0x63, 0x2e, 0x51, 0x75, 0x69, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
0x30, 0x01, 0x12, 0x39, 0x0a, 0x08, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x12, 0x14,
0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x79, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x2e, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74,
0x69, 0x66, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x07, 0x5a,
0x05, 0x2e, 0x3b, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (

View File

@@ -250,6 +250,7 @@ message ConfigRemoveResponse {
message LogRequest {
bool Follow = 1;
int32 Lines = 2;
}
message LogResponse {

View File

@@ -368,9 +368,9 @@ func (option *Options) CreateConnectContainer(portBindings nat.PortMap) (*RunCon
var entrypoint []string
if option.NoProxy {
entrypoint = []string{"kubevpn", "connect", "--foreground", "-n", option.Namespace, "--kubeconfig", "/root/.kube/config", "--image", config.Image, "--engine", string(option.Engine)}
entrypoint = []string{"kubevpn", "connect", "--foreground", "-n", option.Namespace, "--kubeconfig", "/root/.kube/config", "--image", config.Image, "--netstack", string(option.Engine)}
} else {
entrypoint = []string{"kubevpn", "proxy", option.Workload, "--foreground", "-n", option.Namespace, "--kubeconfig", "/root/.kube/config", "--image", config.Image, "--engine", string(option.Engine)}
entrypoint = []string{"kubevpn", "proxy", option.Workload, "--foreground", "-n", option.Namespace, "--kubeconfig", "/root/.kube/config", "--image", config.Image, "--netstack", string(option.Engine)}
for k, v := range option.Headers {
entrypoint = append(entrypoint, "--headers", fmt.Sprintf("%s=%s", k, v))
}

View File

@@ -293,7 +293,7 @@ func (d *CloneOptions) DoClone(ctx context.Context, kubeconfigJsonBytes []byte)
"--kubeconfig", "/tmp/.kube/" + config.KUBECONFIG,
"--namespace", d.Namespace,
"--image", config.Image,
"--engine", string(d.Engine),
"--netstack", string(d.Engine),
"--foreground",
}, args...),
Env: []v1.EnvVar{},

View File

@@ -225,9 +225,10 @@ func (c *ConnectOptions) DoConnect(ctx context.Context, isLite bool) (err error)
driver.InstallWireGuardTunDriver()
}
forward := fmt.Sprintf("tcp://127.0.0.1:%d", rawTCPForwardPort)
core.GvisorTCPForwardAddr = fmt.Sprintf("tcp://127.0.0.1:%d", gvisorTCPForwardPort)
core.GvisorUDPForwardAddr = fmt.Sprintf("tcp://127.0.0.1:%d", gvisorUDPForwardPort)
if err = c.startLocalTunServe(c.ctx, forward, isLite); err != nil {
if c.Engine == config.EngineGvisor {
forward = fmt.Sprintf("tcp://127.0.0.1:%d", gvisorTCPForwardPort)
}
if err = c.startLocalTunServer(c.ctx, forward, isLite); err != nil {
log.Errorf("Start local tun service failed: %v", err)
return
}
@@ -276,7 +277,7 @@ func (c *ConnectOptions) portForward(ctx context.Context, portPair []string) err
var readyChan = make(chan struct{})
podName := podList[0].GetName()
// try to detect pod is delete event, if pod is deleted, needs to redo port-forward
//go util.CheckPodStatus(childCtx, cancelFunc, podName, c.clientset.CoreV1().Pods(c.Namespace))
go util.CheckPodStatus(childCtx, cancelFunc, podName, c.clientset.CoreV1().Pods(c.Namespace))
go util.CheckPortStatus(childCtx, cancelFunc, readyChan, strings.Split(portPair[1], ":")[0])
if *first {
go func() {
@@ -330,12 +331,20 @@ func (c *ConnectOptions) portForward(ctx context.Context, portPair []string) err
}
}
func (c *ConnectOptions) startLocalTunServe(ctx context.Context, forwardAddress string, lite bool) (err error) {
func (c *ConnectOptions) startLocalTunServer(ctx context.Context, forwardAddress string, lite bool) (err error) {
log.Debugf("IPv4: %s, IPv6: %s", c.localTunIPv4.IP.String(), c.localTunIPv6.IP.String())
var cidrList []*net.IPNet
if !lite {
cidrList = append(cidrList, config.CIDR)
cidrList = append(cidrList, config.CIDR, config.CIDR6)
} else {
// windows needs to add tun IP self to route table, but linux and macOS not need
if util.IsWindows() {
cidrList = append(cidrList,
&net.IPNet{IP: c.localTunIPv4.IP, Mask: net.CIDRMask(32, 32)},
&net.IPNet{IP: c.localTunIPv6.IP, Mask: net.CIDRMask(128, 128)},
)
}
}
for _, ipNet := range c.cidrs {
cidrList = append(cidrList, ipNet)
@@ -356,11 +365,11 @@ func (c *ConnectOptions) startLocalTunServe(ctx context.Context, forwardAddress
}
tunConfig := tun.Config{
Addr: c.localTunIPv4.String(),
Addr: (&net.IPNet{IP: c.localTunIPv4.IP, Mask: net.CIDRMask(32, 32)}).String(),
Routes: routes,
}
if enable, _ := util.IsIPv6Enabled(); enable {
tunConfig.Addr6 = c.localTunIPv6.String()
tunConfig.Addr6 = (&net.IPNet{IP: c.localTunIPv6.IP, Mask: net.CIDRMask(128, 128)}).String()
}
localNode := fmt.Sprintf("tun:/127.0.0.1:8422")
@@ -506,6 +515,16 @@ func (c *ConnectOptions) addRouteDynamic(ctx context.Context) error {
}
func (c *ConnectOptions) deleteFirewallRule(ctx context.Context) {
if !util.IsWindows() {
return
}
// The reason why delete firewall rule is:
// On windows ping local tun IPv4/v6 not works
// so needs to add firewall rule to allow this
if !util.FindAllowFirewallRule(ctx) {
util.AddAllowFirewallRule(ctx)
}
// The reason why delete firewall rule is:
// On windows use 'kubevpn proxy deploy/authors -H user=windows'
// Open terminal 'curl localhost:9080' ok

View File

@@ -7,6 +7,7 @@ import (
"net"
"net/netip"
"reflect"
"syscall"
"time"
"github.com/containernetworking/cni/pkg/types"
@@ -24,18 +25,18 @@ func createTun(cfg Config) (conn net.Conn, itf *net.Interface, err error) {
return
}
interfaceName := "KubeVPN"
tunName := "KubeVPN"
if len(cfg.Name) != 0 {
interfaceName = cfg.Name
tunName = cfg.Name
}
wireguardtun.WintunTunnelType = "KubeVPN"
tunDevice, err := wireguardtun.CreateTUN(interfaceName, cfg.MTU)
tunDevice, err := wireguardtun.CreateTUN(tunName, cfg.MTU)
if err != nil {
err = fmt.Errorf("failed to create TUN device: %w", err)
return
}
ifName := winipcfg.LUID(tunDevice.(*wireguardtun.NativeTun).LUID())
ifUID := winipcfg.LUID(tunDevice.(*wireguardtun.NativeTun).LUID())
var ipv4, ipv6 net.IP
if cfg.Addr != "" {
@@ -46,7 +47,8 @@ func createTun(cfg Config) (conn net.Conn, itf *net.Interface, err error) {
if prefix, err = netip.ParsePrefix(cfg.Addr); err != nil {
return
}
if err = ifName.AddIPAddress(prefix); err != nil {
if err = ifUID.AddIPAddress(prefix); err != nil {
err = fmt.Errorf("can not setup IPv4 address %s to device %s : %v", prefix.String(), tunName, err)
return
}
}
@@ -59,25 +61,25 @@ func createTun(cfg Config) (conn net.Conn, itf *net.Interface, err error) {
if prefix, err = netip.ParsePrefix(cfg.Addr6); err != nil {
return
}
if err = ifName.AddIPAddress(prefix); err != nil {
if err = ifUID.AddIPAddress(prefix); err != nil && !errors.Is(err, syscall.ERROR_NOT_FOUND) {
err = fmt.Errorf("can not setup IPv6 address %s to device %s : %v", prefix.String(), tunName, err)
return
}
}
var tunName string
tunName, err = tunDevice.Name()
if err != nil {
return nil, nil, err
}
_ = ifName.FlushRoutes(windows.AF_INET)
_ = ifName.FlushRoutes(windows.AF_INET6)
_ = ifUID.FlushRoutes(windows.AF_INET)
_ = ifUID.FlushRoutes(windows.AF_INET6)
if err = addTunRoutes(tunName /*cfg.Gateway,*/, cfg.Routes...); err != nil {
return
}
var row *winipcfg.MibIfRow2
if row, err = ifName.Interface(); err != nil {
if row, err = ifUID.Interface(); err != nil {
return
}
if itf, err = net.InterfaceByIndex(int(row.InterfaceIndex)); err != nil {
@@ -87,7 +89,7 @@ func createTun(cfg Config) (conn net.Conn, itf *net.Interface, err error) {
// windows,macOS,linux connect to same cluster
// macOS and linux can ping each other, but macOS and linux can not ping windows
var ipInterface *winipcfg.MibIPInterfaceRow
ipInterface, err = ifName.IPInterface(windows.AF_INET)
ipInterface, err = ifUID.IPInterface(windows.AF_INET)
if err != nil {
return
}
@@ -105,7 +107,7 @@ func addTunRoutes(tunName string, routes ...types.Route) error {
if err2 != nil {
return err2
}
ifName, err := winipcfg.LUIDFromIndex(uint32(name.Index))
ifUID, err := winipcfg.LUIDFromIndex(uint32(name.Index))
if err != nil {
return err
}
@@ -113,10 +115,7 @@ func addTunRoutes(tunName string, routes ...types.Route) error {
if route.Dst.String() == "" {
continue
}
var gw string
if gw != "" {
route.GW = net.ParseIP(gw)
} else {
if route.GW == nil {
if route.Dst.IP.To4() != nil {
route.GW = net.IPv4zero
} else {
@@ -133,8 +132,8 @@ func addTunRoutes(tunName string, routes ...types.Route) error {
if err != nil {
return err
}
err = ifName.AddRoute(prefix, addr.Unmap(), 0)
if err != nil && err != windows.ERROR_OBJECT_ALREADY_EXISTS {
err = ifUID.AddRoute(prefix, addr.Unmap(), 0)
if err != nil && !errors.Is(err, windows.ERROR_OBJECT_ALREADY_EXISTS) && !errors.Is(err, syscall.ERROR_NOT_FOUND) {
return err
}
}

View File

@@ -2,14 +2,20 @@ package util
import (
"context"
"errors"
"fmt"
"math"
"math/rand"
"net"
"strings"
"time"
"github.com/cilium/ipam/service/allocator"
"github.com/cilium/ipam/service/ipallocator"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/prometheus-community/pro-bing"
"golang.org/x/net/ipv4"
"golang.org/x/net/ipv6"
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
)
@@ -20,14 +26,16 @@ func GetTunDevice(ips ...net.IP) (*net.Interface, error) {
return nil, err
}
for _, i := range interfaces {
addrs, err := i.Addrs()
addrList, err := i.Addrs()
if err != nil {
return nil, err
}
for _, addr := range addrs {
for _, ip := range ips {
if strings.Contains(addr.String(), ip.String()) {
return &i, nil
for _, addr := range addrList {
if ipNet, ok := addr.(*net.IPNet); ok {
for _, ip := range ips {
if ipNet.IP.Equal(ip) {
return &i, nil
}
}
}
}
@@ -36,57 +44,62 @@ func GetTunDevice(ips ...net.IP) (*net.Interface, error) {
}
func GetTunDeviceByConn(tun net.Conn) (*net.Interface, error) {
interfaces, err := net.Interfaces()
if err != nil {
return nil, err
var ip net.IP
switch tun.LocalAddr().(type) {
case *net.IPNet:
ip = tun.LocalAddr().(*net.IPNet).IP
case *net.IPAddr:
ip = tun.LocalAddr().(*net.IPAddr).IP
}
var ip string
if tunIP, ok := tun.LocalAddr().(*net.IPNet); ok {
ip = tunIP.IP.String()
} else {
ip = tun.LocalAddr().String()
}
for _, i := range interfaces {
addrs, err := i.Addrs()
if err != nil {
return nil, err
}
for _, addr := range addrs {
if strings.Contains(addr.String(), tun.LocalAddr().String()) {
return &i, nil
}
}
}
return nil, fmt.Errorf("can not found any interface with ip %v", ip)
return GetTunDevice(ip)
}
func GetLocalTunIP(tunName string) (net.IP, net.IP, error) {
tunIface, err := net.InterfaceByName(tunName)
func GetTunDeviceIP(tunName string) (net.IP, net.IP, error) {
tunIfi, err := net.InterfaceByName(tunName)
if err != nil {
return nil, nil, err
}
addrs, err := tunIface.Addrs()
addrList, err := tunIfi.Addrs()
if err != nil {
return nil, nil, err
}
var srcIPv4, srcIPv6 net.IP
for _, addr := range addrs {
ip, _, err := net.ParseCIDR(addr.String())
if err != nil {
continue
}
if ip.To4() != nil {
srcIPv4 = ip
} else {
srcIPv6 = ip
for _, addr := range addrList {
if ipNet, ok := addr.(*net.IPNet); ok {
if config.CIDR.Contains(ipNet.IP) || config.CIDR6.Contains(ipNet.IP) || config.DockerCIDR.Contains(ipNet.IP) {
if ipNet.IP.To4() != nil {
srcIPv4 = ipNet.IP
} else {
srcIPv6 = ipNet.IP
}
}
}
}
if srcIPv4 == nil || srcIPv6 == nil {
return srcIPv4, srcIPv6, fmt.Errorf("not found all ip")
if srcIPv4 == nil && srcIPv6 == nil {
return srcIPv4, srcIPv6, fmt.Errorf("can not found any ip")
}
return srcIPv4, srcIPv6, nil
}
func PingOnce(ctx context.Context, srcIP, dstIP string) (bool, error) {
pinger, err := probing.NewPinger(dstIP)
if err != nil {
return false, err
}
pinger.Source = srcIP
pinger.SetLogger(nil)
pinger.SetPrivileged(true)
pinger.Count = 1
pinger.Timeout = time.Second * 1
pinger.ResolveTimeout = time.Second * 1
err = pinger.RunWithContext(ctx) // Blocks until finished.
if err != nil {
return false, err
}
stat := pinger.Statistics()
return stat.PacketsRecv == stat.PacketsSent, err
}
func Ping(ctx context.Context, srcIP, dstIP string) (bool, error) {
pinger, err := probing.NewPinger(dstIP)
if err != nil {
@@ -95,8 +108,9 @@ func Ping(ctx context.Context, srcIP, dstIP string) (bool, error) {
pinger.Source = srcIP
pinger.SetLogger(nil)
pinger.SetPrivileged(true)
pinger.Count = 3
pinger.Timeout = time.Millisecond * 1500
pinger.Count = 4
pinger.Timeout = time.Second * 4
pinger.ResolveTimeout = time.Second * 1
err = pinger.RunWithContext(ctx) // Blocks until finished.
if err != nil {
return false, err
@@ -113,6 +127,24 @@ func IsIPv6(packet []byte) bool {
return 6 == (packet[0] >> 4)
}
func ParseIP(packet []byte) (src net.IP, dst net.IP, err error) {
if IsIPv4(packet) {
header, err := ipv4.ParseHeader(packet)
if err != nil {
return nil, nil, err
}
return header.Src, header.Dst, nil
}
if IsIPv6(packet) {
header, err := ipv6.ParseHeader(packet)
if err != nil {
return nil, nil, err
}
return header.Src, header.Dst, nil
}
return nil, nil, errors.New("packet is invalid")
}
func GetIPBaseNic() (*net.IPNet, error) {
addrs, _ := net.InterfaceAddrs()
var sum int
@@ -154,3 +186,57 @@ func getIP(addr net.Addr) net.IP {
}
return ip
}
func GenICMPPacket(src net.IP, dst net.IP) ([]byte, error) {
buf := gopacket.NewSerializeBuffer()
var id uint16
for _, b := range src {
id += uint16(b)
}
icmpLayer := layers.ICMPv4{
TypeCode: layers.CreateICMPv4TypeCode(layers.ICMPv4TypeEchoRequest, 0),
Id: id,
Seq: uint16(rand.Intn(math.MaxUint16 + 1)),
}
ipLayer := layers.IPv4{
Version: 4,
SrcIP: src,
DstIP: dst,
Protocol: layers.IPProtocolICMPv4,
Flags: layers.IPv4DontFragment,
TTL: 64,
IHL: 5,
Id: uint16(rand.Intn(math.MaxUint16 + 1)),
}
opts := gopacket.SerializeOptions{
FixLengths: true,
ComputeChecksums: true,
}
err := gopacket.SerializeLayers(buf, opts, &ipLayer, &icmpLayer)
if err != nil {
return nil, fmt.Errorf("failed to serialize icmp packet, err: %v", err)
}
return buf.Bytes(), nil
}
func GenICMPPacketIPv6(src net.IP, dst net.IP) ([]byte, error) {
buf := gopacket.NewSerializeBuffer()
icmpLayer := layers.ICMPv6{
TypeCode: layers.CreateICMPv6TypeCode(layers.ICMPv6TypeEchoRequest, 0),
}
ipLayer := layers.IPv6{
Version: 6,
SrcIP: src,
DstIP: dst,
NextHeader: layers.IPProtocolICMPv6,
HopLimit: 255,
}
opts := gopacket.SerializeOptions{
FixLengths: true,
}
err := gopacket.SerializeLayers(buf, opts, &ipLayer, &icmpLayer)
if err != nil {
return nil, fmt.Errorf("failed to serialize icmp6 packet, err: %v", err)
}
return buf.Bytes(), nil
}

View File

@@ -6,4 +6,7 @@ import (
"context"
)
func DeleteBlockFirewallRule(ctx context.Context) {}
func DeleteBlockFirewallRule(ctx context.Context) {}
func DeleteAllowFirewallRule(ctx context.Context) {}
func FindAllowFirewallRule(ctx context.Context) bool { return false }
func AddAllowFirewallRule(ctx context.Context) {}

View File

@@ -5,10 +5,14 @@ package util
import (
"context"
"os/exec"
"strings"
"syscall"
"time"
log "github.com/sirupsen/logrus"
"golang.org/x/text/encoding/simplifiedchinese"
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
)
/**
@@ -88,3 +92,77 @@ func decode(in []byte) ([]byte, error) {
}
return nil, err
}
// AddAllowFirewallRule
// for ping local tun device ip, if not add this firewall, can not ping local tun IP on windows
func AddAllowFirewallRule(ctx context.Context) {
// netsh advfirewall firewall add rule name=kubevpn-traffic-manager dir=in action=allow enable=yes remoteip=223.254.0.100/16,efff:ffff:ffff:ffff:ffff:ffff:ffff:9999/64,LocalSubnet
cmd := exec.CommandContext(ctx, "netsh", []string{
"advfirewall",
"firewall",
"add",
"rule",
"name=" + config.ConfigMapPodTrafficManager,
"dir=in",
"action=allow",
"enable=yes",
"remoteip=" + strings.Join([]string{config.CIDR.String(), config.CIDR6.String(), config.DockerCIDR.String(), "LocalSubnet"}, ","),
}...)
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
if out, err := cmd.CombinedOutput(); err != nil {
var s string
var b []byte
if b, err = decode(out); err == nil {
s = string(b)
} else {
s = string(out)
}
log.Infof("Failed to exec command: %s, output: %s", cmd.Args, s)
}
}
func DeleteAllowFirewallRule(ctx context.Context) {
// netsh advfirewall firewall delete rule name=kubevpn-traffic-manager
cmd := exec.CommandContext(ctx, "netsh", []string{
"advfirewall",
"firewall",
"delete",
"rule",
"name=" + config.ConfigMapPodTrafficManager,
}...)
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
if out, err := cmd.CombinedOutput(); err != nil {
var s string
var b []byte
if b, err = decode(out); err == nil {
s = string(b)
} else {
s = string(out)
}
log.Errorf("Failed to exec command: %s, output: %s", cmd.Args, s)
}
}
func FindAllowFirewallRule(ctx context.Context) bool {
// netsh advfirewall firewall show rule name=kubevpn-traffic-manager
cmd := exec.CommandContext(ctx, "netsh", []string{
"advfirewall",
"firewall",
"show",
"rule",
"name=" + config.ConfigMapPodTrafficManager,
}...)
cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true}
out, err := cmd.CombinedOutput()
if err != nil {
s := string(out)
var b []byte
if b, err = decode(out); err == nil {
s = string(b)
}
log.Debugf("Find firewall %s, output: %s", config.ConfigMapPodTrafficManager, s)
return false
} else {
return true
}
}

View File

@@ -18,14 +18,12 @@ import (
"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
corev1 "k8s.io/api/core/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/fields"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/httpstream"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/cli-runtime/pkg/genericiooptions"
"k8s.io/cli-runtime/pkg/resource"
@@ -171,11 +169,20 @@ func PortForwardPod(config *rest.Config, clientset *rest.RESTClient, podName, na
return err
}
if err = forwarder.ForwardPorts(); err != nil {
log.Debugf("Forward port error: %s", err.Error())
defer forwarder.Close()
var errChan = make(chan error, 1)
go func() {
errChan <- forwarder.ForwardPorts()
}()
select {
case err = <-errChan:
log.Debugf("Forward port error: %v", err)
return err
case <-stopChan:
return nil
}
return nil
}
func GetTopOwnerReference(factory util.Factory, ns, workload string) (*resource.Info, error) {
@@ -330,36 +337,42 @@ func FindContainerByName(pod *corev1.Pod, name string) (*corev1.Container, int)
}
func CheckPodStatus(ctx context.Context, cancelFunc context.CancelFunc, podName string, podInterface v12.PodInterface) {
var verifyAPIServerConnection = func() {
err := retry.OnError(
retry.DefaultBackoff,
func(err error) bool {
return err != nil
},
func() error {
ctx1, cancelFunc1 := context.WithTimeout(ctx, time.Second*10)
defer cancelFunc1()
_, err := podInterface.Get(ctx1, podName, v1.GetOptions{})
return err
})
if err != nil {
log.Debugf("Failed to get Pod %s: %v", podName, err)
cancelFunc()
}
}
for ctx.Err() == nil {
func() {
defer time.Sleep(time.Millisecond * 200)
defer time.Sleep(time.Second * 5)
w, err := podInterface.Watch(ctx, v1.ListOptions{
FieldSelector: fields.OneTermEqualSelector("metadata.name", podName).String(),
})
if err != nil {
if !k8serrors.IsForbidden(err) && !errors.Is(err, context.Canceled) {
log.Debugf("Failed to watch Pod %s: %v", podName, err)
}
log.Debugf("Failed to watch Pod %s: %v", podName, err)
return
}
defer w.Stop()
_, err = podInterface.Get(ctx, podName, v1.GetOptions{})
if err != nil {
if !k8serrors.IsForbidden(err) && !errors.Is(err, context.Canceled) {
log.Debugf("Failed to get Pod %s: %v", podName, err)
}
return
}
verifyAPIServerConnection()
select {
case e, ok := <-w.ResultChan():
if !ok {
_, err = podInterface.Get(ctx, podName, v1.GetOptions{})
if err != nil && !errors.Is(err, context.Canceled) {
log.Debugf("Failed to get Pod %s: %v", podName, err)
cancelFunc()
}
verifyAPIServerConnection()
return
}
switch e.Type {
@@ -368,11 +381,7 @@ func CheckPodStatus(ctx context.Context, cancelFunc context.CancelFunc, podName
cancelFunc()
return
case watch.Error:
_, err = podInterface.Get(ctx, podName, v1.GetOptions{})
if err != nil && !errors.Is(err, context.Canceled) {
log.Debugf("Failed to get Pod %s: %v", podName, err)
cancelFunc()
}
verifyAPIServerConnection()
return
case watch.Added, watch.Modified, watch.Bookmark:
// do nothing
@@ -397,25 +406,14 @@ func CheckPortStatus(ctx context.Context, cancelFunc context.CancelFunc, readyCh
}
for ctx.Err() == nil {
err := retry.OnError(wait.Backoff{
Steps: 6,
Duration: time.Second,
}, func(err error) bool {
return err != nil
}, func() error {
var lc net.ListenConfig
conn, err := lc.Listen(ctx, "tcp", net.JoinHostPort("127.0.0.1", localGvisorTCPPort))
if err == nil {
_ = conn.Close()
return errors.New("port is free")
}
return nil
})
if err != nil {
log.Debugf("Can not dial local port: %s: %v", localGvisorTCPPort, err)
var lc net.ListenConfig
conn, err := lc.Listen(ctx, "tcp", net.JoinHostPort("127.0.0.1", localGvisorTCPPort))
if err == nil {
_ = conn.Close()
log.Debugf("Local port: %s is free", localGvisorTCPPort)
return
}
time.Sleep(time.Second * 5)
time.Sleep(time.Second * 1)
}
}

View File

@@ -298,6 +298,10 @@ func StartupPProf(port int) {
_ = http.ListenAndServe(fmt.Sprintf("localhost:%d", port), nil)
}
func StartupPProfForServer(port int) {
_ = http.ListenAndServe(fmt.Sprintf(":%d", port), nil)
}
func Merge[K comparable, V any](fromMap, ToMap map[K]V) map[K]V {
if fromMap == nil {
return ToMap

View File

@@ -3,7 +3,7 @@ kind: Plugin
metadata:
name: kubevpn
spec:
version: v2.2.20
version: v2.3.1
homepage: https://github.com/kubenetworks/kubevpn
shortDescription: "KubeVPN offers a Cloud Native Dev Environment that connects to kubernetes cluster network"
description: |
@@ -16,8 +16,8 @@ spec:
matchLabels:
os: windows
arch: amd64
uri: https://github.com/kubenetworks/kubevpn/releases/download/v2.2.20/kubevpn_v2.2.20_windows_amd64.zip
sha256: d54bccd5e13d079250cee370929693991d6e20f9427a530c5170e61685c41f4d
uri: https://github.com/kubenetworks/kubevpn/releases/download/v2.3.1/kubevpn_v2.3.1_windows_amd64.zip
sha256: 7b4cf616362611ef839b1f8e08712c5f49f151e48838d9748d8ee243f1201a60
files:
- from: ./bin/kubevpn.exe
to: .
@@ -28,8 +28,8 @@ spec:
matchLabels:
os: windows
arch: arm64
uri: https://github.com/kubenetworks/kubevpn/releases/download/v2.2.20/kubevpn_v2.2.20_windows_arm64.zip
sha256: b370fc74e0df4025cab7757ef9b949781e0055e882b874af73d0c24636da1399
uri: https://github.com/kubenetworks/kubevpn/releases/download/v2.3.1/kubevpn_v2.3.1_windows_arm64.zip
sha256: 844dd52d51c573691b76795c538dfa86bd55f5360e85db43f6a65386b3cf7841
files:
- from: ./bin/kubevpn.exe
to: .
@@ -40,8 +40,8 @@ spec:
matchLabels:
os: windows
arch: 386
uri: https://github.com/kubenetworks/kubevpn/releases/download/v2.2.20/kubevpn_v2.2.20_windows_386.zip
sha256: 95a71cb998799003a33dcd15443de25062dd086359aca5e4c4066cc1891fc431
uri: https://github.com/kubenetworks/kubevpn/releases/download/v2.3.1/kubevpn_v2.3.1_windows_386.zip
sha256: 74efa7f1a45b7373f07b13604caba497e838e60ec896da198f5df2e1b810bb18
files:
- from: ./bin/kubevpn.exe
to: .
@@ -52,8 +52,8 @@ spec:
matchLabels:
os: linux
arch: amd64
uri: https://github.com/kubenetworks/kubevpn/releases/download/v2.2.20/kubevpn_v2.2.20_linux_amd64.zip
sha256: ceeee8a023d3a080970864173b6c9cd9a5f20c6741713d39f683f7ee13fbf980
uri: https://github.com/kubenetworks/kubevpn/releases/download/v2.3.1/kubevpn_v2.3.1_linux_amd64.zip
sha256: 6994501aa08c9257fcc025326ff76ecfd9c401cf69cb1894d8111ba50534c328
files:
- from: ./bin/kubevpn
to: .
@@ -64,8 +64,8 @@ spec:
matchLabels:
os: linux
arch: arm64
uri: https://github.com/kubenetworks/kubevpn/releases/download/v2.2.20/kubevpn_v2.2.20_linux_arm64.zip
sha256: 5581a1f20c63dca61f901fa85aafe497372871349528d816a4d0b5d946e58f04
uri: https://github.com/kubenetworks/kubevpn/releases/download/v2.3.1/kubevpn_v2.3.1_linux_arm64.zip
sha256: a59edb8c34cd60ba04278dc19da1e0551aa782d4ca7023196e9e48ba3afb3002
files:
- from: ./bin/kubevpn
to: .
@@ -76,8 +76,8 @@ spec:
matchLabels:
os: linux
arch: 386
uri: https://github.com/kubenetworks/kubevpn/releases/download/v2.2.20/kubevpn_v2.2.20_linux_386.zip
sha256: d5a106eb7fbee7e49e00570d271ecb5ee9497bade2b14771548204636ea72d9e
uri: https://github.com/kubenetworks/kubevpn/releases/download/v2.3.1/kubevpn_v2.3.1_linux_386.zip
sha256: 7fedeb94fd8f67d9e83ec6ef7204d6da07d108a00c41565a209493d93732f889
files:
- from: ./bin/kubevpn
to: .
@@ -88,8 +88,8 @@ spec:
matchLabels:
os: darwin
arch: amd64
uri: https://github.com/kubenetworks/kubevpn/releases/download/v2.2.20/kubevpn_v2.2.20_darwin_amd64.zip
sha256: 4677eadd64062923218db1bdd272a20bff845f6a78fa2c9eecc8bce14e0b8c32
uri: https://github.com/kubenetworks/kubevpn/releases/download/v2.3.1/kubevpn_v2.3.1_darwin_amd64.zip
sha256: 872c98c254cba35f43d1bd226165c2a9c41c7f4d5f5780e63e79569585df32a1
files:
- from: ./bin/kubevpn
to: .
@@ -100,8 +100,8 @@ spec:
matchLabels:
os: darwin
arch: arm64
uri: https://github.com/kubenetworks/kubevpn/releases/download/v2.2.20/kubevpn_v2.2.20_darwin_arm64.zip
sha256: aba8160774b52f3c5f4526c233eb7dd021d41c1c4b2d1af8a35ded6ae152cf6b
uri: https://github.com/kubenetworks/kubevpn/releases/download/v2.3.1/kubevpn_v2.3.1_darwin_arm64.zip
sha256: c6fcbc0ef6b55cbb508ad13459c0789b87db8bea2354fb9a9bb478647a495e56
files:
- from: ./bin/kubevpn
to: .

View File

@@ -1 +1 @@
v2.2.20
v2.3.1