mirror of
https://github.com/kubenetworks/kubevpn.git
synced 2025-10-28 01:32:01 +08:00
feat: complete gvisor
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
FROM envoyproxy/envoy:v1.25.0 AS envoy
|
FROM envoyproxy/envoy:v1.25.0 AS envoy
|
||||||
FROM golang:1.19 AS builder
|
FROM golang:1.20 AS builder
|
||||||
ARG BASE=github.com/wencaiwulue/kubevpn
|
ARG BASE=github.com/wencaiwulue/kubevpn
|
||||||
|
|
||||||
COPY . /go/src/$BASE
|
COPY . /go/src/$BASE
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM golang:1.19 AS builder
|
FROM golang:1.20 AS builder
|
||||||
RUN go env -w GO111MODULE=on && go env -w GOPROXY=https://goproxy.cn,direct
|
RUN go env -w GO111MODULE=on && go env -w GOPROXY=https://goproxy.cn,direct
|
||||||
RUN go install github.com/go-delve/delve/cmd/dlv@latest
|
RUN go install github.com/go-delve/delve/cmd/dlv@latest
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package core
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"math"
|
"math"
|
||||||
"net"
|
"net"
|
||||||
)
|
)
|
||||||
@@ -61,7 +60,7 @@ func (c *Chain) dial(ctx context.Context) (net.Conn, error) {
|
|||||||
func (*Chain) resolve(addr string) string {
|
func (*Chain) 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 fmt.Sprintf("%s:%s", ips[0].String(), port)
|
return net.JoinHostPort(ips[0].String(), port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return addr
|
return addr
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ package core
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
@@ -16,33 +18,63 @@ import (
|
|||||||
"github.com/wencaiwulue/kubevpn/pkg/config"
|
"github.com/wencaiwulue/kubevpn/pkg/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var GvisorTCPForwardAddr string
|
||||||
|
|
||||||
func TCPForwarder(s *stack.Stack) func(stack.TransportEndpointID, *stack.PacketBuffer) bool {
|
func TCPForwarder(s *stack.Stack) func(stack.TransportEndpointID, *stack.PacketBuffer) bool {
|
||||||
rcvWnd := 1000 << 20 // 1000MB
|
rcvWnd := 1000 << 20 // 1000MB
|
||||||
return tcp.NewForwarder(s, rcvWnd, 100000, func(request *tcp.ForwarderRequest) {
|
return tcp.NewForwarder(s, rcvWnd, 100000, func(request *tcp.ForwarderRequest) {
|
||||||
defer request.Complete(false)
|
defer request.Complete(false)
|
||||||
id := request.ID()
|
id := request.ID()
|
||||||
log.Debugf("[TUN-TCP] Info: LocalPort: %d, LocalAddress: %s, RemotePort: %d, RemoteAddress %s",
|
log.Debugf("[TUN-TCP] Debug: LocalPort: %d, LocalAddress: %s, RemotePort: %d, RemoteAddress %s",
|
||||||
id.LocalPort, id.LocalAddress.String(), id.RemotePort, id.RemoteAddress.String(),
|
id.LocalPort, id.LocalAddress.String(), id.RemotePort, id.RemoteAddress.String(),
|
||||||
)
|
)
|
||||||
remote, err := net.Dial("tcp", "localhost:10801")
|
|
||||||
|
node, err := ParseNode(GvisorTCPForwardAddr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warningln(err)
|
log.Errorf("[TUN-TCP] Error: can not 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.Errorf("[TUN-TCP] Error: failed to dial remote conn: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = WriteProxyInfo(remote, id); err != nil {
|
if err = WriteProxyInfo(remote, id); err != nil {
|
||||||
log.Warningln(err)
|
log.Errorf("[TUN-TCP] Error: failed to write proxy info: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w := &waiter.Queue{}
|
w := &waiter.Queue{}
|
||||||
endpoint, t := request.CreateEndpoint(w)
|
endpoint, tErr := request.CreateEndpoint(w)
|
||||||
if t != nil {
|
if tErr != nil {
|
||||||
log.Warningln(t)
|
log.Errorf("[TUN-TCP] Error: can not create endpoint: %v", tErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
conn := gonet.NewTCPConn(w, endpoint)
|
conn := gonet.NewTCPConn(w, endpoint)
|
||||||
go io.Copy(remote, conn)
|
|
||||||
io.Copy(conn, remote)
|
defer conn.Close()
|
||||||
|
defer remote.Close()
|
||||||
|
errChan := make(chan error, 2)
|
||||||
|
go func() {
|
||||||
|
written, err2 := io.Copy(remote, conn)
|
||||||
|
log.Errorf("[TUN-TCP] Debug: write length %d data to remote", written)
|
||||||
|
errChan <- err2
|
||||||
|
}()
|
||||||
|
go func() {
|
||||||
|
written, err2 := io.Copy(conn, remote)
|
||||||
|
log.Errorf("[TUN-TCP] Debug: read length %d data from remote", written)
|
||||||
|
errChan <- err2
|
||||||
|
}()
|
||||||
|
err = <-errChan
|
||||||
|
if err != nil && !errors.Is(err, io.EOF) {
|
||||||
|
log.Errorf("[TUN-TCP] Error: dsiconnect: %s >-<: %s: %v", conn.LocalAddr(), remote.RemoteAddr(), err)
|
||||||
|
}
|
||||||
}).HandlePacket
|
}).HandlePacket
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,14 +2,41 @@ package core
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"strconv"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type gvisorTCPTunnelConnector struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
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{}
|
type gvisorTCPHandler struct{}
|
||||||
|
|
||||||
func GvisorTCPHandler() Handler {
|
func GvisorTCPHandler() Handler {
|
||||||
@@ -18,30 +45,41 @@ func GvisorTCPHandler() Handler {
|
|||||||
|
|
||||||
func (h *gvisorTCPHandler) Handle(ctx context.Context, tcpConn net.Conn) {
|
func (h *gvisorTCPHandler) Handle(ctx context.Context, tcpConn net.Conn) {
|
||||||
defer tcpConn.Close()
|
defer tcpConn.Close()
|
||||||
log.Debugf("[GvisorTCPServer] %s -> %s\n", tcpConn.RemoteAddr(), tcpConn.LocalAddr())
|
log.Debugf("[TUN-TCP] %s -> %s", tcpConn.RemoteAddr(), tcpConn.LocalAddr())
|
||||||
func(conn net.Conn) {
|
// 1, get proxy info
|
||||||
defer conn.Close()
|
endpointID, err := ParseProxyInfo(tcpConn)
|
||||||
// 1, get proxy info
|
if err != nil {
|
||||||
endpointID, err := ParseProxyInfo(conn)
|
log.Errorf("[TUN-TCP] Error: failed to parse proxy info: %v", err)
|
||||||
if err != nil {
|
return
|
||||||
log.Warning("failed to parse proxy info", "err: ", err)
|
}
|
||||||
return
|
log.Debugf("[TUN-TCP] Debug: LocalPort: %d, LocalAddress: %s, RemotePort: %d, RemoteAddress %s",
|
||||||
}
|
endpointID.LocalPort, endpointID.LocalAddress.String(), endpointID.RemotePort, endpointID.RemoteAddress.String(),
|
||||||
log.Debugf("[TUN-TCP] Info: 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()
|
||||||
// 2, dial proxy
|
port := fmt.Sprintf("%d", endpointID.LocalPort)
|
||||||
s := net.ParseIP(endpointID.LocalAddress.String()).String()
|
var remote net.Conn
|
||||||
port := strconv.FormatUint(uint64(endpointID.LocalPort), 10)
|
remote, err = net.DialTimeout("tcp", net.JoinHostPort(host, port), time.Second*5)
|
||||||
var dial net.Conn
|
if err != nil {
|
||||||
dial, err = net.DialTimeout("tcp", net.JoinHostPort(s, port), time.Second*5)
|
log.Errorf("[TUN-TCP] Error: failed to connect addr %s: %v", net.JoinHostPort(host, port), err)
|
||||||
if err != nil {
|
return
|
||||||
log.Warningln(err)
|
}
|
||||||
return
|
|
||||||
}
|
errChan := make(chan error, 2)
|
||||||
go io.Copy(conn, dial)
|
go func() {
|
||||||
io.Copy(dial, conn)
|
written, err2 := io.Copy(remote, tcpConn)
|
||||||
}(tcpConn)
|
log.Errorf("[TUN-TCP] Debug: write length %d data to remote", written)
|
||||||
|
errChan <- err2
|
||||||
|
}()
|
||||||
|
go func() {
|
||||||
|
written, err2 := io.Copy(tcpConn, remote)
|
||||||
|
log.Errorf("[TUN-TCP] Debug: read length %d data from remote", written)
|
||||||
|
errChan <- err2
|
||||||
|
}()
|
||||||
|
err = <-errChan
|
||||||
|
if err != nil && !errors.Is(err, io.EOF) {
|
||||||
|
log.Errorf("[TUN-TCP] Error: dsiconnect: %s >-<: %s: %v", tcpConn.LocalAddr(), remote.RemoteAddr(), err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func GvisorTCPListener(addr string) (net.Listener, error) {
|
func GvisorTCPListener(addr string) (net.Listener, error) {
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ package core
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
|
"gvisor.dev/gvisor/pkg/tcpip/adapters/gonet"
|
||||||
@@ -12,36 +12,65 @@ import (
|
|||||||
"gvisor.dev/gvisor/pkg/waiter"
|
"gvisor.dev/gvisor/pkg/waiter"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var GvisorUDPForwardAddr string
|
||||||
|
|
||||||
func UDPForwarder(s *stack.Stack) func(id stack.TransportEndpointID, pkt *stack.PacketBuffer) bool {
|
func UDPForwarder(s *stack.Stack) func(id stack.TransportEndpointID, pkt *stack.PacketBuffer) bool {
|
||||||
return udp.NewForwarder(s, func(request *udp.ForwarderRequest) {
|
return udp.NewForwarder(s, func(request *udp.ForwarderRequest) {
|
||||||
endpointID := request.ID()
|
endpointID := request.ID()
|
||||||
log.Infof("[TUN-UDP] Info: LocalPort: %d, LocalAddress: %s, RemotePort: %d, RemoteAddress %s",
|
log.Debugf("[TUN-UDP] Debug: LocalPort: %d, LocalAddress: %s, RemotePort: %d, RemoteAddress %s",
|
||||||
endpointID.LocalPort, endpointID.LocalAddress.String(), endpointID.RemotePort, endpointID.RemoteAddress.String(),
|
endpointID.LocalPort, endpointID.LocalAddress.String(), endpointID.RemotePort, endpointID.RemoteAddress.String(),
|
||||||
)
|
)
|
||||||
w := &waiter.Queue{}
|
w := &waiter.Queue{}
|
||||||
endpoint, t := request.CreateEndpoint(w)
|
endpoint, tErr := request.CreateEndpoint(w)
|
||||||
if t != nil {
|
if tErr != nil {
|
||||||
log.Warningln(t)
|
log.Errorf("[TUN-UDP] Error: can not create endpoint: %v", tErr)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c, err2 := net.Dial("tcp", "127.0.0.1:10802")
|
|
||||||
if err2 != nil {
|
node, err := ParseNode(GvisorUDPForwardAddr)
|
||||||
log.Error(err2)
|
|
||||||
}
|
|
||||||
if err := WriteProxyInfo(c, endpointID); err != nil {
|
|
||||||
log.Warningln(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ctx := context.Background()
|
|
||||||
dial, err := GvisorUDPOverTCPTunnelConnector(endpointID).ConnectContext(ctx, c)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warningln(err)
|
log.Errorf("[TUN-UDP] Error: 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.Errorf("[TUN-UDP] Error: can not get conn: %v", err)
|
||||||
|
}
|
||||||
|
if err = WriteProxyInfo(c, endpointID); err != nil {
|
||||||
|
log.Errorf("[TUN-UDP] Error: can not write proxy info: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
remote, err := node.Client.ConnectContext(ctx, c)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("[TUN-UDP] Error: can not connect: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
conn := gonet.NewUDPConn(s, w, endpoint)
|
conn := gonet.NewUDPConn(s, w, endpoint)
|
||||||
go func() {
|
go func() {
|
||||||
go io.Copy(dial, conn)
|
defer conn.Close()
|
||||||
io.Copy(conn, dial)
|
defer remote.Close()
|
||||||
|
errChan := make(chan error, 2)
|
||||||
|
go func() {
|
||||||
|
written, err2 := io.Copy(remote, conn)
|
||||||
|
log.Errorf("[TUN-UDP] Debug: write length %d data to remote", written)
|
||||||
|
errChan <- err2
|
||||||
|
}()
|
||||||
|
go func() {
|
||||||
|
written, err2 := io.Copy(conn, remote)
|
||||||
|
log.Errorf("[TUN-UDP] Debug: read length %d data from remote", written)
|
||||||
|
errChan <- err2
|
||||||
|
}()
|
||||||
|
err = <-errChan
|
||||||
|
if err != nil && !errors.Is(err, io.EOF) {
|
||||||
|
log.Errorf("[TUN-UDP] Error: dsiconnect: %s >-<: %s: %v", conn.LocalAddr(), remote.RemoteAddr(), err)
|
||||||
|
}
|
||||||
}()
|
}()
|
||||||
}).HandlePacket
|
}).HandlePacket
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package core
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
@@ -14,17 +13,17 @@ import (
|
|||||||
"github.com/wencaiwulue/kubevpn/pkg/config"
|
"github.com/wencaiwulue/kubevpn/pkg/config"
|
||||||
)
|
)
|
||||||
|
|
||||||
type GvisorFakeUDPTunnelConnector struct {
|
type gvisorUDPOverTCPTunnelConnector struct {
|
||||||
Id stack.TransportEndpointID
|
Id stack.TransportEndpointID
|
||||||
}
|
}
|
||||||
|
|
||||||
func GvisorUDPOverTCPTunnelConnector(endpointID stack.TransportEndpointID) Connector {
|
func GvisorUDPOverTCPTunnelConnector(endpointID stack.TransportEndpointID) Connector {
|
||||||
return &GvisorFakeUDPTunnelConnector{
|
return &gvisorUDPOverTCPTunnelConnector{
|
||||||
Id: endpointID,
|
Id: endpointID,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *GvisorFakeUDPTunnelConnector) ConnectContext(ctx context.Context, conn net.Conn) (net.Conn, error) {
|
func (c *gvisorUDPOverTCPTunnelConnector) ConnectContext(ctx context.Context, conn net.Conn) (net.Conn, error) {
|
||||||
switch con := conn.(type) {
|
switch con := conn.(type) {
|
||||||
case *net.TCPConn:
|
case *net.TCPConn:
|
||||||
err := con.SetNoDelay(true)
|
err := con.SetNoDelay(true)
|
||||||
@@ -52,31 +51,27 @@ func GvisorUDPHandler() Handler {
|
|||||||
func (h *gvisorUDPHandler) Handle(ctx context.Context, tcpConn net.Conn) {
|
func (h *gvisorUDPHandler) Handle(ctx context.Context, tcpConn net.Conn) {
|
||||||
defer tcpConn.Close()
|
defer tcpConn.Close()
|
||||||
log.Debugf("[TUN-UDP] %s -> %s", tcpConn.RemoteAddr(), tcpConn.LocalAddr())
|
log.Debugf("[TUN-UDP] %s -> %s", tcpConn.RemoteAddr(), tcpConn.LocalAddr())
|
||||||
func(conn net.Conn) {
|
// 1, get proxy info
|
||||||
defer conn.Close()
|
endpointID, err := ParseProxyInfo(tcpConn)
|
||||||
// 1, get proxy info
|
if err != nil {
|
||||||
endpointID, err := ParseProxyInfo(conn)
|
log.Warningf("[TUN-UDP] Error: Failed to parse proxy info: %v", err)
|
||||||
if err != nil {
|
return
|
||||||
log.Warningf("[TUN-UDP] ERROR Failed to parse proxy info: %v", err)
|
}
|
||||||
return
|
log.Debugf("[TUN-UDP] Debug: LocalPort: %d, LocalAddress: %s, RemotePort: %d, RemoteAddress %s",
|
||||||
}
|
endpointID.LocalPort, endpointID.LocalAddress.String(), endpointID.RemotePort, endpointID.RemoteAddress.String(),
|
||||||
log.Infof("[TUN-UDP] Info: LocalPort: %d, LocalAddress: %s, RemotePort: %d, RemoteAddress %s",
|
)
|
||||||
endpointID.LocalPort, endpointID.LocalAddress.String(), endpointID.RemotePort, endpointID.RemoteAddress.String(),
|
// 2, dial proxy
|
||||||
)
|
addr := &net.UDPAddr{
|
||||||
// 2, dial proxy
|
IP: endpointID.LocalAddress.AsSlice(),
|
||||||
var dial *net.UDPConn
|
Port: int(endpointID.LocalPort),
|
||||||
// todo 发送到 localhost:8422 ? 🤔
|
}
|
||||||
addr := &net.UDPAddr{
|
var remote *net.UDPConn
|
||||||
IP: endpointID.LocalAddress.AsSlice(),
|
remote, err = net.DialUDP("udp", nil, addr)
|
||||||
Port: int(endpointID.LocalPort),
|
if err != nil {
|
||||||
}
|
log.Errorf("[TUN-UDP] Error: failed to connect addr %s: %v", addr.String(), err)
|
||||||
dial, err = net.DialUDP("udp", nil, addr)
|
return
|
||||||
if err != nil {
|
}
|
||||||
log.Warningln(err)
|
handle(ctx, tcpConn, remote)
|
||||||
return
|
|
||||||
}
|
|
||||||
h.HandleInner(ctx, tcpConn, dial)
|
|
||||||
}(tcpConn)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fake udp connect over tcp
|
// fake udp connect over tcp
|
||||||
@@ -93,7 +88,7 @@ func newGvisorFakeUDPTunnelConnOverTCP(ctx context.Context, conn net.Conn) (net.
|
|||||||
func (c *gvisorFakeUDPTunnelConn) Read(b []byte) (int, error) {
|
func (c *gvisorFakeUDPTunnelConn) Read(b []byte) (int, error) {
|
||||||
select {
|
select {
|
||||||
case <-c.ctx.Done():
|
case <-c.ctx.Done():
|
||||||
return 0, errors.New("closed connection")
|
return 0, c.ctx.Err()
|
||||||
default:
|
default:
|
||||||
dgram, err := readDatagramPacket(c.Conn, b)
|
dgram, err := readDatagramPacket(c.Conn, b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -156,10 +151,9 @@ func copyPacketData(dst, src net.PacketConn, to net.Addr, timeout time.Duration)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *gvisorUDPHandler) HandleInner(ctx context.Context, tcpConn net.Conn, udpConn *net.UDPConn) {
|
func handle(ctx context.Context, tcpConn net.Conn, udpConn *net.UDPConn) {
|
||||||
defer udpConn.Close()
|
defer udpConn.Close()
|
||||||
log.Debugf("[TUN-UDP] %s -> %s", tcpConn.RemoteAddr(), tcpConn.LocalAddr())
|
log.Debugf("[TUN-UDP] Debug: %s <-> %s", tcpConn.RemoteAddr(), udpConn.LocalAddr())
|
||||||
log.Debugf("[TUN-UDP] udp-tun %s <-> %s", tcpConn.RemoteAddr(), udpConn.LocalAddr())
|
|
||||||
errChan := make(chan error, 2)
|
errChan := make(chan error, 2)
|
||||||
go func() {
|
go func() {
|
||||||
b := config.LPool.Get().([]byte)
|
b := config.LPool.Get().([]byte)
|
||||||
@@ -168,22 +162,22 @@ func (h *gvisorUDPHandler) HandleInner(ctx context.Context, tcpConn net.Conn, ud
|
|||||||
for {
|
for {
|
||||||
dgram, err := readDatagramPacket(tcpConn, b[:])
|
dgram, err := readDatagramPacket(tcpConn, b[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debugf("[TUN-UDP] %s -> 0 : %v", tcpConn.RemoteAddr(), err)
|
log.Debugf("[TUN-UDP] Debug: %s -> 0 : %v", tcpConn.RemoteAddr(), err)
|
||||||
errChan <- err
|
errChan <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if dgram.DataLength == 0 {
|
if dgram.DataLength == 0 {
|
||||||
log.Debugf("[TUN-UDP] length is zero")
|
log.Debugf("[TUN-UDP] Error: length is zero")
|
||||||
errChan <- fmt.Errorf("length of read packet is zero")
|
errChan <- fmt.Errorf("length of read packet is zero")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err = udpConn.Write(dgram.Data); err != nil {
|
if _, err = udpConn.Write(dgram.Data); err != nil {
|
||||||
log.Debugf("[TUN-UDP] udp-tun %s -> %s : %s", tcpConn.RemoteAddr(), Server8422, err)
|
log.Debugf("[TUN-UDP] Error: %s -> %s : %s", tcpConn.RemoteAddr(), Server8422, err)
|
||||||
errChan <- err
|
errChan <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debugf("[TUN-UDP] udp-tun %s >>> %s length: %d", tcpConn.RemoteAddr(), Server8422, dgram.DataLength)
|
log.Debugf("[TUN-UDP] Debug: %s >>> %s length: %d", tcpConn.RemoteAddr(), Server8422, dgram.DataLength)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
@@ -194,12 +188,12 @@ func (h *gvisorUDPHandler) HandleInner(ctx context.Context, tcpConn net.Conn, ud
|
|||||||
for {
|
for {
|
||||||
n, _, err := udpConn.ReadFrom(b[:])
|
n, _, err := udpConn.ReadFrom(b[:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debugf("[TUN-UDP] %s : %s", tcpConn.RemoteAddr(), err)
|
log.Debugf("[TUN-UDP] Error: %s : %s", tcpConn.RemoteAddr(), err)
|
||||||
errChan <- err
|
errChan <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if n == 0 {
|
if n == 0 {
|
||||||
log.Debugf("[TUN-UDP] length is zero")
|
log.Debugf("[TUN-UDP] Error: length is zero")
|
||||||
errChan <- fmt.Errorf("length of read packet is zero")
|
errChan <- fmt.Errorf("length of read packet is zero")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -207,17 +201,17 @@ func (h *gvisorUDPHandler) HandleInner(ctx context.Context, tcpConn net.Conn, ud
|
|||||||
// pipe from peer to tunnel
|
// pipe from peer to tunnel
|
||||||
dgram := newDatagramPacket(b[:n])
|
dgram := newDatagramPacket(b[:n])
|
||||||
if err = dgram.Write(tcpConn); err != nil {
|
if err = dgram.Write(tcpConn); err != nil {
|
||||||
log.Debugf("[TUN-UDP] udp-tun %s <- %s : %s", tcpConn.RemoteAddr(), dgram.Addr(), err)
|
log.Debugf("[TUN-UDP] Error: %s <- %s : %s", tcpConn.RemoteAddr(), dgram.Addr(), err)
|
||||||
errChan <- err
|
errChan <- err
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Debugf("[TUN-UDP] udp-tun %s <<< %s length: %d", tcpConn.RemoteAddr(), dgram.Addr(), len(dgram.Data))
|
log.Debugf("[TUN-UDP] Debug: %s <<< %s length: %d", tcpConn.RemoteAddr(), dgram.Addr(), len(dgram.Data))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
err := <-errChan
|
err := <-errChan
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Debugf("[TUN-UDP] Error: %v", err)
|
||||||
}
|
}
|
||||||
log.Debugf("[TUN-UDP] udp-tun %s >-< %s", tcpConn.RemoteAddr(), udpConn.LocalAddr())
|
log.Debugf("[TUN-UDP] Debug: %s >-< %s", tcpConn.RemoteAddr(), udpConn.LocalAddr())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package core
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"net"
|
"net"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
@@ -119,7 +118,7 @@ func newFakeUDPTunnelConnOverTCP(ctx context.Context, conn net.Conn) (net.Conn,
|
|||||||
func (c *fakeUDPTunnelConn) ReadFrom(b []byte) (int, net.Addr, error) {
|
func (c *fakeUDPTunnelConn) ReadFrom(b []byte) (int, net.Addr, error) {
|
||||||
select {
|
select {
|
||||||
case <-c.ctx.Done():
|
case <-c.ctx.Done():
|
||||||
return 0, nil, errors.New("closed connection")
|
return 0, nil, c.ctx.Err()
|
||||||
default:
|
default:
|
||||||
dgram, err := readDatagramPacket(c.Conn, b)
|
dgram, err := readDatagramPacket(c.Conn, b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ func (d *Device) parseIPHeader() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("[tun] %s --> %s", e.src, e.dst)
|
log.Debugf("[tun] %s --> %s, length: %d", e.src, e.dst, e.length)
|
||||||
d.tunInbound <- e
|
d.tunInbound <- e
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -370,7 +370,7 @@ func (d *Device) Start(ctx context.Context) {
|
|||||||
}
|
}
|
||||||
go d.tunInboundHandler(d.tunInbound, d.tunOutbound)
|
go d.tunInboundHandler(d.tunInbound, d.tunOutbound)
|
||||||
go d.writeToTun()
|
go d.writeToTun()
|
||||||
//go heartbeats(d.tunInbound)
|
go heartbeats(d.tunInbound)
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case err := <-d.chExit:
|
case err := <-d.chExit:
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ type ClientDevice struct {
|
|||||||
|
|
||||||
func (d *ClientDevice) Start(ctx context.Context) {
|
func (d *ClientDevice) Start(ctx context.Context) {
|
||||||
go d.tunInboundHandler(d.tunInbound, d.tunOutbound)
|
go d.tunInboundHandler(d.tunInbound, d.tunOutbound)
|
||||||
//go heartbeats(d.tunInbound)
|
go heartbeats(d.tunInbound)
|
||||||
|
|
||||||
select {
|
select {
|
||||||
case err := <-d.chExit:
|
case err := <-d.chExit:
|
||||||
|
|||||||
@@ -4,9 +4,9 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -102,7 +102,7 @@ func (s *server) ServeDNS(w miekgdns.ResponseWriter, r *miekgdns.Msg) {
|
|||||||
msg.Ns = nil
|
msg.Ns = nil
|
||||||
msg.Extra = nil
|
msg.Extra = nil
|
||||||
msg.Id = uint16(rand.Intn(math.MaxUint16 + 1))
|
msg.Id = uint16(rand.Intn(math.MaxUint16 + 1))
|
||||||
answer, _, err := s.client.ExchangeContext(context.Background(), &msg, fmt.Sprintf("%s:%s", dnsAddr, s.forwardDNS.Port))
|
answer, _, err := s.client.ExchangeContext(context.Background(), &msg, net.JoinHostPort(dnsAddr, s.forwardDNS.Port))
|
||||||
|
|
||||||
if err == nil && len(answer.Answer) != 0 {
|
if err == nil && len(answer.Answer) != 0 {
|
||||||
s.dnsCache.Add(originName, name, time.Hour*24*365*100) // never expire
|
s.dnsCache.Add(originName, name, time.Hour*24*365*100) // never expire
|
||||||
|
|||||||
@@ -158,16 +158,20 @@ func (c *ConnectOptions) DoConnect() (err error) {
|
|||||||
if err = c.portForward(ctx, fmt.Sprintf("%d:10800", port)); err != nil {
|
if err = c.portForward(ctx, fmt.Sprintf("%d:10800", port)); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = c.portForward(ctx, "10801:10801"); err != nil {
|
tcpForwardPort := util.GetAvailableTCPPortOrDie()
|
||||||
|
if err = c.portForward(ctx, fmt.Sprintf("%d:10801", tcpForwardPort)); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = c.portForward(ctx, "10802:10802"); err != nil {
|
udpForwardPort := util.GetAvailableTCPPortOrDie()
|
||||||
|
if err = c.portForward(ctx, fmt.Sprintf("%d:10802", udpForwardPort)); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if util.IsWindows() {
|
if util.IsWindows() {
|
||||||
driver.InstallWireGuardTunDriver()
|
driver.InstallWireGuardTunDriver()
|
||||||
}
|
}
|
||||||
forward := fmt.Sprintf("tcp://127.0.0.1:%d", port)
|
forward := fmt.Sprintf("tcp://127.0.0.1:%d", port)
|
||||||
|
core.GvisorTCPForwardAddr = fmt.Sprintf("tcp://127.0.0.1:%d", tcpForwardPort)
|
||||||
|
core.GvisorUDPForwardAddr = fmt.Sprintf("tcp://127.0.0.1:%d", udpForwardPort)
|
||||||
if err = c.startLocalTunServe(ctx, forward); err != nil {
|
if err = c.startLocalTunServe(ctx, forward); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -181,13 +185,13 @@ func (c *ConnectOptions) DoConnect() (err error) {
|
|||||||
if err = c.setupDNS(); err != nil {
|
if err = c.setupDNS(); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
//go c.heartbeats()
|
go c.heartbeats()
|
||||||
log.Info("dns service ok")
|
log.Info("dns service ok")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// detect pod is delete event, if pod is deleted, needs to redo port-forward immediately
|
// detect pod is delete event, if pod is deleted, needs to redo port-forward immediately
|
||||||
func (c *ConnectOptions) portForward(ctx context.Context, port string) error {
|
func (c *ConnectOptions) portForward(ctx context.Context, portPair string) error {
|
||||||
var readyChan = make(chan struct{}, 1)
|
var readyChan = make(chan struct{}, 1)
|
||||||
var errChan = make(chan error, 1)
|
var errChan = make(chan error, 1)
|
||||||
podInterface := c.clientset.CoreV1().Pods(c.Namespace)
|
podInterface := c.clientset.CoreV1().Pods(c.Namespace)
|
||||||
@@ -218,7 +222,7 @@ func (c *ConnectOptions) portForward(ctx context.Context, port string) error {
|
|||||||
c.restclient,
|
c.restclient,
|
||||||
podName,
|
podName,
|
||||||
c.Namespace,
|
c.Namespace,
|
||||||
port,
|
portPair,
|
||||||
readyChan,
|
readyChan,
|
||||||
childCtx.Done(),
|
childCtx.Done(),
|
||||||
)
|
)
|
||||||
@@ -232,7 +236,7 @@ func (c *ConnectOptions) portForward(ctx context.Context, port string) error {
|
|||||||
}
|
}
|
||||||
if strings.Contains(err.Error(), "unable to listen on any of the requested ports") ||
|
if strings.Contains(err.Error(), "unable to listen on any of the requested ports") ||
|
||||||
strings.Contains(err.Error(), "address already in use") {
|
strings.Contains(err.Error(), "address already in use") {
|
||||||
log.Errorf("port %s already in use, needs to release it manually", port)
|
log.Errorf("port %s already in use, needs to release it manually", portPair)
|
||||||
time.Sleep(time.Second * 5)
|
time.Sleep(time.Second * 5)
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("port-forward occurs error, err: %v, retrying", err)
|
log.Debugf("port-forward occurs error, err: %v, retrying", err)
|
||||||
@@ -247,7 +251,7 @@ func (c *ConnectOptions) portForward(ctx context.Context, port string) error {
|
|||||||
case err := <-errChan:
|
case err := <-errChan:
|
||||||
return err
|
return err
|
||||||
case <-readyChan:
|
case <-readyChan:
|
||||||
log.Info("port forward ready")
|
log.Infof("port forward %s ready", portPair)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -576,7 +580,7 @@ func Run(ctx context.Context, servers []core.Server) error {
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return nil
|
return ctx.Err()
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ func getBastion(name string) *SshConfig {
|
|||||||
config.Keyfile = value
|
config.Keyfile = value
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
config.Addr = fmt.Sprintf("%s:%s", host, port)
|
config.Addr = net.JoinHostPort(host, port)
|
||||||
return &config
|
return &config
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ func WaitPod(podInterface v12.PodInterface, list metav1.ListOptions, checker fun
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func PortForwardPod(config *rest.Config, clientset *rest.RESTClient, podName, namespace, port string, readyChan chan struct{}, stopChan <-chan struct{}) error {
|
func PortForwardPod(config *rest.Config, clientset *rest.RESTClient, podName, namespace, portPair string, readyChan chan struct{}, stopChan <-chan struct{}) error {
|
||||||
url := clientset.
|
url := clientset.
|
||||||
Post().
|
Post().
|
||||||
Resource("pods").
|
Resource("pods").
|
||||||
@@ -116,7 +116,7 @@ func PortForwardPod(config *rest.Config, clientset *rest.RESTClient, podName, na
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
dialer := spdy.NewDialer(upgrader, &http.Client{Transport: transport}, "POST", url)
|
dialer := spdy.NewDialer(upgrader, &http.Client{Transport: transport}, "POST", url)
|
||||||
p := []string{port}
|
p := []string{portPair}
|
||||||
forwarder, err := portforward.NewOnAddresses(dialer, []string{"0.0.0.0"}, p, stopChan, readyChan, nil, os.Stderr)
|
forwarder, err := portforward.NewOnAddresses(dialer, []string{"0.0.0.0"}, p, stopChan, readyChan, nil, os.Stderr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error(err)
|
log.Error(err)
|
||||||
|
|||||||
Reference in New Issue
Block a user