mirror of
https://github.com/kubenetworks/kubevpn.git
synced 2025-10-19 13:44:40 +08:00
@@ -39,17 +39,15 @@ spec:
|
|||||||
sysctl -w net.ipv6.conf.all.disable_ipv6=0
|
sysctl -w net.ipv6.conf.all.disable_ipv6=0
|
||||||
sysctl -w net.ipv6.conf.all.forwarding=1
|
sysctl -w net.ipv6.conf.all.forwarding=1
|
||||||
update-alternatives --set iptables /usr/sbin/iptables-legacy
|
update-alternatives --set iptables /usr/sbin/iptables-legacy
|
||||||
iptables -F
|
|
||||||
ip6tables -F
|
|
||||||
iptables -P INPUT ACCEPT
|
iptables -P INPUT ACCEPT
|
||||||
ip6tables -P INPUT ACCEPT
|
ip6tables -P INPUT ACCEPT
|
||||||
iptables -P FORWARD ACCEPT
|
iptables -P FORWARD ACCEPT
|
||||||
ip6tables -P FORWARD ACCEPT
|
ip6tables -P FORWARD ACCEPT
|
||||||
iptables -t nat -A POSTROUTING -s ${CIDR4} -o eth0 -j MASQUERADE
|
iptables -t nat -A POSTROUTING -s ${CIDR4} -o eth0 -j MASQUERADE
|
||||||
ip6tables -t nat -A POSTROUTING -s ${CIDR6} -o eth0 -j MASQUERADE
|
ip6tables -t nat -A POSTROUTING -s ${CIDR6} -o eth0 -j MASQUERADE
|
||||||
kubevpn server -L "tcp://:10800" -L "tun://:8422?net=${TunIPv4}" -L "gtcp://:10801" -L "gudp://:10802" --debug=true
|
kubevpn server -l "tcp://:10800" -l "tun://:8422?net=${TunIPv4}&net6=${TunIPv6}" -l "gtcp://:10801" -l "gudp://:10802" --debug=true
|
||||||
{{- else }}
|
{{- else }}
|
||||||
- kubevpn server -L "tcp://:10800" -L "gtcp://:10801" -L "gudp://:10802" --debug=true
|
- kubevpn server -l "tcp://:10800" -l "gtcp://:10801" -l "gudp://:10802" --debug=true
|
||||||
{{- end }}
|
{{- end }}
|
||||||
command:
|
command:
|
||||||
- /bin/sh
|
- /bin/sh
|
||||||
|
@@ -17,7 +17,7 @@ import (
|
|||||||
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CmdControlPlane(_ cmdutil.Factory) *cobra.Command {
|
func CmdControlPlane(cmdutil.Factory) *cobra.Command {
|
||||||
var (
|
var (
|
||||||
watchDirectoryFilename string
|
watchDirectoryFilename string
|
||||||
port uint = 9002
|
port uint = 9002
|
||||||
|
@@ -21,7 +21,7 @@ import (
|
|||||||
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CmdDaemon(_ cmdutil.Factory) *cobra.Command {
|
func CmdDaemon(cmdutil.Factory) *cobra.Command {
|
||||||
var opt = &daemon.SvrOption{}
|
var opt = &daemon.SvrOption{}
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "daemon",
|
Use: "daemon",
|
||||||
|
@@ -8,7 +8,7 @@ import (
|
|||||||
"github.com/wencaiwulue/kubevpn/v2/pkg/util/regctl"
|
"github.com/wencaiwulue/kubevpn/v2/pkg/util/regctl"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CmdImageCopy(_ cmdutil.Factory) *cobra.Command {
|
func CmdImageCopy(cmdutil.Factory) *cobra.Command {
|
||||||
var imageCmd = &cobra.Command{
|
var imageCmd = &cobra.Command{
|
||||||
Use: "image <cmd>",
|
Use: "image <cmd>",
|
||||||
Short: "copy images",
|
Short: "copy images",
|
||||||
|
@@ -20,7 +20,7 @@ import (
|
|||||||
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CmdServer(_ cmdutil.Factory) *cobra.Command {
|
func CmdServer(cmdutil.Factory) *cobra.Command {
|
||||||
var route = &core.Route{}
|
var route = &core.Route{}
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "server",
|
Use: "server",
|
||||||
@@ -30,8 +30,8 @@ func CmdServer(_ cmdutil.Factory) *cobra.Command {
|
|||||||
Server side, startup traffic manager, forward inbound and outbound traffic.
|
Server side, startup traffic manager, forward inbound and outbound traffic.
|
||||||
`)),
|
`)),
|
||||||
Example: templates.Examples(i18n.T(`
|
Example: templates.Examples(i18n.T(`
|
||||||
# server node
|
# server listener
|
||||||
kubevpn server -L "tcp://:10800" -L "tun://127.0.0.1:8422?net=198.19.0.123/32"
|
kubevpn server -l "tcp://:10800" -l "tun://127.0.0.1:8422?net=198.19.0.123/32"
|
||||||
`)),
|
`)),
|
||||||
PreRun: func(*cobra.Command, []string) {
|
PreRun: func(*cobra.Command, []string) {
|
||||||
runtime.GOMAXPROCS(0)
|
runtime.GOMAXPROCS(0)
|
||||||
@@ -50,8 +50,8 @@ func CmdServer(_ cmdutil.Factory) *cobra.Command {
|
|||||||
return handler.Run(ctx, servers)
|
return handler.Run(ctx, servers)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cmd.Flags().StringArrayVarP(&route.ServeNodes, "node", "L", []string{}, "Startup node server. eg: tcp://localhost:1080")
|
cmd.Flags().StringArrayVarP(&route.Listeners, "listener", "l", []string{}, "Startup listener server. eg: tcp://localhost:1080")
|
||||||
cmd.Flags().StringVarP(&route.ChainNode, "chain", "F", "", "Forward chain. eg: tcp://192.168.1.100:2345")
|
cmd.Flags().StringVarP(&route.Forwarder, "forwarder", "f", "", "Special forwarder. eg: tcp://192.168.1.100:2345")
|
||||||
cmd.Flags().BoolVar(&config.Debug, "debug", false, "Enable debug log or not")
|
cmd.Flags().BoolVar(&config.Debug, "debug", false, "Enable debug log or not")
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
@@ -27,7 +27,7 @@ import (
|
|||||||
|
|
||||||
// CmdSSH
|
// CmdSSH
|
||||||
// Remember to use network mask 32, because ssh using unique network CIDR 198.18.0.0/16
|
// Remember to use network mask 32, because ssh using unique network CIDR 198.18.0.0/16
|
||||||
func CmdSSH(_ cmdutil.Factory) *cobra.Command {
|
func CmdSSH(cmdutil.Factory) *cobra.Command {
|
||||||
var sshConf = &pkgssh.SshConfig{}
|
var sshConf = &pkgssh.SshConfig{}
|
||||||
var extraCIDR []string
|
var extraCIDR []string
|
||||||
var platform string
|
var platform string
|
||||||
|
@@ -15,7 +15,7 @@ import (
|
|||||||
|
|
||||||
// CmdSSHDaemon
|
// CmdSSHDaemon
|
||||||
// set local tun ip 198.19.0.1/32, remember to use mask 32
|
// set local tun ip 198.19.0.1/32, remember to use mask 32
|
||||||
func CmdSSHDaemon(_ cmdutil.Factory) *cobra.Command {
|
func CmdSSHDaemon(cmdutil.Factory) *cobra.Command {
|
||||||
var clientIP string
|
var clientIP string
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "ssh-daemon",
|
Use: "ssh-daemon",
|
||||||
|
@@ -10,7 +10,7 @@ import (
|
|||||||
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CmdSyncthing(_ cmdutil.Factory) *cobra.Command {
|
func CmdSyncthing(cmdutil.Factory) *cobra.Command {
|
||||||
var detach bool
|
var detach bool
|
||||||
var dir string
|
var dir string
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
|
@@ -16,7 +16,7 @@ import (
|
|||||||
"github.com/wencaiwulue/kubevpn/v2/pkg/upgrade"
|
"github.com/wencaiwulue/kubevpn/v2/pkg/upgrade"
|
||||||
)
|
)
|
||||||
|
|
||||||
func CmdUpgrade(_ cmdutil.Factory) *cobra.Command {
|
func CmdUpgrade(cmdutil.Factory) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "upgrade",
|
Use: "upgrade",
|
||||||
Short: i18n.T("Upgrade kubevpn client to latest version"),
|
Short: i18n.T("Upgrade kubevpn client to latest version"),
|
||||||
|
@@ -160,7 +160,7 @@ var (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
KeepAliveTime = 180 * time.Second
|
KeepAliveTime = 60 * time.Second
|
||||||
DialTimeout = 15 * time.Second
|
DialTimeout = 15 * time.Second
|
||||||
HandshakeTimeout = 5 * time.Second
|
HandshakeTimeout = 5 * time.Second
|
||||||
ConnectTimeout = 5 * time.Second
|
ConnectTimeout = 5 * time.Second
|
||||||
|
@@ -3,34 +3,33 @@ package core
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"math"
|
|
||||||
"net"
|
"net"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// ErrorEmptyChain is an error that implies the chain is empty.
|
// ErrorEmptyForwarder is an error that implies the forward is empty.
|
||||||
ErrorEmptyChain = errors.New("empty chain")
|
ErrorEmptyForwarder = errors.New("empty forwarder")
|
||||||
)
|
)
|
||||||
|
|
||||||
type Chain struct {
|
type Forwarder struct {
|
||||||
retries int
|
retries int
|
||||||
node *Node
|
node *Node
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewChain(retry int, node *Node) *Chain {
|
func NewForwarder(retry int, node *Node) *Forwarder {
|
||||||
return &Chain{retries: retry, node: node}
|
return &Forwarder{retries: retry, node: node}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Chain) Node() *Node {
|
func (c *Forwarder) Node() *Node {
|
||||||
return c.node
|
return c.node
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Chain) IsEmpty() bool {
|
func (c *Forwarder) IsEmpty() bool {
|
||||||
return c == nil || c.node == nil
|
return c == nil || c.node == nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Chain) DialContext(ctx context.Context) (conn net.Conn, err error) {
|
func (c *Forwarder) DialContext(ctx context.Context) (conn net.Conn, err error) {
|
||||||
for i := 0; i < int(math.Max(float64(1), float64(c.retries))); i++ {
|
for i := 0; i < max(1, c.retries); i++ {
|
||||||
conn, err = c.dial(ctx)
|
conn, err = c.dial(ctx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
break
|
break
|
||||||
@@ -39,9 +38,9 @@ func (c *Chain) DialContext(ctx context.Context) (conn net.Conn, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Chain) dial(ctx context.Context) (net.Conn, error) {
|
func (c *Forwarder) dial(ctx context.Context) (net.Conn, error) {
|
||||||
if c.IsEmpty() {
|
if c.IsEmpty() {
|
||||||
return nil, ErrorEmptyChain
|
return nil, ErrorEmptyForwarder
|
||||||
}
|
}
|
||||||
|
|
||||||
conn, err := c.getConn(ctx)
|
conn, err := c.getConn(ctx)
|
||||||
@@ -58,7 +57,7 @@ func (c *Chain) dial(ctx context.Context) (net.Conn, error) {
|
|||||||
return cc, nil
|
return cc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (*Chain) resolve(addr string) string {
|
func (*Forwarder) resolve(addr string) string {
|
||||||
if host, port, err := net.SplitHostPort(addr); err == nil {
|
if host, port, err := net.SplitHostPort(addr); err == nil {
|
||||||
if ips, err := net.LookupIP(host); err == nil && len(ips) > 0 {
|
if ips, err := net.LookupIP(host); err == nil && len(ips) > 0 {
|
||||||
return net.JoinHostPort(ips[0].String(), port)
|
return net.JoinHostPort(ips[0].String(), port)
|
||||||
@@ -67,9 +66,9 @@ func (*Chain) resolve(addr string) string {
|
|||||||
return addr
|
return addr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Chain) getConn(ctx context.Context) (net.Conn, error) {
|
func (c *Forwarder) getConn(ctx context.Context) (net.Conn, error) {
|
||||||
if c.IsEmpty() {
|
if c.IsEmpty() {
|
||||||
return nil, ErrorEmptyChain
|
return nil, ErrorEmptyForwarder
|
||||||
}
|
}
|
||||||
return c.Node().Client.Dial(ctx, c.resolve(c.Node().Addr))
|
return c.Node().Client.Dial(ctx, c.resolve(c.Node().Addr))
|
||||||
}
|
}
|
@@ -18,7 +18,7 @@ import (
|
|||||||
type gvisorTCPHandler struct {
|
type gvisorTCPHandler struct {
|
||||||
// map[srcIP]net.Conn
|
// map[srcIP]net.Conn
|
||||||
routeMapTCP *sync.Map
|
routeMapTCP *sync.Map
|
||||||
packetChan chan *datagramPacket
|
packetChan chan *DatagramPacket
|
||||||
}
|
}
|
||||||
|
|
||||||
func GvisorTCPHandler() Handler {
|
func GvisorTCPHandler() Handler {
|
||||||
@@ -32,7 +32,7 @@ func (h *gvisorTCPHandler) Handle(ctx context.Context, tcpConn net.Conn) {
|
|||||||
defer tcpConn.Close()
|
defer tcpConn.Close()
|
||||||
cancel, cancelFunc := context.WithCancel(ctx)
|
cancel, cancelFunc := context.WithCancel(ctx)
|
||||||
defer cancelFunc()
|
defer cancelFunc()
|
||||||
plog.G(ctx).Debugf("[TCP] %s -> %s", tcpConn.RemoteAddr(), tcpConn.LocalAddr())
|
plog.G(ctx).Debugf("[TUN-GVISOR] %s -> %s", tcpConn.RemoteAddr(), tcpConn.LocalAddr())
|
||||||
h.handle(cancel, tcpConn)
|
h.handle(cancel, tcpConn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -20,7 +20,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (h *gvisorTCPHandler) readFromEndpointWriteToTCPConn(ctx context.Context, conn net.Conn, endpoint *channel.Endpoint) {
|
func (h *gvisorTCPHandler) readFromEndpointWriteToTCPConn(ctx context.Context, conn net.Conn, endpoint *channel.Endpoint) {
|
||||||
tcpConn, _ := newGvisorFakeUDPTunnelConnOverTCP(ctx, conn)
|
tcpConn, _ := newGvisorUDPConnOverTCP(ctx, conn)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
@@ -34,7 +34,7 @@ func (h *gvisorTCPHandler) readFromEndpointWriteToTCPConn(ctx context.Context, c
|
|||||||
buf := pktBuffer.ToView().AsSlice()
|
buf := pktBuffer.ToView().AsSlice()
|
||||||
_, err := tcpConn.Write(buf)
|
_, err := tcpConn.Write(buf)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
plog.G(ctx).Errorf("[TUN] Failed to write data to tun device: %v", err)
|
plog.G(ctx).Errorf("[TUN-GVISOR] Failed to write data to tun device: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,7 +42,9 @@ func (h *gvisorTCPHandler) readFromEndpointWriteToTCPConn(ctx context.Context, c
|
|||||||
|
|
||||||
// tun --> dispatcher
|
// tun --> dispatcher
|
||||||
func (h *gvisorTCPHandler) readFromTCPConnWriteToEndpoint(ctx context.Context, conn net.Conn, endpoint *channel.Endpoint) {
|
func (h *gvisorTCPHandler) readFromTCPConnWriteToEndpoint(ctx context.Context, conn net.Conn, endpoint *channel.Endpoint) {
|
||||||
tcpConn, _ := newGvisorFakeUDPTunnelConnOverTCP(ctx, conn)
|
tcpConn, _ := newGvisorUDPConnOverTCP(ctx, conn)
|
||||||
|
defer h.removeFromRouteMapTCP(ctx, conn)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
@@ -53,12 +55,12 @@ func (h *gvisorTCPHandler) readFromTCPConnWriteToEndpoint(ctx context.Context, c
|
|||||||
buf := config.LPool.Get().([]byte)[:]
|
buf := config.LPool.Get().([]byte)[:]
|
||||||
read, err := tcpConn.Read(buf[:])
|
read, err := tcpConn.Read(buf[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
plog.G(ctx).Errorf("[TUN] Failed to read from tcp conn: %v", err)
|
plog.G(ctx).Errorf("[TUN-GVISOR] Failed to read from tcp conn: %v", err)
|
||||||
config.LPool.Put(buf[:])
|
config.LPool.Put(buf[:])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if read == 0 {
|
if read == 0 {
|
||||||
plog.G(ctx).Warnf("[TUN] Read from tcp conn length is %d", read)
|
plog.G(ctx).Warnf("[TUN-GVISOR] Read from tcp conn length is %d", read)
|
||||||
config.LPool.Put(buf[:])
|
config.LPool.Put(buf[:])
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -83,7 +85,7 @@ func (h *gvisorTCPHandler) readFromTCPConnWriteToEndpoint(ctx context.Context, c
|
|||||||
protocol = header.IPv6ProtocolNumber
|
protocol = header.IPv6ProtocolNumber
|
||||||
ipHeader, err := ipv6.ParseHeader(buf[:read])
|
ipHeader, err := ipv6.ParseHeader(buf[:read])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
plog.G(ctx).Errorf("Failed to parse IPv6 header: %s", err.Error())
|
plog.G(ctx).Errorf("[TUN-GVISOR] Failed to parse IPv6 header: %s", err.Error())
|
||||||
config.LPool.Put(buf[:])
|
config.LPool.Put(buf[:])
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -96,11 +98,11 @@ func (h *gvisorTCPHandler) readFromTCPConnWriteToEndpoint(ctx context.Context, c
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
h.addRoute(ctx, src, conn)
|
h.addToRouteMapTCP(ctx, src, conn)
|
||||||
// inner ip like 198.19.0.100/102/103 connect each other
|
// inner ip like 198.19.0.100/102/103 connect each other
|
||||||
if config.CIDR.Contains(dst) || config.CIDR6.Contains(dst) {
|
if config.CIDR.Contains(dst) || config.CIDR6.Contains(dst) {
|
||||||
plog.G(ctx).Debugf("[TUN-RAW] Forward to TUN device, SRC: %s, DST: %s, Length: %d", src.String(), dst.String(), read)
|
plog.G(ctx).Debugf("[TUN-GVISOR] Forward to TUN device, SRC: %s, DST: %s, Length: %d", src.String(), dst.String(), read)
|
||||||
util.SafeWrite(h.packetChan, &datagramPacket{
|
util.SafeWrite(h.packetChan, &DatagramPacket{
|
||||||
DataLength: uint16(read),
|
DataLength: uint16(read),
|
||||||
Data: buf[:],
|
Data: buf[:],
|
||||||
})
|
})
|
||||||
@@ -115,18 +117,28 @@ func (h *gvisorTCPHandler) readFromTCPConnWriteToEndpoint(ctx context.Context, c
|
|||||||
sniffer.LogPacket("[gVISOR] ", sniffer.DirectionRecv, protocol, pkt)
|
sniffer.LogPacket("[gVISOR] ", sniffer.DirectionRecv, protocol, pkt)
|
||||||
endpoint.InjectInbound(protocol, pkt)
|
endpoint.InjectInbound(protocol, pkt)
|
||||||
pkt.DecRef()
|
pkt.DecRef()
|
||||||
plog.G(ctx).Debugf("[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)
|
plog.G(ctx).Debugf("[TUN-GVISOR] Write to Gvisor IP-Protocol: %s, SRC: %s, DST: %s, Length: %d", layers.IPProtocol(ipProtocol).String(), src.String(), dst, read)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *gvisorTCPHandler) addRoute(ctx context.Context, src net.IP, tcpConn net.Conn) {
|
func (h *gvisorTCPHandler) addToRouteMapTCP(ctx context.Context, src net.IP, tcpConn net.Conn) {
|
||||||
value, loaded := h.routeMapTCP.LoadOrStore(src.String(), tcpConn)
|
value, loaded := h.routeMapTCP.LoadOrStore(src.String(), tcpConn)
|
||||||
if loaded {
|
if loaded {
|
||||||
if tcpConn != value.(net.Conn) {
|
if tcpConn != value.(net.Conn) {
|
||||||
h.routeMapTCP.Store(src.String(), tcpConn)
|
h.routeMapTCP.Store(src.String(), tcpConn)
|
||||||
plog.G(ctx).Debugf("[TCP] Replace route map TCP: %s -> %s-%s", src, tcpConn.LocalAddr(), tcpConn.RemoteAddr())
|
plog.G(ctx).Debugf("[TUN-GVISOR] Replace route map TCP: %s -> %s-%s", src, tcpConn.LocalAddr(), tcpConn.RemoteAddr())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
plog.G(ctx).Debugf("[TCP] Add new route map TCP: %s -> %s-%s", src, tcpConn.LocalAddr(), tcpConn.RemoteAddr())
|
plog.G(ctx).Debugf("[TUN-GVISOR] Add new route map TCP: %s -> %s-%s", src, tcpConn.LocalAddr(), tcpConn.RemoteAddr())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *gvisorTCPHandler) removeFromRouteMapTCP(ctx context.Context, tcpConn net.Conn) {
|
||||||
|
h.routeMapTCP.Range(func(key, value any) bool {
|
||||||
|
if value.(net.Conn) == tcpConn {
|
||||||
|
h.routeMapTCP.Delete(key)
|
||||||
|
plog.G(ctx).Debugf("[TCP-GVISOR] Delete to DST %s by conn %s from globle route map TCP", key, tcpConn.LocalAddr())
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
@@ -44,17 +44,17 @@ func (h *gvisorUDPHandler) Handle(ctx context.Context, tcpConn net.Conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fake udp connect over tcp
|
// fake udp connect over tcp
|
||||||
type gvisorFakeUDPTunnelConn struct {
|
type gvisorUDPConnOverTCP struct {
|
||||||
// tcp connection
|
// tcp connection
|
||||||
net.Conn
|
net.Conn
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
func newGvisorFakeUDPTunnelConnOverTCP(ctx context.Context, conn net.Conn) (net.Conn, error) {
|
func newGvisorUDPConnOverTCP(ctx context.Context, conn net.Conn) (net.Conn, error) {
|
||||||
return &gvisorFakeUDPTunnelConn{ctx: ctx, Conn: conn}, nil
|
return &gvisorUDPConnOverTCP{ctx: ctx, Conn: conn}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *gvisorFakeUDPTunnelConn) Read(b []byte) (int, error) {
|
func (c *gvisorUDPConnOverTCP) Read(b []byte) (int, error) {
|
||||||
select {
|
select {
|
||||||
case <-c.ctx.Done():
|
case <-c.ctx.Done():
|
||||||
return 0, c.ctx.Err()
|
return 0, c.ctx.Err()
|
||||||
@@ -67,15 +67,15 @@ func (c *gvisorFakeUDPTunnelConn) Read(b []byte) (int, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *gvisorFakeUDPTunnelConn) Write(b []byte) (int, error) {
|
func (c *gvisorUDPConnOverTCP) Write(b []byte) (int, error) {
|
||||||
dgram := newDatagramPacket(b)
|
packet := newDatagramPacket(b)
|
||||||
if err := dgram.Write(c.Conn); err != nil {
|
if err := packet.Write(c.Conn); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return len(b), nil
|
return len(b), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *gvisorFakeUDPTunnelConn) Close() error {
|
func (c *gvisorUDPConnOverTCP) Close() error {
|
||||||
if cc, ok := c.Conn.(interface{ CloseRead() error }); ok {
|
if cc, ok := c.Conn.(interface{ CloseRead() error }); ok {
|
||||||
_ = cc.CloseRead()
|
_ = cc.CloseRead()
|
||||||
}
|
}
|
||||||
@@ -184,13 +184,13 @@ func handle(ctx context.Context, tcpConn net.Conn, udpConn *net.UDPConn) {
|
|||||||
errChan <- err
|
errChan <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
dgram := newDatagramPacket(buf[:n])
|
packet := newDatagramPacket(buf[:n])
|
||||||
if err = dgram.Write(tcpConn); err != nil {
|
if err = packet.Write(tcpConn); err != nil {
|
||||||
plog.G(ctx).Errorf("[TUN-UDP] Error: %s <- %s : %s", tcpConn.RemoteAddr(), dgram.Addr(), err)
|
plog.G(ctx).Errorf("[TUN-UDP] Error: %s <- %s : %s", tcpConn.RemoteAddr(), tcpConn.LocalAddr(), err)
|
||||||
errChan <- err
|
errChan <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
plog.G(ctx).Debugf("[TUN-UDP] %s <<< %s length: %d", tcpConn.RemoteAddr(), dgram.Addr(), len(dgram.Data))
|
plog.G(ctx).Debugf("[TUN-UDP] %s <<< %s length: %d", tcpConn.RemoteAddr(), tcpConn.LocalAddr(), len(packet.Data))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
err := <-errChan
|
err := <-errChan
|
||||||
|
@@ -4,14 +4,12 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/containernetworking/cni/pkg/types"
|
"github.com/containernetworking/cni/pkg/types"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
|
|
||||||
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
|
||||||
plog "github.com/wencaiwulue/kubevpn/v2/pkg/log"
|
plog "github.com/wencaiwulue/kubevpn/v2/pkg/log"
|
||||||
"github.com/wencaiwulue/kubevpn/v2/pkg/tun"
|
"github.com/wencaiwulue/kubevpn/v2/pkg/tun"
|
||||||
)
|
)
|
||||||
@@ -20,71 +18,63 @@ var (
|
|||||||
// RouteMapTCP map[srcIP]net.Conn Globe route table for inner ip
|
// RouteMapTCP map[srcIP]net.Conn Globe route table for inner ip
|
||||||
RouteMapTCP = &sync.Map{}
|
RouteMapTCP = &sync.Map{}
|
||||||
// TCPPacketChan tcp connects
|
// TCPPacketChan tcp connects
|
||||||
TCPPacketChan = make(chan *datagramPacket, MaxSize)
|
TCPPacketChan = make(chan *DatagramPacket, MaxSize)
|
||||||
)
|
)
|
||||||
|
|
||||||
type TCPUDPacket struct {
|
type TCPUDPacket struct {
|
||||||
data *datagramPacket
|
data *DatagramPacket
|
||||||
}
|
}
|
||||||
|
|
||||||
// Route example:
|
// Route example:
|
||||||
// -L "tcp://:10800" -L "tun://:8422?net=198.19.0.100/16"
|
// -l "tcp://:10800" -l "tun://:8422?net=198.19.0.100/16"
|
||||||
// -L "tun:/10.233.24.133:8422?net=198.19.0.102/16&route=198.19.0.0/16"
|
// -l "tun:/10.233.24.133:8422?net=198.19.0.102/16&route=198.19.0.0/16"
|
||||||
// -L "tun:/127.0.0.1:8422?net=198.19.0.102/16&route=198.19.0.0/16,10.233.0.0/16" -F "tcp://127.0.0.1:10800"
|
// -l "tun:/127.0.0.1:8422?net=198.19.0.102/16&route=198.19.0.0/16,10.233.0.0/16" -f "tcp://127.0.0.1:10800"
|
||||||
type Route struct {
|
type Route struct {
|
||||||
ServeNodes []string // -L tun
|
Listeners []string // -l tun
|
||||||
ChainNode string // -F tcp
|
Forwarder string // -f tcp
|
||||||
Retries int
|
Retries int
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Route) parseChain() (*Chain, error) {
|
func (r *Route) ParseForwarder() (*Forwarder, error) {
|
||||||
node, err := parseChainNode(r.ChainNode)
|
forwarder, err := ParseNode(r.Forwarder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return NewChain(r.Retries, node), nil
|
forwarder.Client = &Client{
|
||||||
}
|
Connector: NewUDPOverTCPConnector(),
|
||||||
|
|
||||||
func parseChainNode(ns string) (*Node, error) {
|
|
||||||
node, err := ParseNode(ns)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
node.Client = &Client{
|
|
||||||
Connector: UDPOverTCPTunnelConnector(),
|
|
||||||
Transporter: TCPTransporter(),
|
Transporter: TCPTransporter(),
|
||||||
}
|
}
|
||||||
return node, nil
|
return NewForwarder(r.Retries, forwarder), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Route) GenerateServers() ([]Server, error) {
|
func (r *Route) GenerateServers() ([]Server, error) {
|
||||||
chain, err := r.parseChain()
|
forwarder, err := r.ParseForwarder()
|
||||||
if err != nil && !errors.Is(err, ErrorInvalidNode) {
|
if err != nil && !errors.Is(err, ErrorInvalidNode) {
|
||||||
plog.G(context.Background()).Errorf("Failed to parse chain: %v", err)
|
plog.G(context.Background()).Errorf("Failed to parse forwarder: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
servers := make([]Server, 0, len(r.ServeNodes))
|
servers := make([]Server, 0, len(r.Listeners))
|
||||||
for _, serveNode := range r.ServeNodes {
|
for _, l := range r.Listeners {
|
||||||
var node *Node
|
var node *Node
|
||||||
node, err = ParseNode(serveNode)
|
node, err = ParseNode(l)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
plog.G(context.Background()).Errorf("Failed to parse node %s: %v", serveNode, err)
|
plog.G(context.Background()).Errorf("Failed to parse node %s: %v", l, err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var ln net.Listener
|
var listener net.Listener
|
||||||
var handler Handler
|
var handler Handler
|
||||||
|
|
||||||
switch node.Protocol {
|
switch node.Protocol {
|
||||||
case "tun":
|
case "tun":
|
||||||
handler = TunHandler(chain, node)
|
handler = TunHandler(forwarder, node)
|
||||||
ln, err = tun.Listener(tun.Config{
|
listener, err = tun.Listener(tun.Config{
|
||||||
Name: node.Get("name"),
|
Name: node.Get("name"),
|
||||||
Addr: node.Get("net"),
|
Addr: node.Get("net"),
|
||||||
Addr6: os.Getenv(config.EnvInboundPodTunIPv6),
|
Addr6: node.Get("net6"),
|
||||||
MTU: node.GetInt("mtu"),
|
MTU: node.GetInt("mtu"),
|
||||||
Routes: parseIPRoutes(node.Get("route")),
|
Routes: parseRoutes(node.Get("route")),
|
||||||
Gateway: node.Get("gw"),
|
Gateway: node.Get("gw"),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -93,28 +83,28 @@ func (r *Route) GenerateServers() ([]Server, error) {
|
|||||||
}
|
}
|
||||||
case "tcp":
|
case "tcp":
|
||||||
handler = TCPHandler()
|
handler = TCPHandler()
|
||||||
ln, err = TCPListener(node.Addr)
|
listener, err = TCPListener(node.Addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
plog.G(context.Background()).Errorf("Failed to create tcp listener: %v", err)
|
plog.G(context.Background()).Errorf("Failed to create tcp listener: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
case "gtcp":
|
case "gtcp":
|
||||||
handler = GvisorTCPHandler()
|
handler = GvisorTCPHandler()
|
||||||
ln, err = GvisorTCPListener(node.Addr)
|
listener, err = GvisorTCPListener(node.Addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
plog.G(context.Background()).Errorf("Failed to create gvisor tcp listener: %v", err)
|
plog.G(context.Background()).Errorf("Failed to create gvisor tcp listener: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
case "gudp":
|
case "gudp":
|
||||||
handler = GvisorUDPHandler()
|
handler = GvisorUDPHandler()
|
||||||
ln, err = GvisorUDPListener(node.Addr)
|
listener, err = GvisorUDPListener(node.Addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
plog.G(context.Background()).Errorf("Failed to create gvisor udp listener: %v", err)
|
plog.G(context.Background()).Errorf("Failed to create gvisor udp listener: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
case "ssh":
|
case "ssh":
|
||||||
handler = SSHHandler()
|
handler = SSHHandler()
|
||||||
ln, err = SSHListener(node.Addr)
|
listener, err = SSHListener(node.Addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
plog.G(context.Background()).Errorf("Failed to create ssh listener: %v", err)
|
plog.G(context.Background()).Errorf("Failed to create ssh listener: %v", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -123,21 +113,18 @@ func (r *Route) GenerateServers() ([]Server, error) {
|
|||||||
plog.G(context.Background()).Errorf("Not support protocol %s", node.Protocol)
|
plog.G(context.Background()).Errorf("Not support protocol %s", node.Protocol)
|
||||||
return nil, fmt.Errorf("not support protocol %s", node.Protocol)
|
return nil, fmt.Errorf("not support protocol %s", node.Protocol)
|
||||||
}
|
}
|
||||||
servers = append(servers, Server{Listener: ln, Handler: handler})
|
servers = append(servers, Server{Listener: listener, Handler: handler})
|
||||||
}
|
}
|
||||||
return servers, nil
|
return servers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseIPRoutes(routeStringList string) (routes []types.Route) {
|
func parseRoutes(str string) []types.Route {
|
||||||
if len(routeStringList) == 0 {
|
var routes []types.Route
|
||||||
return
|
list := strings.Split(str, ",")
|
||||||
}
|
for _, route := range list {
|
||||||
|
|
||||||
routeList := strings.Split(routeStringList, ",")
|
|
||||||
for _, route := range routeList {
|
|
||||||
if _, ipNet, _ := net.ParseCIDR(strings.TrimSpace(route)); ipNet != nil {
|
if _, ipNet, _ := net.ParseCIDR(strings.TrimSpace(route)); ipNet != nil {
|
||||||
routes = append(routes, types.Route{Dst: *ipNet})
|
routes = append(routes, types.Route{Dst: *ipNet})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return routes
|
||||||
}
|
}
|
||||||
|
@@ -3,23 +3,21 @@ package core
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
||||||
plog "github.com/wencaiwulue/kubevpn/v2/pkg/log"
|
plog "github.com/wencaiwulue/kubevpn/v2/pkg/log"
|
||||||
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
type fakeUDPTunnelConnector struct {
|
type UDPOverTCPConnector struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func UDPOverTCPTunnelConnector() Connector {
|
func NewUDPOverTCPConnector() Connector {
|
||||||
return &fakeUDPTunnelConnector{}
|
return &UDPOverTCPConnector{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *fakeUDPTunnelConnector) ConnectContext(ctx context.Context, conn net.Conn) (net.Conn, error) {
|
func (c *UDPOverTCPConnector) ConnectContext(ctx context.Context, conn net.Conn) (net.Conn, error) {
|
||||||
//defer conn.SetDeadline(time.Time{})
|
//defer conn.SetDeadline(time.Time{})
|
||||||
switch con := conn.(type) {
|
switch con := conn.(type) {
|
||||||
case *net.TCPConn:
|
case *net.TCPConn:
|
||||||
@@ -31,44 +29,32 @@ func (c *fakeUDPTunnelConnector) ConnectContext(ctx context.Context, conn net.Co
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = con.SetKeepAlivePeriod(15 * time.Second)
|
err = con.SetKeepAlivePeriod(config.KeepAliveTime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newFakeUDPTunnelConnOverTCP(ctx, conn)
|
return newUDPConnOverTCP(ctx, conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
type fakeUdpHandler struct {
|
type UDPOverTCPHandler struct {
|
||||||
// map[srcIP]net.Conn
|
// map[srcIP]net.Conn
|
||||||
routeMapTCP *sync.Map
|
routeMapTCP *sync.Map
|
||||||
packetChan chan *datagramPacket
|
packetChan chan *DatagramPacket
|
||||||
}
|
}
|
||||||
|
|
||||||
func TCPHandler() Handler {
|
func TCPHandler() Handler {
|
||||||
return &fakeUdpHandler{
|
return &UDPOverTCPHandler{
|
||||||
routeMapTCP: RouteMapTCP,
|
routeMapTCP: RouteMapTCP,
|
||||||
packetChan: TCPPacketChan,
|
packetChan: TCPPacketChan,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *fakeUdpHandler) Handle(ctx context.Context, tcpConn net.Conn) {
|
func (h *UDPOverTCPHandler) Handle(ctx context.Context, tcpConn net.Conn) {
|
||||||
defer tcpConn.Close()
|
defer tcpConn.Close()
|
||||||
plog.G(ctx).Debugf("[TCP] %s -> %s", tcpConn.RemoteAddr(), tcpConn.LocalAddr())
|
plog.G(ctx).Debugf("[TCP] %s -> %s", tcpConn.RemoteAddr(), tcpConn.LocalAddr())
|
||||||
|
|
||||||
defer func(addr net.Addr) {
|
defer h.removeFromRouteMapTCP(ctx, tcpConn)
|
||||||
var keys []string
|
|
||||||
h.routeMapTCP.Range(func(key, value any) bool {
|
|
||||||
if value.(net.Conn) == tcpConn {
|
|
||||||
keys = append(keys, key.(string))
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
for _, key := range keys {
|
|
||||||
h.routeMapTCP.Delete(key)
|
|
||||||
}
|
|
||||||
plog.G(ctx).Debugf("[TCP] To %s by conn %s from globle route map TCP", strings.Join(keys, " "), addr)
|
|
||||||
}(tcpConn.LocalAddr())
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
@@ -78,7 +64,7 @@ func (h *fakeUdpHandler) Handle(ctx context.Context, tcpConn net.Conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
buf := config.LPool.Get().([]byte)[:]
|
buf := config.LPool.Get().([]byte)[:]
|
||||||
dgram, err := readDatagramPacketServer(tcpConn, buf[:])
|
packet, err := readDatagramPacketServer(tcpConn, buf[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
plog.G(ctx).Errorf("[TCP] %s -> %s : %v", tcpConn.RemoteAddr(), tcpConn.LocalAddr(), err)
|
plog.G(ctx).Errorf("[TCP] %s -> %s : %v", tcpConn.RemoteAddr(), tcpConn.LocalAddr(), err)
|
||||||
config.LPool.Put(buf[:])
|
config.LPool.Put(buf[:])
|
||||||
@@ -86,7 +72,7 @@ func (h *fakeUdpHandler) Handle(ctx context.Context, tcpConn net.Conn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var src net.IP
|
var src net.IP
|
||||||
src, _, err = util.ParseIP(dgram.Data[:dgram.DataLength])
|
src, _, err = util.ParseIP(packet.Data[:packet.DataLength])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
plog.G(ctx).Errorf("[TCP] Unknown packet")
|
plog.G(ctx).Errorf("[TCP] Unknown packet")
|
||||||
config.LPool.Put(buf[:])
|
config.LPool.Put(buf[:])
|
||||||
@@ -101,43 +87,54 @@ func (h *fakeUdpHandler) Handle(ctx context.Context, tcpConn net.Conn) {
|
|||||||
} else {
|
} else {
|
||||||
plog.G(ctx).Debugf("[TCP] Add new route map TCP: %s -> %s-%s", src, tcpConn.LocalAddr(), tcpConn.RemoteAddr())
|
plog.G(ctx).Debugf("[TCP] Add new route map TCP: %s -> %s-%s", src, tcpConn.LocalAddr(), tcpConn.RemoteAddr())
|
||||||
}
|
}
|
||||||
util.SafeWrite(h.packetChan, dgram)
|
util.SafeWrite(h.packetChan, packet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fake udp connect over tcp
|
func (h *UDPOverTCPHandler) removeFromRouteMapTCP(ctx context.Context, tcpConn net.Conn) {
|
||||||
type fakeUDPTunnelConn struct {
|
h.routeMapTCP.Range(func(key, value any) bool {
|
||||||
|
if value.(net.Conn) == tcpConn {
|
||||||
|
plog.G(ctx).Debugf("[TCP] Delete to DST: %s by conn %s from globle route map TCP", key, tcpConn.LocalAddr())
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
var _ net.PacketConn = (*UDPConnOverTCP)(nil)
|
||||||
|
|
||||||
|
// UDPConnOverTCP fake udp connection over tcp connection
|
||||||
|
type UDPConnOverTCP struct {
|
||||||
// tcp connection
|
// tcp connection
|
||||||
net.Conn
|
net.Conn
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFakeUDPTunnelConnOverTCP(ctx context.Context, conn net.Conn) (net.Conn, error) {
|
func newUDPConnOverTCP(ctx context.Context, conn net.Conn) (net.Conn, error) {
|
||||||
return &fakeUDPTunnelConn{ctx: ctx, Conn: conn}, nil
|
return &UDPConnOverTCP{ctx: ctx, Conn: conn}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *fakeUDPTunnelConn) ReadFrom(b []byte) (int, net.Addr, error) {
|
func (c *UDPConnOverTCP) ReadFrom(b []byte) (int, net.Addr, error) {
|
||||||
select {
|
select {
|
||||||
case <-c.ctx.Done():
|
case <-c.ctx.Done():
|
||||||
return 0, nil, c.ctx.Err()
|
return 0, nil, c.ctx.Err()
|
||||||
default:
|
default:
|
||||||
dgram, err := readDatagramPacket(c.Conn, b)
|
packet, err := readDatagramPacket(c.Conn, b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, nil, err
|
return 0, nil, err
|
||||||
}
|
}
|
||||||
return int(dgram.DataLength), dgram.Addr(), nil
|
return int(packet.DataLength), nil, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *fakeUDPTunnelConn) WriteTo(b []byte, _ net.Addr) (int, error) {
|
func (c *UDPConnOverTCP) WriteTo(b []byte, _ net.Addr) (int, error) {
|
||||||
dgram := newDatagramPacket(b)
|
packet := newDatagramPacket(b)
|
||||||
if err := dgram.Write(c.Conn); err != nil {
|
if err := packet.Write(c.Conn); err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
return len(b), nil
|
return len(b), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *fakeUDPTunnelConn) Close() error {
|
func (c *UDPConnOverTCP) Close() error {
|
||||||
if cc, ok := c.Conn.(interface{ CloseRead() error }); ok {
|
if cc, ok := c.Conn.(interface{ CloseRead() error }); ok {
|
||||||
_ = cc.CloseRead()
|
_ = cc.CloseRead()
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,6 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
||||||
plog "github.com/wencaiwulue/kubevpn/v2/pkg/log"
|
plog "github.com/wencaiwulue/kubevpn/v2/pkg/log"
|
||||||
@@ -12,103 +11,83 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
MaxSize = 1000
|
MaxSize = 100
|
||||||
)
|
)
|
||||||
|
|
||||||
type tunHandler struct {
|
type tunHandler struct {
|
||||||
chain *Chain
|
forward *Forwarder
|
||||||
node *Node
|
node *Node
|
||||||
routeMapUDP *RouteMap
|
routeMapUDP *sync.Map
|
||||||
// map[srcIP]net.Conn
|
|
||||||
routeMapTCP *sync.Map
|
routeMapTCP *sync.Map
|
||||||
chExit chan error
|
errChan chan error
|
||||||
}
|
|
||||||
|
|
||||||
type RouteMap struct {
|
|
||||||
lock *sync.RWMutex
|
|
||||||
routes map[string]net.Addr
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewRouteMap() *RouteMap {
|
|
||||||
return &RouteMap{
|
|
||||||
lock: &sync.RWMutex{},
|
|
||||||
routes: map[string]net.Addr{},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *RouteMap) LoadOrStore(to net.IP, addr net.Addr) (net.Addr, bool) {
|
|
||||||
n.lock.RLock()
|
|
||||||
route, load := n.routes[to.String()]
|
|
||||||
n.lock.RUnlock()
|
|
||||||
if load {
|
|
||||||
return route, true
|
|
||||||
}
|
|
||||||
|
|
||||||
n.lock.Lock()
|
|
||||||
defer n.lock.Unlock()
|
|
||||||
n.routes[to.String()] = addr
|
|
||||||
return addr, false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *RouteMap) Store(to net.IP, addr net.Addr) {
|
|
||||||
n.lock.Lock()
|
|
||||||
defer n.lock.Unlock()
|
|
||||||
n.routes[to.String()] = addr
|
|
||||||
}
|
|
||||||
|
|
||||||
func (n *RouteMap) RouteTo(ip net.IP) net.Addr {
|
|
||||||
n.lock.RLock()
|
|
||||||
defer n.lock.RUnlock()
|
|
||||||
return n.routes[ip.String()]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TunHandler creates a handler for tun tunnel.
|
// TunHandler creates a handler for tun tunnel.
|
||||||
func TunHandler(chain *Chain, node *Node) Handler {
|
func TunHandler(forward *Forwarder, node *Node) Handler {
|
||||||
return &tunHandler{
|
return &tunHandler{
|
||||||
chain: chain,
|
forward: forward,
|
||||||
node: node,
|
node: node,
|
||||||
routeMapUDP: NewRouteMap(),
|
routeMapUDP: &sync.Map{},
|
||||||
routeMapTCP: RouteMapTCP,
|
routeMapTCP: RouteMapTCP,
|
||||||
chExit: make(chan error, 1),
|
errChan: make(chan error, 1),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *tunHandler) Handle(ctx context.Context, tun net.Conn) {
|
func (h *tunHandler) Handle(ctx context.Context, tun net.Conn) {
|
||||||
if h.node.Remote != "" {
|
if remote := h.node.Remote; remote != "" {
|
||||||
h.HandleClient(ctx, tun)
|
remoteAddr, err := net.ResolveUDPAddr("udp", remote)
|
||||||
|
if err != nil {
|
||||||
|
plog.G(ctx).Errorf("[TUN-CLIENT] Failed to resolve udp addr %s: %v", remote, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
h.HandleClient(ctx, tun, remoteAddr)
|
||||||
} else {
|
} else {
|
||||||
h.HandleServer(ctx, tun)
|
h.HandleServer(ctx, tun)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *tunHandler) HandleServer(ctx context.Context, tun net.Conn) {
|
||||||
|
device := &Device{
|
||||||
|
tun: tun,
|
||||||
|
tunInbound: make(chan *Packet, MaxSize),
|
||||||
|
tunOutbound: make(chan *Packet, MaxSize),
|
||||||
|
errChan: h.errChan,
|
||||||
|
}
|
||||||
|
|
||||||
|
defer device.Close()
|
||||||
|
go device.readFromTUN()
|
||||||
|
go device.writeToTUN()
|
||||||
|
go device.transport(ctx, h.node.Addr, h.routeMapUDP, h.routeMapTCP)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case err := <-device.errChan:
|
||||||
|
plog.G(ctx).Errorf("Device exit: %v", err)
|
||||||
|
return
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type Device struct {
|
type Device struct {
|
||||||
tun net.Conn
|
tun net.Conn
|
||||||
|
|
||||||
tunInbound chan *DataElem
|
tunInbound chan *Packet
|
||||||
tunOutbound chan *DataElem
|
tunOutbound chan *Packet
|
||||||
|
|
||||||
// your main logic
|
errChan chan error
|
||||||
tunInboundHandler func(tunInbound <-chan *DataElem, tunOutbound chan<- *DataElem)
|
|
||||||
|
|
||||||
chExit chan error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) readFromTun() {
|
func (d *Device) readFromTUN() {
|
||||||
defer util.HandleCrash()
|
defer util.HandleCrash()
|
||||||
for {
|
for {
|
||||||
buf := config.LPool.Get().([]byte)[:]
|
buf := config.LPool.Get().([]byte)[:]
|
||||||
n, err := d.tun.Read(buf[:])
|
n, err := d.tun.Read(buf[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
config.LPool.Put(buf[:])
|
config.LPool.Put(buf[:])
|
||||||
plog.G(context.Background()).Errorf("[TUN] Failed to read from tun: %v", err)
|
plog.G(context.Background()).Errorf("[TUN] Failed to read from tun device: %v", err)
|
||||||
util.SafeWrite(d.chExit, err)
|
util.SafeWrite(d.errChan, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n == 0 {
|
|
||||||
plog.G(context.Background()).Errorf("[TUN] Read packet length 0")
|
|
||||||
config.LPool.Put(buf[:])
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
src, dst, err := util.ParseIP(buf[:n])
|
src, dst, err := util.ParseIP(buf[:n])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -117,8 +96,8 @@ func (d *Device) readFromTun() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
plog.G(context.Background()).Debugf("[TUN] SRC: %s --> DST: %s, length: %d", src, dst, n)
|
plog.G(context.Background()).Debugf("[TUN] SRC: %s, DST: %s, Length: %d", src, dst, n)
|
||||||
util.SafeWrite(d.tunInbound, &DataElem{
|
util.SafeWrite(d.tunInbound, &Packet{
|
||||||
data: buf[:],
|
data: buf[:],
|
||||||
length: n,
|
length: n,
|
||||||
src: src,
|
src: src,
|
||||||
@@ -127,13 +106,14 @@ func (d *Device) readFromTun() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *Device) writeToTun() {
|
func (d *Device) writeToTUN() {
|
||||||
defer util.HandleCrash()
|
defer util.HandleCrash()
|
||||||
for e := range d.tunOutbound {
|
for packet := range d.tunOutbound {
|
||||||
_, err := d.tun.Write(e.data[:e.length])
|
_, err := d.tun.Write(packet.data[:packet.length])
|
||||||
config.LPool.Put(e.data[:])
|
config.LPool.Put(packet.data[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.SafeWrite(d.chExit, err)
|
plog.G(context.Background()).Errorf("[TUN] Failed to write to tun device: %v", err)
|
||||||
|
util.SafeWrite(d.errChan, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -146,91 +126,51 @@ func (d *Device) Close() {
|
|||||||
util.SafeClose(TCPPacketChan)
|
util.SafeClose(TCPPacketChan)
|
||||||
}
|
}
|
||||||
|
|
||||||
func heartbeats(ctx context.Context, tun net.Conn) {
|
func (d *Device) transport(ctx context.Context, addr string, routeMapUDP *sync.Map, routeMapTCP *sync.Map) {
|
||||||
tunIfi, err := util.GetTunDeviceByConn(tun)
|
for ctx.Err() == nil {
|
||||||
if err != nil {
|
func() {
|
||||||
plog.G(ctx).Errorf("Failed to get tun device: %s", err.Error())
|
packetConn, err := (&net.ListenConfig{}).ListenPacket(ctx, "udp", addr)
|
||||||
return
|
|
||||||
}
|
|
||||||
srcIPv4, srcIPv6, dockerSrcIPv4, err := util.GetTunDeviceIP(tunIfi.Name)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ticker := time.NewTicker(time.Second * 5)
|
|
||||||
defer ticker.Stop()
|
|
||||||
|
|
||||||
for ; true; <-ticker.C {
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
return
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
|
|
||||||
if srcIPv4 != nil {
|
|
||||||
go util.Ping(ctx, srcIPv4.String(), config.RouterIP.String())
|
|
||||||
}
|
|
||||||
if srcIPv6 != nil {
|
|
||||||
go util.Ping(ctx, srcIPv6.String(), config.RouterIP6.String())
|
|
||||||
}
|
|
||||||
if dockerSrcIPv4 != nil {
|
|
||||||
go util.Ping(ctx, dockerSrcIPv4.String(), config.DockerRouterIP.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) Start(ctx context.Context) {
|
|
||||||
go d.readFromTun()
|
|
||||||
go d.tunInboundHandler(d.tunInbound, d.tunOutbound)
|
|
||||||
go d.writeToTun()
|
|
||||||
|
|
||||||
select {
|
|
||||||
case err := <-d.chExit:
|
|
||||||
plog.G(ctx).Errorf("Device exit: %v", err)
|
|
||||||
return
|
|
||||||
case <-ctx.Done():
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *Device) SetTunInboundHandler(handler func(tunInbound <-chan *DataElem, tunOutbound chan<- *DataElem)) {
|
|
||||||
d.tunInboundHandler = handler
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *tunHandler) HandleServer(ctx context.Context, tun net.Conn) {
|
|
||||||
device := &Device{
|
|
||||||
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 {
|
|
||||||
packetConn, err := (&net.ListenConfig{}).ListenPacket(ctx, "udp", h.node.Addr)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
plog.G(ctx).Errorf("[UDP] Failed to listen %s: %v", h.node.Addr, err)
|
plog.G(ctx).Errorf("[UDP] Failed to listen %s: %v", addr, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
err = transportTunServer(ctx, tunInbound, tunOutbound, packetConn, h.routeMapUDP, h.routeMapTCP)
|
|
||||||
if err != nil {
|
|
||||||
plog.G(ctx).Errorf("[TUN] %s: %v", tun.LocalAddr(), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
defer device.Close()
|
p := &Peer{
|
||||||
device.Start(ctx)
|
conn: packetConn,
|
||||||
|
tcpInbound: make(chan *Packet, MaxSize),
|
||||||
|
tunInbound: d.tunInbound,
|
||||||
|
tunOutbound: d.tunOutbound,
|
||||||
|
routeMapUDP: routeMapUDP,
|
||||||
|
routeMapTCP: routeMapTCP,
|
||||||
|
errChan: d.errChan,
|
||||||
|
}
|
||||||
|
|
||||||
|
defer p.Close()
|
||||||
|
go p.readFromConn()
|
||||||
|
go p.readFromTCPConn()
|
||||||
|
go p.routeTCP()
|
||||||
|
go p.routeTUN()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case err = <-p.errChan:
|
||||||
|
plog.G(ctx).Errorf("[TUN] %s: %v", d.tun.LocalAddr(), err)
|
||||||
|
return
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type DataElem struct {
|
type Packet struct {
|
||||||
data []byte
|
data []byte
|
||||||
length int
|
length int
|
||||||
src net.IP
|
src net.IP
|
||||||
dst net.IP
|
dst net.IP
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewDataElem(data []byte, length int, src net.IP, dst net.IP) *DataElem {
|
func NewDataElem(data []byte, length int, src net.IP, dst net.IP) *Packet {
|
||||||
return &DataElem{
|
return &Packet{
|
||||||
data: data,
|
data: data,
|
||||||
length: length,
|
length: length,
|
||||||
src: src,
|
src: src,
|
||||||
@@ -238,32 +178,24 @@ func NewDataElem(data []byte, length int, src net.IP, dst net.IP) *DataElem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DataElem) Data() []byte {
|
func (d *Packet) Data() []byte {
|
||||||
return d.data
|
return d.data
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *DataElem) Length() int {
|
func (d *Packet) Length() int {
|
||||||
return d.length
|
return d.length
|
||||||
}
|
}
|
||||||
|
|
||||||
type udpElem struct {
|
|
||||||
from net.Addr
|
|
||||||
data []byte
|
|
||||||
length int
|
|
||||||
src net.IP
|
|
||||||
dst net.IP
|
|
||||||
}
|
|
||||||
|
|
||||||
type Peer struct {
|
type Peer struct {
|
||||||
conn net.PacketConn
|
conn net.PacketConn
|
||||||
|
|
||||||
connInbound chan *udpElem
|
tcpInbound chan *Packet
|
||||||
|
|
||||||
tunInbound <-chan *DataElem
|
tunInbound chan *Packet
|
||||||
tunOutbound chan<- *DataElem
|
tunOutbound chan<- *Packet
|
||||||
|
|
||||||
// map[srcIP.String()]net.Addr for udp
|
// map[srcIP.String()]net.Addr for udp
|
||||||
routeMapUDP *RouteMap
|
routeMapUDP *sync.Map
|
||||||
// map[srcIP.String()]net.Conn for tcp
|
// map[srcIP.String()]net.Conn for tcp
|
||||||
routeMapTCP *sync.Map
|
routeMapTCP *sync.Map
|
||||||
|
|
||||||
@@ -294,17 +226,16 @@ func (p *Peer) readFromConn() {
|
|||||||
plog.G(context.Background()).Errorf("[TUN] Unknown packet: %v", err)
|
plog.G(context.Background()).Errorf("[TUN] Unknown packet: %v", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if addr, loaded := p.routeMapUDP.LoadOrStore(src, from); loaded {
|
if addr, loaded := p.routeMapUDP.LoadOrStore(src.String(), from); loaded {
|
||||||
if addr.String() != from.String() {
|
if addr.(net.Addr).String() != from.String() {
|
||||||
p.routeMapUDP.Store(src, from)
|
p.routeMapUDP.Store(src.String(), from)
|
||||||
plog.G(context.Background()).Debugf("[TUN] Replace route map UDP: %s -> %s", src, from)
|
plog.G(context.Background()).Debugf("[TUN] Replace route map UDP: %s -> %s", src, from)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
plog.G(context.Background()).Debugf("[TUN] Add new route map UDP: %s -> %s", src, from)
|
plog.G(context.Background()).Debugf("[TUN] Add new route map UDP: %s -> %s", src, from)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.connInbound <- &udpElem{
|
p.tunInbound <- &Packet{
|
||||||
from: from,
|
|
||||||
data: buf[:],
|
data: buf[:],
|
||||||
length: n,
|
length: n,
|
||||||
src: src,
|
src: src,
|
||||||
@@ -318,49 +249,40 @@ func (p *Peer) readFromTCPConn() {
|
|||||||
for packet := range TCPPacketChan {
|
for packet := range TCPPacketChan {
|
||||||
src, dst, err := util.ParseIP(packet.Data)
|
src, dst, err := util.ParseIP(packet.Data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
plog.G(context.Background()).Errorf("[TUN] Unknown packet")
|
plog.G(context.Background()).Errorf("[TCP] Unknown packet")
|
||||||
config.LPool.Put(packet.Data[:])
|
config.LPool.Put(packet.Data[:])
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
u := &udpElem{
|
plog.G(context.Background()).Debugf("[TCP] SRC: %s > DST: %s Length: %d", src, dst, packet.DataLength)
|
||||||
|
p.tcpInbound <- &Packet{
|
||||||
data: packet.Data[:],
|
data: packet.Data[:],
|
||||||
length: int(packet.DataLength),
|
length: int(packet.DataLength),
|
||||||
src: src,
|
src: src,
|
||||||
dst: dst,
|
dst: dst,
|
||||||
}
|
}
|
||||||
plog.G(context.Background()).Debugf("[TCP] udp-tun %s >>> %s length: %d", u.src, u.dst, u.length)
|
|
||||||
p.connInbound <- u
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Peer) routePeer() {
|
func (p *Peer) routeTCP() {
|
||||||
defer util.HandleCrash()
|
defer util.HandleCrash()
|
||||||
for e := range p.connInbound {
|
for packet := range p.tcpInbound {
|
||||||
if routeToAddr := p.routeMapUDP.RouteTo(e.dst); routeToAddr != nil {
|
if conn, ok := p.routeMapTCP.Load(packet.dst.String()); ok {
|
||||||
plog.G(context.Background()).Debugf("[UDP] Find UDP route to dst: %s -> %s", e.dst, routeToAddr)
|
plog.G(context.Background()).Debugf("[TCP] Find TCP route SRC: %s to DST: %s -> %s", packet.src.String(), packet.dst.String(), conn.(net.Conn).RemoteAddr())
|
||||||
_, err := p.conn.WriteTo(e.data[:e.length], routeToAddr)
|
dgram := newDatagramPacket(packet.data[:packet.length])
|
||||||
config.LPool.Put(e.data[:])
|
|
||||||
if err != nil {
|
|
||||||
p.sendErr(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} else if conn, ok := p.routeMapTCP.Load(e.dst.String()); ok {
|
|
||||||
plog.G(context.Background()).Debugf("[TCP] 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))
|
err := dgram.Write(conn.(net.Conn))
|
||||||
config.LPool.Put(e.data[:])
|
config.LPool.Put(packet.data[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
plog.G(context.Background()).Errorf("[TCP] udp-tun %s <- %s : %s", conn.(net.Conn).RemoteAddr(), dgram.Addr(), err)
|
plog.G(context.Background()).Errorf("[TCP] Failed to write to %s <- %s : %s", conn.(net.Conn).RemoteAddr(), conn.(net.Conn).LocalAddr(), err)
|
||||||
p.sendErr(err)
|
p.sendErr(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
plog.G(context.Background()).Debugf("[TUN] Not found route to dst: %s, write to TUN device", e.dst.String())
|
plog.G(context.Background()).Debugf("[TCP] Not found route, write to TUN device. SRC: %s, DST: %s", packet.src.String(), packet.dst.String())
|
||||||
p.tunOutbound <- &DataElem{
|
p.tunOutbound <- &Packet{
|
||||||
data: e.data,
|
data: packet.data,
|
||||||
length: e.length,
|
length: packet.length,
|
||||||
src: e.src,
|
src: packet.src,
|
||||||
dst: e.dst,
|
dst: packet.dst,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -368,63 +290,33 @@ func (p *Peer) routePeer() {
|
|||||||
|
|
||||||
func (p *Peer) routeTUN() {
|
func (p *Peer) routeTUN() {
|
||||||
defer util.HandleCrash()
|
defer util.HandleCrash()
|
||||||
for e := range p.tunInbound {
|
for packet := range p.tunInbound {
|
||||||
if addr := p.routeMapUDP.RouteTo(e.dst); addr != nil {
|
if addr, ok := p.routeMapUDP.Load(packet.dst.String()); ok {
|
||||||
plog.G(context.Background()).Debugf("[TUN] Find UDP route to dst: %s -> %s", e.dst, addr)
|
plog.G(context.Background()).Debugf("[TUN] Find UDP route to DST: %s -> %s, SRC: %s, DST: %s", packet.dst, addr, packet.src.String(), packet.dst.String())
|
||||||
_, err := p.conn.WriteTo(e.data[:e.length], addr)
|
_, err := p.conn.WriteTo(packet.data[:packet.length], addr.(net.Addr))
|
||||||
config.LPool.Put(e.data[:])
|
config.LPool.Put(packet.data[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
plog.G(context.Background()).Debugf("[TUN] Failed wirte to route dst: %s -> %s", e.dst, addr)
|
plog.G(context.Background()).Debugf("[TUN] Failed wirte to route dst: %s -> %s", packet.dst, addr)
|
||||||
p.sendErr(err)
|
p.sendErr(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if conn, ok := p.routeMapTCP.Load(e.dst.String()); ok {
|
} else if conn, ok := p.routeMapTCP.Load(packet.dst.String()); ok {
|
||||||
plog.G(context.Background()).Debugf("[TUN] Find TCP route to dst: %s -> %s", e.dst.String(), conn.(net.Conn).RemoteAddr())
|
plog.G(context.Background()).Debugf("[TUN] Find TCP route to dst: %s -> %s", packet.dst.String(), conn.(net.Conn).RemoteAddr())
|
||||||
dgram := newDatagramPacket(e.data[:e.length])
|
dgram := newDatagramPacket(packet.data[:packet.length])
|
||||||
err := dgram.Write(conn.(net.Conn))
|
err := dgram.Write(conn.(net.Conn))
|
||||||
config.LPool.Put(e.data[:])
|
config.LPool.Put(packet.data[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
plog.G(context.Background()).Errorf("[TUN] Failed to write TCP %s <- %s : %s", conn.(net.Conn).RemoteAddr(), dgram.Addr(), err)
|
plog.G(context.Background()).Errorf("[TUN] Failed to write TCP %s <- %s : %s", conn.(net.Conn).RemoteAddr(), conn.(net.Conn).LocalAddr(), err)
|
||||||
p.sendErr(err)
|
p.sendErr(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
plog.G(context.Background()).Errorf("[TUN] No route for src: %s -> dst: %s, drop it", e.src, e.dst)
|
plog.G(context.Background()).Errorf("[TUN] No route for src: %s -> dst: %s, drop it", packet.src, packet.dst)
|
||||||
config.LPool.Put(e.data[:])
|
config.LPool.Put(packet.data[:])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Peer) Start() {
|
|
||||||
go p.readFromConn()
|
|
||||||
go p.readFromTCPConn()
|
|
||||||
go p.routePeer()
|
|
||||||
go p.routeTUN()
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *Peer) Close() {
|
func (p *Peer) Close() {
|
||||||
p.conn.Close()
|
p.conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
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),
|
|
||||||
tunInbound: tunInbound,
|
|
||||||
tunOutbound: tunOutbound,
|
|
||||||
routeMapUDP: routeMapUDP,
|
|
||||||
routeMapTCP: routeMapTCP,
|
|
||||||
errChan: make(chan error, 2),
|
|
||||||
}
|
|
||||||
|
|
||||||
defer p.Close()
|
|
||||||
p.Start()
|
|
||||||
|
|
||||||
select {
|
|
||||||
case err := <-p.errChan:
|
|
||||||
plog.G(ctx).Errorf(err.Error())
|
|
||||||
return err
|
|
||||||
case <-ctx.Done():
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@@ -13,56 +13,66 @@ import (
|
|||||||
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (h *tunHandler) HandleClient(ctx context.Context, tun net.Conn) {
|
func (h *tunHandler) HandleClient(ctx context.Context, tun net.Conn, remoteAddr *net.UDPAddr) {
|
||||||
defer tun.Close()
|
device := &ClientDevice{
|
||||||
remoteAddr, err := net.ResolveUDPAddr("udp", h.node.Remote)
|
|
||||||
if err != nil {
|
|
||||||
plog.G(ctx).Errorf("[TUN-CLIENT] Failed to resolve udp addr %s: %v", h.node.Remote, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
in := make(chan *DataElem, MaxSize)
|
|
||||||
out := make(chan *DataElem, MaxSize)
|
|
||||||
defer util.SafeClose(in)
|
|
||||||
defer util.SafeClose(out)
|
|
||||||
|
|
||||||
d := &ClientDevice{
|
|
||||||
tun: tun,
|
tun: tun,
|
||||||
tunInbound: in,
|
tunInbound: make(chan *Packet, MaxSize),
|
||||||
tunOutbound: out,
|
tunOutbound: make(chan *Packet, MaxSize),
|
||||||
chExit: h.chExit,
|
errChan: h.errChan,
|
||||||
}
|
}
|
||||||
d.SetTunInboundHandler(func(tunInbound <-chan *DataElem, tunOutbound chan<- *DataElem) {
|
|
||||||
for ctx.Err() == nil {
|
|
||||||
packetConn, err := getRemotePacketConn(ctx, h.chain)
|
|
||||||
if err != nil {
|
|
||||||
plog.G(ctx).Debugf("[TUN-CLIENT] Failed to get remote conn from %s -> %s: %s", tun.LocalAddr(), remoteAddr, err)
|
|
||||||
time.Sleep(time.Millisecond * 200)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
err = transportTunClient(ctx, tunInbound, tunOutbound, packetConn, remoteAddr)
|
|
||||||
if err != nil {
|
|
||||||
plog.G(ctx).Debugf("[TUN-CLIENT] %s: %v", tun.LocalAddr(), err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
d.Start(ctx)
|
defer device.Close()
|
||||||
|
go device.forwardPacketToRemote(ctx, remoteAddr, h.forward)
|
||||||
|
go device.readFromTun()
|
||||||
|
go device.writeToTun()
|
||||||
|
go heartbeats(ctx, device.tun)
|
||||||
|
select {
|
||||||
|
case <-device.errChan:
|
||||||
|
case <-ctx.Done():
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRemotePacketConn(ctx context.Context, chain *Chain) (packetConn net.PacketConn, err error) {
|
type ClientDevice struct {
|
||||||
|
tun net.Conn
|
||||||
|
tunInbound chan *Packet
|
||||||
|
tunOutbound chan *Packet
|
||||||
|
errChan chan error
|
||||||
|
|
||||||
|
remote *net.UDPAddr
|
||||||
|
forward *Forwarder
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *ClientDevice) forwardPacketToRemote(ctx context.Context, remoteAddr *net.UDPAddr, forward *Forwarder) {
|
||||||
|
for ctx.Err() == nil {
|
||||||
|
func() {
|
||||||
|
packetConn, err := getRemotePacketConn(ctx, forward)
|
||||||
|
if err != nil {
|
||||||
|
plog.G(ctx).Debugf("[TUN-CLIENT] Failed to get remote conn from %s -> %s: %s", d.tun.LocalAddr(), remoteAddr, err)
|
||||||
|
time.Sleep(time.Millisecond * 200)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err = transportTunPacketClient(ctx, d.tunInbound, d.tunOutbound, packetConn, remoteAddr)
|
||||||
|
if err != nil {
|
||||||
|
plog.G(ctx).Debugf("[TUN-CLIENT] %s: %v", d.tun.LocalAddr(), err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRemotePacketConn(ctx context.Context, forwarder *Forwarder) (packetConn net.PacketConn, err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if err != nil && packetConn != nil {
|
if err != nil && packetConn != nil {
|
||||||
_ = packetConn.Close()
|
_ = packetConn.Close()
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
if !chain.IsEmpty() {
|
if !forwarder.IsEmpty() {
|
||||||
var cc net.Conn
|
var conn net.Conn
|
||||||
cc, err = chain.DialContext(ctx)
|
conn, err = forwarder.DialContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var ok bool
|
var ok bool
|
||||||
if packetConn, ok = cc.(net.PacketConn); !ok {
|
if packetConn, ok = conn.(net.PacketConn); !ok {
|
||||||
err = errors.New("not a packet connection")
|
err = errors.New("not a packet connection")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -76,20 +86,21 @@ func getRemotePacketConn(ctx context.Context, chain *Chain) (packetConn net.Pack
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func transportTunClient(ctx context.Context, tunInbound <-chan *DataElem, tunOutbound chan<- *DataElem, packetConn net.PacketConn, remoteAddr net.Addr) error {
|
func transportTunPacketClient(ctx context.Context, tunInbound <-chan *Packet, tunOutbound chan<- *Packet, packetConn net.PacketConn, remoteAddr net.Addr) error {
|
||||||
errChan := make(chan error, 2)
|
errChan := make(chan error, 2)
|
||||||
defer packetConn.Close()
|
defer packetConn.Close()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer util.HandleCrash()
|
defer util.HandleCrash()
|
||||||
for e := range tunInbound {
|
for packet := range tunInbound {
|
||||||
if e.src.Equal(e.dst) {
|
if packet.src.Equal(packet.dst) {
|
||||||
util.SafeWrite(tunOutbound, e)
|
util.SafeWrite(tunOutbound, packet)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
_, err := packetConn.WriteTo(e.data[:e.length], remoteAddr)
|
_, err := packetConn.WriteTo(packet.data[:packet.length], remoteAddr)
|
||||||
config.LPool.Put(e.data[:])
|
config.LPool.Put(packet.data[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
plog.G(ctx).Errorf("failed to write packet to remote %s: %v", remoteAddr, err)
|
||||||
util.SafeWrite(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
|
return
|
||||||
}
|
}
|
||||||
@@ -106,7 +117,7 @@ func transportTunClient(ctx context.Context, tunInbound <-chan *DataElem, tunOut
|
|||||||
util.SafeWrite(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
|
return
|
||||||
}
|
}
|
||||||
util.SafeWrite(tunOutbound, &DataElem{data: buf[:], length: n})
|
util.SafeWrite(tunOutbound, &Packet{data: buf[:], length: n})
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -118,54 +129,22 @@ func transportTunClient(ctx context.Context, tunInbound <-chan *DataElem, tunOut
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type ClientDevice struct {
|
|
||||||
tun net.Conn
|
|
||||||
tunInbound chan *DataElem
|
|
||||||
tunOutbound chan *DataElem
|
|
||||||
// your main logic
|
|
||||||
tunInboundHandler func(tunInbound <-chan *DataElem, tunOutbound chan<- *DataElem)
|
|
||||||
chExit chan error
|
|
||||||
}
|
|
||||||
|
|
||||||
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:
|
|
||||||
plog.G(ctx).Errorf("[TUN-CLIENT]: %v", err)
|
|
||||||
return
|
|
||||||
case <-ctx.Done():
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *ClientDevice) SetTunInboundHandler(handler func(tunInbound <-chan *DataElem, tunOutbound chan<- *DataElem)) {
|
|
||||||
d.tunInboundHandler = handler
|
|
||||||
}
|
|
||||||
|
|
||||||
func (d *ClientDevice) readFromTun() {
|
func (d *ClientDevice) readFromTun() {
|
||||||
defer util.HandleCrash()
|
defer util.HandleCrash()
|
||||||
for {
|
for {
|
||||||
buf := config.LPool.Get().([]byte)[:]
|
buf := config.LPool.Get().([]byte)[:]
|
||||||
n, err := d.tun.Read(buf[:])
|
n, err := d.tun.Read(buf[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.SafeWrite(d.chExit, err)
|
util.SafeWrite(d.errChan, err)
|
||||||
config.LPool.Put(buf[:])
|
config.LPool.Put(buf[:])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n == 0 {
|
|
||||||
config.LPool.Put(buf[:])
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
// Try to determine network protocol number, default zero.
|
// Try to determine network protocol number, default zero.
|
||||||
var src, dst net.IP
|
var src, dst net.IP
|
||||||
src, dst, err = util.ParseIP(buf[:n])
|
src, dst, err = util.ParseIP(buf[:n])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
plog.G(context.Background()).Debugf("[TUN-GVISOR] Unknown packet: %v", err)
|
plog.G(context.Background()).Errorf("[TUN-RAW] Unknown packet: %v", err)
|
||||||
config.LPool.Put(buf[:])
|
config.LPool.Put(buf[:])
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -180,8 +159,47 @@ func (d *ClientDevice) writeToTun() {
|
|||||||
_, err := d.tun.Write(e.data[:e.length])
|
_, err := d.tun.Write(e.data[:e.length])
|
||||||
config.LPool.Put(e.data[:])
|
config.LPool.Put(e.data[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
util.SafeWrite(d.chExit, err)
|
util.SafeWrite(d.errChan, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (d *ClientDevice) Close() {
|
||||||
|
d.tun.Close()
|
||||||
|
util.SafeClose(d.tunInbound)
|
||||||
|
util.SafeClose(d.tunOutbound)
|
||||||
|
}
|
||||||
|
|
||||||
|
func heartbeats(ctx context.Context, tun net.Conn) {
|
||||||
|
tunIfi, err := util.GetTunDeviceByConn(tun)
|
||||||
|
if err != nil {
|
||||||
|
plog.G(ctx).Errorf("Failed to get tun device: %s", err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
srcIPv4, srcIPv6, dockerSrcIPv4, err := util.GetTunDeviceIP(tunIfi.Name)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ticker := time.NewTicker(time.Second * 60)
|
||||||
|
defer ticker.Stop()
|
||||||
|
|
||||||
|
for ; true; <-ticker.C {
|
||||||
|
select {
|
||||||
|
case <-ctx.Done():
|
||||||
|
return
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
if srcIPv4 != nil {
|
||||||
|
util.Ping(ctx, srcIPv4.String(), config.RouterIP.String())
|
||||||
|
}
|
||||||
|
if srcIPv6 != nil {
|
||||||
|
util.Ping(ctx, srcIPv6.String(), config.RouterIP6.String())
|
||||||
|
}
|
||||||
|
if dockerSrcIPv4 != nil {
|
||||||
|
util.Ping(ctx, dockerSrcIPv4.String(), config.DockerRouterIP.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -2,65 +2,51 @@ package core
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
|
||||||
"io"
|
"io"
|
||||||
"net"
|
|
||||||
|
|
||||||
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
type datagramPacket struct {
|
type DatagramPacket struct {
|
||||||
DataLength uint16 // [2]byte
|
DataLength uint16 // [2]byte
|
||||||
Data []byte // []byte
|
Data []byte // []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
func (addr *datagramPacket) String() string {
|
func newDatagramPacket(data []byte) (r *DatagramPacket) {
|
||||||
if addr == nil {
|
return &DatagramPacket{
|
||||||
return ""
|
|
||||||
}
|
|
||||||
return fmt.Sprintf("DataLength: %d, Data: %v\n", addr.DataLength, addr.Data)
|
|
||||||
}
|
|
||||||
|
|
||||||
func newDatagramPacket(data []byte) (r *datagramPacket) {
|
|
||||||
return &datagramPacket{
|
|
||||||
DataLength: uint16(len(data)),
|
DataLength: uint16(len(data)),
|
||||||
Data: data,
|
Data: data,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (addr *datagramPacket) Addr() net.Addr {
|
func readDatagramPacket(r io.Reader, b []byte) (*DatagramPacket, error) {
|
||||||
var server8422, _ = net.ResolveUDPAddr("udp", "127.0.0.1:8422")
|
|
||||||
return server8422
|
|
||||||
}
|
|
||||||
|
|
||||||
func readDatagramPacket(r io.Reader, b []byte) (*datagramPacket, error) {
|
|
||||||
_, err := io.ReadFull(r, b[:2])
|
_, err := io.ReadFull(r, b[:2])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
dataLength := binary.BigEndian.Uint16(b[:2])
|
dataLength := binary.BigEndian.Uint16(b[:2])
|
||||||
_, err = io.ReadFull(r, b[:dataLength])
|
_, err = io.ReadFull(r, b[:dataLength])
|
||||||
if err != nil /*&& (err != io.ErrUnexpectedEOF || err != io.EOF)*/ {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &datagramPacket{DataLength: dataLength, Data: b[:dataLength]}, nil
|
return &DatagramPacket{DataLength: dataLength, Data: b[:dataLength]}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// this method will return all byte array in the way: b[:]
|
// this method will return all byte array in the way: b[:]
|
||||||
func readDatagramPacketServer(r io.Reader, b []byte) (*datagramPacket, error) {
|
func readDatagramPacketServer(r io.Reader, b []byte) (*DatagramPacket, error) {
|
||||||
_, err := io.ReadFull(r, b[:2])
|
_, err := io.ReadFull(r, b[:2])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
dataLength := binary.BigEndian.Uint16(b[:2])
|
dataLength := binary.BigEndian.Uint16(b[:2])
|
||||||
_, err = io.ReadFull(r, b[:dataLength])
|
_, err = io.ReadFull(r, b[:dataLength])
|
||||||
if err != nil /*&& (err != io.ErrUnexpectedEOF || err != io.EOF)*/ {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &datagramPacket{DataLength: dataLength, Data: b[:]}, nil
|
return &DatagramPacket{DataLength: dataLength, Data: b[:]}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (addr *datagramPacket) Write(w io.Writer) error {
|
func (addr *DatagramPacket) Write(w io.Writer) error {
|
||||||
buf := config.LPool.Get().([]byte)[:]
|
buf := config.LPool.Get().([]byte)[:]
|
||||||
defer config.LPool.Put(buf[:])
|
defer config.LPool.Put(buf[:])
|
||||||
binary.BigEndian.PutUint16(buf[:2], uint16(len(addr.Data)))
|
binary.BigEndian.PutUint16(buf[:2], uint16(len(addr.Data)))
|
||||||
|
@@ -2,15 +2,16 @@ package action
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
plog "github.com/wencaiwulue/kubevpn/v2/pkg/log"
|
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/containernetworking/cni/pkg/types"
|
"github.com/containernetworking/cni/pkg/types"
|
||||||
|
|
||||||
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
"github.com/wencaiwulue/kubevpn/v2/pkg/config"
|
||||||
"github.com/wencaiwulue/kubevpn/v2/pkg/core"
|
"github.com/wencaiwulue/kubevpn/v2/pkg/core"
|
||||||
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon/rpc"
|
"github.com/wencaiwulue/kubevpn/v2/pkg/daemon/rpc"
|
||||||
"github.com/wencaiwulue/kubevpn/v2/pkg/handler"
|
"github.com/wencaiwulue/kubevpn/v2/pkg/handler"
|
||||||
|
plog "github.com/wencaiwulue/kubevpn/v2/pkg/log"
|
||||||
"github.com/wencaiwulue/kubevpn/v2/pkg/tun"
|
"github.com/wencaiwulue/kubevpn/v2/pkg/tun"
|
||||||
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
||||||
)
|
)
|
||||||
@@ -44,7 +45,7 @@ func (svr *Server) SshStart(ctx context.Context, req *rpc.SshStartRequest) (resp
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
r := core.Route{
|
r := core.Route{
|
||||||
ServeNodes: []string{
|
Listeners: []string{
|
||||||
"tun://127.0.0.1:8422?net=" + DefaultServerIP,
|
"tun://127.0.0.1:8422?net=" + DefaultServerIP,
|
||||||
"tcp://:10800",
|
"tcp://:10800",
|
||||||
},
|
},
|
||||||
|
@@ -130,10 +130,10 @@ func (w *wsHandler) createTwoWayTUNTunnel(ctx context.Context, cli *ssh.Client)
|
|||||||
w.PrintLine(msg)
|
w.PrintLine(msg)
|
||||||
w.cidr = append(w.cidr, string(serverIP))
|
w.cidr = append(w.cidr, string(serverIP))
|
||||||
r := core.Route{
|
r := core.Route{
|
||||||
ServeNodes: []string{
|
Listeners: []string{
|
||||||
fmt.Sprintf("tun:/127.0.0.1:8422?net=%s&route=%s", clientIP, strings.Join(w.cidr, ",")),
|
fmt.Sprintf("tun:/127.0.0.1:8422?net=%s&route=%s", clientIP, strings.Join(w.cidr, ",")),
|
||||||
},
|
},
|
||||||
ChainNode: fmt.Sprintf("tcp://127.0.0.1:%d", localPort),
|
Forwarder: fmt.Sprintf("tcp://127.0.0.1:%d", localPort),
|
||||||
Retries: 5,
|
Retries: 5,
|
||||||
}
|
}
|
||||||
servers, err := handler.Parse(r)
|
servers, err := handler.Parse(r)
|
||||||
|
@@ -416,18 +416,18 @@ func (c *ConnectOptions) startLocalTunServer(ctx context.Context, forwardAddress
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
chainNode, err := core.ParseNode(forwardAddress)
|
forward, err := core.ParseNode(forwardAddress)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
plog.G(ctx).Errorf("Failed to parse forward node %s: %v", forwardAddress, err)
|
plog.G(ctx).Errorf("Failed to parse forward node %s: %v", forwardAddress, err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
chainNode.Client = &core.Client{
|
forward.Client = &core.Client{
|
||||||
Connector: core.UDPOverTCPTunnelConnector(),
|
Connector: core.NewUDPOverTCPConnector(),
|
||||||
Transporter: core.TCPTransporter(),
|
Transporter: core.TCPTransporter(),
|
||||||
}
|
}
|
||||||
chain := core.NewChain(5, chainNode)
|
forwarder := core.NewForwarder(5, forward)
|
||||||
|
|
||||||
handler := core.TunHandler(chain, node)
|
handler := core.TunHandler(forwarder, node)
|
||||||
listener, err := tun.Listener(tunConfig)
|
listener, err := tun.Listener(tunConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
plog.G(ctx).Errorf("Failed to create tun listener: %v", err)
|
plog.G(ctx).Errorf("Failed to create tun listener: %v", err)
|
||||||
@@ -703,7 +703,7 @@ func Parse(r core.Route) ([]core.Server, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(servers) == 0 {
|
if len(servers) == 0 {
|
||||||
return nil, fmt.Errorf("server is empty, server config: %s", strings.Join(r.ServeNodes, ","))
|
return nil, fmt.Errorf("server is empty, server config: %s", strings.Join(r.Listeners, ","))
|
||||||
}
|
}
|
||||||
return servers, nil
|
return servers, nil
|
||||||
}
|
}
|
||||||
@@ -772,7 +772,7 @@ func (c *ConnectOptions) getCIDR(ctx context.Context, m *dhcp.Manager) (err erro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if len(c.cidrs) != 0 {
|
if len(c.cidrs) != 0 {
|
||||||
plog.G(ctx).Infoln("Got network CIDR from cache")
|
plog.G(ctx).Infoln("Get network CIDR from cache")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -365,21 +365,19 @@ func genDeploySpec(namespace string, udp8422 string, tcp10800 string, tcp9002 st
|
|||||||
Args: []string{util.If(
|
Args: []string{util.If(
|
||||||
gvisor,
|
gvisor,
|
||||||
`
|
`
|
||||||
kubevpn server -L "tcp://:10800" -L "gtcp://:10801" -L "gudp://:10802" --debug=true`,
|
kubevpn server -l "tcp://:10800" -l "gtcp://:10801" -l "gudp://:10802" --debug=true`,
|
||||||
`
|
`
|
||||||
sysctl -w net.ipv4.ip_forward=1
|
sysctl -w net.ipv4.ip_forward=1
|
||||||
sysctl -w net.ipv6.conf.all.disable_ipv6=0
|
sysctl -w net.ipv6.conf.all.disable_ipv6=0
|
||||||
sysctl -w net.ipv6.conf.all.forwarding=1
|
sysctl -w net.ipv6.conf.all.forwarding=1
|
||||||
update-alternatives --set iptables /usr/sbin/iptables-legacy
|
update-alternatives --set iptables /usr/sbin/iptables-legacy
|
||||||
iptables -F
|
|
||||||
ip6tables -F
|
|
||||||
iptables -P INPUT ACCEPT
|
iptables -P INPUT ACCEPT
|
||||||
ip6tables -P INPUT ACCEPT
|
ip6tables -P INPUT ACCEPT
|
||||||
iptables -P FORWARD ACCEPT
|
iptables -P FORWARD ACCEPT
|
||||||
ip6tables -P FORWARD ACCEPT
|
ip6tables -P FORWARD ACCEPT
|
||||||
iptables -t nat -A POSTROUTING -s ${CIDR4} -o eth0 -j MASQUERADE
|
iptables -t nat -A POSTROUTING -s ${CIDR4} -o eth0 -j MASQUERADE
|
||||||
ip6tables -t nat -A POSTROUTING -s ${CIDR6} -o eth0 -j MASQUERADE
|
ip6tables -t nat -A POSTROUTING -s ${CIDR6} -o eth0 -j MASQUERADE
|
||||||
kubevpn server -L "tcp://:10800" -L "tun://:8422?net=${TunIPv4}" -L "gtcp://:10801" -L "gudp://:10802" --debug=true`,
|
kubevpn server -l "tcp://:10800" -l "tun://:8422?net=${TunIPv4}&net6=${TunIPv6}" -l "gtcp://:10801" -l "gudp://:10802" --debug=true`,
|
||||||
)},
|
)},
|
||||||
EnvFrom: []v1.EnvFromSource{{
|
EnvFrom: []v1.EnvFromSource{{
|
||||||
SecretRef: &v1.SecretEnvSource{
|
SecretRef: &v1.SecretEnvSource{
|
||||||
|
@@ -51,8 +51,6 @@ sysctl -w net.ipv4.ip_forward=1
|
|||||||
sysctl -w net.ipv6.conf.all.disable_ipv6=0
|
sysctl -w net.ipv6.conf.all.disable_ipv6=0
|
||||||
sysctl -w net.ipv6.conf.all.forwarding=1
|
sysctl -w net.ipv6.conf.all.forwarding=1
|
||||||
update-alternatives --set iptables /usr/sbin/iptables-legacy
|
update-alternatives --set iptables /usr/sbin/iptables-legacy
|
||||||
iptables -F
|
|
||||||
ip6tables -F
|
|
||||||
iptables -P INPUT ACCEPT
|
iptables -P INPUT ACCEPT
|
||||||
ip6tables -P INPUT ACCEPT
|
ip6tables -P INPUT ACCEPT
|
||||||
iptables -P FORWARD ACCEPT
|
iptables -P FORWARD ACCEPT
|
||||||
@@ -61,7 +59,7 @@ iptables -t nat -A PREROUTING ! -p icmp ! -s 127.0.0.1 ! -d ${CIDR4} -j DNAT --t
|
|||||||
ip6tables -t nat -A PREROUTING ! -p icmp ! -s 0:0:0:0:0:0:0:1 ! -d ${CIDR6} -j DNAT --to :15006
|
ip6tables -t nat -A PREROUTING ! -p icmp ! -s 0:0:0:0:0:0:0:1 ! -d ${CIDR6} -j DNAT --to :15006
|
||||||
iptables -t nat -A POSTROUTING ! -p icmp ! -s 127.0.0.1 ! -d ${CIDR4} -j MASQUERADE
|
iptables -t nat -A POSTROUTING ! -p icmp ! -s 127.0.0.1 ! -d ${CIDR4} -j MASQUERADE
|
||||||
ip6tables -t nat -A POSTROUTING ! -p icmp ! -s 0:0:0:0:0:0:0:1 ! -d ${CIDR6} -j MASQUERADE
|
ip6tables -t nat -A POSTROUTING ! -p icmp ! -s 0:0:0:0:0:0:0:1 ! -d ${CIDR6} -j MASQUERADE
|
||||||
kubevpn server -L "tun:/localhost:8422?net=${TunIPv4}&route=${CIDR4}" -F "tcp://${TrafficManagerService}:10800"`,
|
kubevpn server -l "tun:/localhost:8422?net=${TunIPv4}&net6=${TunIPv6}&route=${CIDR4}" -f "tcp://${TrafficManagerService}:10800"`,
|
||||||
},
|
},
|
||||||
Env: []v1.EnvVar{
|
Env: []v1.EnvVar{
|
||||||
{
|
{
|
||||||
@@ -170,7 +168,7 @@ func AddEnvoyContainer(spec *v1.PodTemplateSpec, ns, nodeId string, ipv6 bool, c
|
|||||||
Image: config.Image,
|
Image: config.Image,
|
||||||
Command: []string{"/bin/sh", "-c"},
|
Command: []string{"/bin/sh", "-c"},
|
||||||
Args: []string{`
|
Args: []string{`
|
||||||
kubevpn server -L "ssh://:2222"`,
|
kubevpn server -l "ssh://:2222"`,
|
||||||
},
|
},
|
||||||
Resources: v1.ResourceRequirements{
|
Resources: v1.ResourceRequirements{
|
||||||
Requests: map[v1.ResourceName]resource.Quantity{
|
Requests: map[v1.ResourceName]resource.Quantity{
|
||||||
|
@@ -84,8 +84,6 @@ sysctl -w net.ipv6.conf.all.disable_ipv6=0
|
|||||||
sysctl -w net.ipv6.conf.all.forwarding=1
|
sysctl -w net.ipv6.conf.all.forwarding=1
|
||||||
sysctl -w net.ipv4.conf.all.route_localnet=1
|
sysctl -w net.ipv4.conf.all.route_localnet=1
|
||||||
update-alternatives --set iptables /usr/sbin/iptables-legacy
|
update-alternatives --set iptables /usr/sbin/iptables-legacy
|
||||||
iptables -F
|
|
||||||
ip6tables -F
|
|
||||||
iptables -P INPUT ACCEPT
|
iptables -P INPUT ACCEPT
|
||||||
ip6tables -P INPUT ACCEPT
|
ip6tables -P INPUT ACCEPT
|
||||||
iptables -P FORWARD ACCEPT
|
iptables -P FORWARD ACCEPT
|
||||||
@@ -94,7 +92,7 @@ iptables -t nat -A PREROUTING ! -p icmp -j DNAT --to ${LocalTunIPv4}
|
|||||||
ip6tables -t nat -A PREROUTING ! -p icmp -j DNAT --to ${LocalTunIPv6}
|
ip6tables -t nat -A PREROUTING ! -p icmp -j DNAT --to ${LocalTunIPv6}
|
||||||
iptables -t nat -A POSTROUTING ! -p icmp -j MASQUERADE
|
iptables -t nat -A POSTROUTING ! -p icmp -j MASQUERADE
|
||||||
ip6tables -t nat -A POSTROUTING ! -p icmp -j MASQUERADE
|
ip6tables -t nat -A POSTROUTING ! -p icmp -j MASQUERADE
|
||||||
kubevpn server -L "tun:/127.0.0.1:8422?net=${TunIPv4}&route=${CIDR4}" -F "tcp://${TrafficManagerService}:10800"`,
|
kubevpn server -l "tun:/127.0.0.1:8422?net=${TunIPv4}&net6=${TunIPv6}&route=${CIDR4}" -f "tcp://${TrafficManagerService}:10800"`,
|
||||||
},
|
},
|
||||||
SecurityContext: &corev1.SecurityContext{
|
SecurityContext: &corev1.SecurityContext{
|
||||||
Capabilities: &corev1.Capabilities{
|
Capabilities: &corev1.Capabilities{
|
||||||
|
@@ -32,7 +32,7 @@ func GetLoggerForClient(level int32, out io.Writer) *log.Logger {
|
|||||||
func InitLoggerForServer() *log.Logger {
|
func InitLoggerForServer() *log.Logger {
|
||||||
return &log.Logger{
|
return &log.Logger{
|
||||||
Out: os.Stderr,
|
Out: os.Stderr,
|
||||||
Formatter: &format{},
|
Formatter: &serverFormat{},
|
||||||
Hooks: make(log.LevelHooks),
|
Hooks: make(log.LevelHooks),
|
||||||
Level: log.DebugLevel,
|
Level: log.DebugLevel,
|
||||||
ExitFunc: os.Exit,
|
ExitFunc: os.Exit,
|
||||||
|
@@ -76,7 +76,7 @@ func createTun(cfg Config) (conn net.Conn, itf *net.Interface, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err = addTunRoutes(name, cfg.Routes...); err != nil {
|
if err = addTunRoutes(name, cfg.Routes...); err != nil {
|
||||||
err = pkgerr.Wrap(err, "Add tun routes failed")
|
err = pkgerr.Wrap(err, "Add tun device routes failed")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user