Files
kubevpn/pkg/core/route.go
2025-04-19 19:14:39 +08:00

131 lines
3.5 KiB
Go

package core
import (
"context"
"fmt"
"net"
"strings"
"sync"
"github.com/containernetworking/cni/pkg/types"
"github.com/pkg/errors"
plog "github.com/wencaiwulue/kubevpn/v2/pkg/log"
"github.com/wencaiwulue/kubevpn/v2/pkg/tun"
)
var (
// RouteMapTCP map[srcIP]net.Conn Globe route table for inner ip
RouteMapTCP = &sync.Map{}
// TCPPacketChan tcp connects
TCPPacketChan = make(chan *Packet, MaxSize)
)
type TCPUDPacket struct {
data *DatagramPacket
}
// Route example:
// -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:/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 {
Listeners []string // -l tun
Forwarder string // -f tcp
Retries int
}
func (r *Route) ParseForwarder() (*Forwarder, error) {
forwarder, err := ParseNode(r.Forwarder)
if err != nil {
return nil, err
}
forwarder.Client = &Client{
Connector: NewUDPOverTCPConnector(),
Transporter: TCPTransporter(nil),
}
return NewForwarder(r.Retries, forwarder), nil
}
func (r *Route) GenerateServers() ([]Server, error) {
forwarder, err := r.ParseForwarder()
if err != nil && !errors.Is(err, ErrorInvalidNode) {
plog.G(context.Background()).Errorf("Failed to parse forwarder: %v", err)
return nil, err
}
servers := make([]Server, 0, len(r.Listeners))
for _, l := range r.Listeners {
var node *Node
node, err = ParseNode(l)
if err != nil {
plog.G(context.Background()).Errorf("Failed to parse node %s: %v", l, err)
return nil, err
}
var listener net.Listener
var handler Handler
switch node.Protocol {
case "tun":
handler = TunHandler(forwarder, node)
listener, err = tun.Listener(tun.Config{
Name: node.Get("name"),
Addr: node.Get("net"),
Addr6: node.Get("net6"),
MTU: node.GetInt("mtu"),
Routes: parseRoutes(node.Get("route")),
Gateway: node.Get("gw"),
})
if err != nil {
plog.G(context.Background()).Errorf("Failed to create tun listener: %v", err)
return nil, err
}
case "tcp":
handler = TCPHandler()
listener, err = TCPListener(node.Addr)
if err != nil {
plog.G(context.Background()).Errorf("Failed to create tcp listener: %v", err)
return nil, err
}
case "gtcp":
handler = GvisorTCPHandler()
listener, err = GvisorTCPListener(node.Addr)
if err != nil {
plog.G(context.Background()).Errorf("Failed to create gvisor tcp listener: %v", err)
return nil, err
}
case "gudp":
handler = GvisorUDPHandler()
listener, err = GvisorUDPListener(node.Addr)
if err != nil {
plog.G(context.Background()).Errorf("Failed to create gvisor udp listener: %v", err)
return nil, err
}
case "ssh":
handler = SSHHandler()
listener, err = SSHListener(node.Addr)
if err != nil {
plog.G(context.Background()).Errorf("Failed to create ssh listener: %v", err)
return nil, err
}
default:
plog.G(context.Background()).Errorf("Not support protocol %s", node.Protocol)
return nil, fmt.Errorf("not support protocol %s", node.Protocol)
}
servers = append(servers, Server{Listener: listener, Handler: handler})
}
return servers, nil
}
func parseRoutes(str string) []types.Route {
var routes []types.Route
list := strings.Split(str, ",")
for _, route := range list {
if _, ipNet, _ := net.ParseCIDR(strings.TrimSpace(route)); ipNet != nil {
routes = append(routes, types.Route{Dst: *ipNet})
}
}
return routes
}