feat: support reload

This commit is contained in:
mzz2017
2023-02-27 13:29:42 +08:00
parent 8b59492fe5
commit 01162f3d7e
10 changed files with 270 additions and 107 deletions

View File

@ -2,6 +2,7 @@ package cmd
import (
"fmt"
"github.com/mohae/deepcopy"
"github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/v2rayA/dae/cmd/internal"
@ -55,6 +56,66 @@ func init() {
func Run(log *logrus.Logger, conf *config.Config) (err error) {
// New ControlPlane.
c, err := newControlPlane(log, nil, conf)
if err != nil {
return err
}
// Serve tproxy TCP/UDP server util signals.
var listener *control.Listener
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGKILL, syscall.SIGILL, syscall.SIGUSR1)
go func() {
if listener, err = c.ListenAndServe(conf.Global.TproxyPort); err != nil {
log.Errorln("ListenAndServe:", err)
}
sigs <- nil
}()
reloading := false
loop:
for sig := range sigs {
switch sig {
case nil:
if reloading {
reloading = false
log.Warnln("[Reload] Serve")
go func() {
if err := c.Serve(listener); err != nil {
log.Errorln("ListenAndServe:", err)
}
sigs <- nil
}()
} else {
break loop
}
case syscall.SIGUSR1:
// Reload signal.
log.Warnln("[Reload] Received reload signal; prepare to reload")
obj := c.EjectBpf()
log.Warnln("[Reload] Load new control plane")
newC, err := newControlPlane(log, obj, conf)
if err != nil {
log.WithFields(logrus.Fields{
"err": err,
}).Errorln("failed to reload")
continue
}
log.Warnln("[Reload] Stopped old control plane")
c.Close()
c = newC
reloading = true
default:
break loop
}
}
if e := c.Close(); e != nil {
return fmt.Errorf("close control plane: %w", e)
}
return nil
}
func newControlPlane(log *logrus.Logger, bpf interface{}, conf *config.Config) (c *control.ControlPlane, err error) {
/// Get tag -> nodeList mapping.
tagToNodeList := map[string][]string{}
if len(conf.Node) > 0 {
@ -73,16 +134,18 @@ func Run(log *logrus.Logger, conf *config.Config) (err error) {
}
}
if len(tagToNodeList) == 0 {
return fmt.Errorf("no node found, which could because all subscription resolving failed")
return nil, fmt.Errorf("no node found, which could because all subscription resolving failed")
}
if len(conf.Global.LanInterface) == 0 && len(conf.Global.WanInterface) == 0 {
return fmt.Errorf("LanInterface and WanInterface cannot both be empty")
return nil, fmt.Errorf("LanInterface and WanInterface cannot both be empty")
}
// New ControlPlane.
t, err := control.NewControlPlane(
// Deep copy a conf to avoid modification.
conf = deepcopy.Copy(conf).(*config.Config)
c, err = control.NewControlPlane(
log,
bpf,
tagToNodeList,
conf.Group,
&conf.Routing,
@ -90,26 +153,13 @@ func Run(log *logrus.Logger, conf *config.Config) (err error) {
&conf.Dns,
)
if err != nil {
return err
return nil, err
}
// Call GC to release memory.
runtime.GC()
// Serve tproxy TCP/UDP server util signals.
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGQUIT, syscall.SIGKILL, syscall.SIGILL)
go func() {
if err := t.ListenAndServe(conf.Global.TproxyPort); err != nil {
log.Errorln("ListenAndServe:", err)
sigs <- nil
}
}()
<-sigs
if e := t.Close(); e != nil {
return fmt.Errorf("close control plane: %w", e)
}
return nil
return c, nil
}
func readConfig(cfgFile string) (conf *config.Config, includes []string, err error) {

View File

@ -15,6 +15,11 @@ import (
"time"
)
const (
Init = 1 + iota
NotAlive
)
type minLatency struct {
latency time.Duration
dialer *Dialer
@ -66,7 +71,7 @@ func NewAliveDialerSet(
},
}
for _, d := range dialers {
a.dialerToIndex[d] = -1
a.dialerToIndex[d] = -Init
}
for _, d := range dialers {
a.NotifyLatencyChange(d, setAlive)
@ -131,10 +136,13 @@ func (a *AliveDialerSet) NotifyLatencyChange(dialer *Dialer, alive bool) {
// This dialer is already alive.
} else {
// Dialer: not alive -> alive.
if index == -NotAlive {
a.log.WithFields(logrus.Fields{
"dialer": dialer.Name(),
"group": a.dialerGroupName,
"network": a.CheckTyp.StringWithoutDns(),
}).Infoln("NOT ALIVE -> ALIVE:")
}
a.dialerToIndex[dialer] = len(a.inorderedAliveDialerSet)
a.inorderedAliveDialerSet = append(a.inorderedAliveDialerSet, dialer)
}
@ -144,13 +152,14 @@ func (a *AliveDialerSet) NotifyLatencyChange(dialer *Dialer, alive bool) {
// Dialer: alive -> not alive.
a.log.WithFields(logrus.Fields{
"dialer": dialer.Name(),
"group": a.dialerGroupName,
"network": a.CheckTyp.StringWithoutDns(),
}).Infoln("ALIVE -> NOT ALIVE:")
// Remove the dialer from inorderedAliveDialerSet.
if index >= len(a.inorderedAliveDialerSet) {
a.log.Panicf("index:%v >= len(a.inorderedAliveDialerSet):%v", index, len(a.inorderedAliveDialerSet))
}
a.dialerToIndex[dialer] = -1
a.dialerToIndex[dialer] = -NotAlive
if index < len(a.inorderedAliveDialerSet)-1 {
// Swap this element with the last element.
dialerToSwap := a.inorderedAliveDialerSet[len(a.inorderedAliveDialerSet)-1]

View File

@ -136,3 +136,13 @@ func (s *DialerSet) Filter(filters []*config_parser.Function) (dialers []*dialer
}
return dialers, nil
}
func (s *DialerSet) Close() error {
var err error
for _, d := range s.dialers {
if e := d.Close(); e != nil {
err = e
}
}
return err
}

View File

@ -35,7 +35,7 @@ var SectionDescription = map[string]Desc{
}
var GlobalDesc = Desc{
"tproxy_port": "tproxy port to listen at. It is NOT a HTTP/SOCKS port, and is just used by eBPF program.\nIn normal case, you do not need to use it.",
"tproxy_port": "tproxy port to listen on. It is NOT a HTTP/SOCKS port, and is just used by eBPF program.\nIn normal case, you do not need to use it.",
"log_level": "Log level: error, warn, info, debug, trace.",
"tcp_check_url": "Node connectivity check.\nHost of URL should have both IPv4 and IPv6 if you have double stack in local.\nConsidering traffic consumption, it is recommended to choose a site with anycast IP and less response.",
"udp_check_dns": "This DNS will be used to check UDP connectivity of nodes. And if dns_upstream below contains tcp, it also be used to check TCP DNS connectivity of nodes.\nThis DNS should have both IPv4 and IPv6 if you have double stack in local.",

View File

@ -23,7 +23,7 @@ func FormatL4Proto(l4proto uint8) string {
return strconv.Itoa(int(l4proto))
}
func (c *ControlPlaneCore) OutboundAliveChangeCallback(outbound uint8) func(alive bool, networkType *dialer.NetworkType) {
func (c *controlPlaneCore) OutboundAliveChangeCallback(outbound uint8) func(alive bool, networkType *dialer.NetworkType) {
return func(alive bool, networkType *dialer.NetworkType) {
c.log.WithFields(logrus.Fields{
"alive": alive,

View File

@ -38,7 +38,7 @@ import (
type ControlPlane struct {
log *logrus.Logger
core *ControlPlaneCore
core *controlPlaneCore
deferFuncs []func() error
listenIp string
@ -55,6 +55,7 @@ type ControlPlane struct {
func NewControlPlane(
log *logrus.Logger,
_bpf interface{},
tagToNodeList map[string][]string,
groups []config.Group,
routingA *config.Routing,
@ -88,6 +89,8 @@ func NewControlPlane(
consts.BasicFeatureVersion.String())
}
var deferFuncs []func() error
/// Allow the current process to lock memory for eBPF resources.
if err = rlimit.RemoveMemlock(); err != nil {
return nil, fmt.Errorf("rlimit.RemoveMemlock:%v", err)
@ -102,7 +105,7 @@ func NewControlPlane(
/// Load pre-compiled programs and maps into the kernel.
log.Infof("Loading eBPF programs and maps into the kernel")
var bpf bpfObjects
//var bpf bpfObjects
var ProgramOptions = ebpf.ProgramOptions{
KernelTypes: nil,
}
@ -116,7 +119,16 @@ func NewControlPlane(
},
Programs: ProgramOptions,
}
if err = fullLoadBpfObjects(log, &bpf, &loadBpfOptions{
var bpf *bpfObjects
if _bpf != nil {
if _bpf, ok := _bpf.(*bpfObjects); ok {
bpf = _bpf
} else {
return nil, fmt.Errorf("unexpected bpf type: %T", _bpf)
}
} else {
bpf = new(bpfObjects)
if err = fullLoadBpfObjects(log, bpf, &loadBpfOptions{
PinPath: pinPath,
CollectionOptions: collectionOpts,
BindLan: len(global.LanInterface) > 0,
@ -127,13 +139,17 @@ func NewControlPlane(
}
return nil, fmt.Errorf("load eBPF objects: %w", err)
}
core := &ControlPlaneCore{
log: log,
deferFuncs: []func() error{bpf.Close},
bpf: &bpf,
kernelVersion: &kernelVersion,
}
// outboundId2Name can be modified later.
outboundId2Name := make(map[uint8]string)
core := newControlPlaneCore(
log,
bpf,
outboundId2Name,
&kernelVersion,
_bpf != nil,
)
defer func() {
if err != nil {
_ = core.Close()
@ -141,16 +157,7 @@ func NewControlPlane(
}()
// Write params.
var lanNatDirect uint32
if global.LanNatDirect {
lanNatDirect = 1
} else {
lanNatDirect = 0
}
if err = bpf.ParamMap.Update(consts.ControlPlaneNatDirectKey, lanNatDirect, ebpf.UpdateAny); err != nil {
return nil, err
}
if err = bpf.ParamMap.Update(consts.ControlPlanePidKey, uint32(os.Getpid()), ebpf.UpdateAny); err != nil {
if err = core.bpf.ParamMap.Update(consts.ControlPlanePidKey, uint32(os.Getpid()), ebpf.UpdateAny); err != nil {
return nil, err
}
@ -212,6 +219,7 @@ func NewControlPlane(
// Filter out groups.
dialerSet := outbound.NewDialerSetFromLinks(option, tagToNodeList)
deferFuncs = append(deferFuncs, dialerSet.Close)
for _, group := range groups {
// Parse policy.
policy, err := outbound.NewDialerSelectionPolicyFromGroupParam(&group)
@ -244,7 +252,6 @@ func NewControlPlane(
return nil, fmt.Errorf("too many outbounds")
}
outboundName2Id := make(map[string]uint8)
outboundId2Name := make(map[uint8]string)
for i, o := range outbounds {
if _, exist := outboundName2Id[o.Name]; exist {
return nil, fmt.Errorf("duplicated outbound name: %v", o.Name)
@ -252,7 +259,6 @@ func NewControlPlane(
outboundName2Id[o.Name] = uint8(i)
outboundId2Name[uint8(i)] = o.Name
}
core.outboundId2Name = outboundId2Name
// Apply rules optimizers.
var rules []*config_parser.RoutingRule
if rules, err = routing.ApplyRulesOptimizers(routingA.Rules,
@ -272,7 +278,7 @@ func NewControlPlane(
log.Debugf("RoutingA:\n%vfallback: %v\n", debugBuilder.String(), routingA.Fallback)
}
// Parse rules and build.
builder, err := NewRoutingMatcherBuilder(log, rules, outboundName2Id, &bpf, routingA.Fallback)
builder, err := NewRoutingMatcherBuilder(log, rules, outboundName2Id, core.bpf, routingA.Fallback)
if err != nil {
return nil, fmt.Errorf("NewRoutingMatcherBuilder: %w", err)
}
@ -293,7 +299,7 @@ func NewControlPlane(
c = &ControlPlane{
log: log,
core: core,
deferFuncs: nil,
deferFuncs: deferFuncs,
listenIp: "0.0.0.0",
outbounds: outbounds,
dialMode: dialMode,
@ -332,6 +338,11 @@ func NewControlPlane(
return c, nil
}
// EjectBpf will resect bpf from destroying life-cycle of control plane.
func (c *ControlPlane) EjectBpf() *bpfObjects {
return c.core.EjectBpf()
}
func (c *ControlPlane) dnsUpstreamReadyCallback(raw *url.URL, dnsUpstream *dns.Upstream) (err error) {
/// Notify dialers to check.
c.onceNetworkReady.Do(func() {
@ -424,7 +435,17 @@ func (c *ControlPlane) ChooseDialTarget(outbound consts.OutboundIndex, dst netip
case consts.DialMode_Ip:
dialTarget = dst.String()
case consts.DialMode_Domain:
if _, err := netip.ParseAddr(domain); err == nil {
// domain is IPv4 or IPv6 (has colon)
dialTarget = net.JoinHostPort(domain, strconv.Itoa(int(dst.Port())))
} else if _, _, err := net.SplitHostPort(domain); err == nil {
// domain is already domain:port
dialTarget = domain
} else {
dialTarget = net.JoinHostPort(domain, strconv.Itoa(int(dst.Port())))
}
c.log.WithFields(logrus.Fields{
"from": dst.String(),
"to": dialTarget,
@ -433,29 +454,33 @@ func (c *ControlPlane) ChooseDialTarget(outbound consts.OutboundIndex, dst netip
return dialTarget, dialMode
}
func (c *ControlPlane) ListenAndServe(port uint16) (err error) {
// Listen.
var listenConfig = net.ListenConfig{
Control: func(network, address string, c syscall.RawConn) error {
return dialer.TproxyControl(c)
},
}
listenAddr := net.JoinHostPort(c.listenIp, strconv.Itoa(int(port)))
tcpListener, err := listenConfig.Listen(context.TODO(), "tcp", listenAddr)
if err != nil {
return fmt.Errorf("listenTCP: %w", err)
}
defer tcpListener.Close()
packetConn, err := listenConfig.ListenPacket(context.TODO(), "udp", listenAddr)
if err != nil {
return fmt.Errorf("listenUDP: %w", err)
}
defer packetConn.Close()
udpConn := packetConn.(*net.UDPConn)
type Listener struct {
tcpListener net.Listener
packetConn net.PacketConn
port uint16
}
func (l *Listener) Close() error {
var (
err error
err2 error
)
if err, err2 = l.tcpListener.Close(), l.packetConn.Close(); err2 != nil {
if err == nil {
err = err2
} else {
err = fmt.Errorf("%w: %v", err, err2)
}
}
return err
}
func (c *ControlPlane) Serve(listener *Listener) (err error) {
udpConn := listener.packetConn.(*net.UDPConn)
/// Serve.
// TCP socket.
tcpFile, err := tcpListener.(*net.TCPListener).File()
tcpFile, err := listener.tcpListener.(*net.TCPListener).File()
if err != nil {
return fmt.Errorf("failed to retrieve copy of the underlying TCP connection file")
}
@ -477,7 +502,7 @@ func (c *ControlPlane) ListenAndServe(port uint16) (err error) {
return err
}
// Port.
if err := c.core.bpf.ParamMap.Update(consts.BigEndianTproxyPortKey, uint32(common.Htons(port)), ebpf.UpdateAny); err != nil {
if err := c.core.bpf.ParamMap.Update(consts.BigEndianTproxyPortKey, uint32(common.Htons(listener.port)), ebpf.UpdateAny); err != nil {
return err
}
@ -489,23 +514,33 @@ func (c *ControlPlane) ListenAndServe(port uint16) (err error) {
go func() {
defer cancel()
for {
lconn, err := tcpListener.Accept()
select {
case <-ctx.Done():
return
default:
}
lconn, err := listener.tcpListener.Accept()
if err != nil {
if !strings.Contains(err.Error(), "use of closed network connection") {
c.log.Errorf("Error when accept: %v", err)
}
break
}
go func() {
go func(lconn net.Conn) {
if err := c.handleConn(lconn); err != nil {
c.log.Warnln("handleConn:", err)
}
}()
}(lconn)
}
}()
go func() {
defer cancel()
for {
select {
case <-ctx.Done():
return
default:
}
var buf [65535]byte
var oob [120]byte // Size for original dest
n, oobn, _, src, err := udpConn.ReadMsgUDPAddrPort(buf[:], oob[:])
@ -551,6 +586,42 @@ func (c *ControlPlane) ListenAndServe(port uint16) (err error) {
return nil
}
func (c *ControlPlane) ListenAndServe(port uint16) (listener *Listener, err error) {
// Listen.
var listenConfig = net.ListenConfig{
Control: func(network, address string, c syscall.RawConn) error {
return dialer.TproxyControl(c)
},
}
listenAddr := net.JoinHostPort(c.listenIp, strconv.Itoa(int(port)))
tcpListener, err := listenConfig.Listen(context.TODO(), "tcp", listenAddr)
if err != nil {
return nil, fmt.Errorf("listenTCP: %w", err)
}
packetConn, err := listenConfig.ListenPacket(context.TODO(), "udp", listenAddr)
if err != nil {
_ = tcpListener.Close()
return nil, fmt.Errorf("listenUDP: %w", err)
}
listener = &Listener{
tcpListener: tcpListener,
packetConn: packetConn,
port: port,
}
defer func() {
if err != nil {
_ = listener.Close()
}
}()
// Serve
if err = c.Serve(listener); err != nil {
return nil, fmt.Errorf("failed to serve: %w", err)
}
return listener, nil
}
func (c *ControlPlane) chooseBestDnsDialer(
req *udpRequest,
dnsUpstream *dns.Upstream,

View File

@ -23,16 +23,39 @@ import (
"regexp"
)
type ControlPlaneCore struct {
var coreFlip = 0
type controlPlaneCore struct {
log *logrus.Logger
deferFuncs []func() error
bpf *bpfObjects
outboundId2Name map[uint8]string
kernelVersion *internal.Version
flip int
}
func (c *ControlPlaneCore) Close() (err error) {
func newControlPlaneCore(log *logrus.Logger,
bpf *bpfObjects,
outboundId2Name map[uint8]string,
kernelVersion *internal.Version,
isReload bool,
) *controlPlaneCore {
if isReload {
coreFlip = ((coreFlip & 1) ^ 1) & 1
}
return &controlPlaneCore{
log: log,
deferFuncs: []func() error{bpf.Close},
bpf: bpf,
outboundId2Name: outboundId2Name,
kernelVersion: kernelVersion,
flip: coreFlip,
}
}
func (c *controlPlaneCore) Close() (err error) {
// Invoke defer funcs in reverse order.
for i := len(c.deferFuncs) - 1; i >= 0; i-- {
if e := c.deferFuncs[i](); e != nil {
@ -79,7 +102,7 @@ func getIfParamsFromLink(link netlink.Link) (ifParams bpfIfParams, err error) {
return ifParams, nil
}
func (c *ControlPlaneCore) addQdisc(ifname string) error {
func (c *controlPlaneCore) addQdisc(ifname string) error {
link, err := netlink.LinkByName(ifname)
if err != nil {
return err
@ -98,7 +121,7 @@ func (c *ControlPlaneCore) addQdisc(ifname string) error {
return nil
}
func (c *ControlPlaneCore) delQdisc(ifname string) error {
func (c *controlPlaneCore) delQdisc(ifname string) error {
link, err := netlink.LinkByName(ifname)
if err != nil {
return err
@ -119,9 +142,9 @@ func (c *ControlPlaneCore) delQdisc(ifname string) error {
return nil
}
func (c *ControlPlaneCore) setupRoutingPolicy() (err error) {
func (c *controlPlaneCore) setupRoutingPolicy() (err error) {
/// Insert ip rule / ip route.
const table = 2023
var table = 2023 + c.flip
/** ip table
ip route add local default dev lo table 2023
@ -229,7 +252,7 @@ tryRuleAddAgain:
return nil
}
func (c *ControlPlaneCore) bindLan(ifname string) error {
func (c *controlPlaneCore) bindLan(ifname string) error {
c.log.Infof("Bind to LAN: %v", ifname)
link, err := netlink.LinkByName(ifname)
@ -259,7 +282,7 @@ func (c *ControlPlaneCore) bindLan(ifname string) error {
FilterAttrs: netlink.FilterAttrs{
LinkIndex: link.Attrs().Index,
Parent: netlink.HANDLE_MIN_INGRESS,
Handle: netlink.MakeHandle(0x2023, 2),
Handle: netlink.MakeHandle(0x2023, 0b100+uint16(c.flip)),
Protocol: unix.ETH_P_ALL,
// Priority should be behind of WAN's
Priority: 2,
@ -285,7 +308,7 @@ func (c *ControlPlaneCore) bindLan(ifname string) error {
FilterAttrs: netlink.FilterAttrs{
LinkIndex: link.Attrs().Index,
Parent: netlink.HANDLE_MIN_EGRESS,
Handle: netlink.MakeHandle(0x2023, 1),
Handle: netlink.MakeHandle(0x2023, 0b010+uint16(c.flip)),
Protocol: unix.ETH_P_ALL,
// Priority should be front of WAN's
Priority: 1,
@ -308,7 +331,7 @@ func (c *ControlPlaneCore) bindLan(ifname string) error {
return nil
}
func (c *ControlPlaneCore) setupSkPidMonitor() error {
func (c *controlPlaneCore) setupSkPidMonitor() error {
/// Set-up SrcPidMapper.
/// Attach programs to support pname routing.
// Get the first-mounted cgroupv2 path.
@ -348,7 +371,7 @@ func (c *ControlPlaneCore) setupSkPidMonitor() error {
}
return nil
}
func (c *ControlPlaneCore) bindWan(ifname string) error {
func (c *controlPlaneCore) bindWan(ifname string) error {
c.log.Infof("Bind to WAN: %v", ifname)
link, err := netlink.LinkByName(ifname)
if err != nil {
@ -375,7 +398,7 @@ func (c *ControlPlaneCore) bindWan(ifname string) error {
FilterAttrs: netlink.FilterAttrs{
LinkIndex: link.Attrs().Index,
Parent: netlink.HANDLE_MIN_EGRESS,
Handle: netlink.MakeHandle(0x2023, 2),
Handle: netlink.MakeHandle(0x2023, 0b100+uint16(c.flip)),
Protocol: unix.ETH_P_ALL,
Priority: 2,
},
@ -399,7 +422,7 @@ func (c *ControlPlaneCore) bindWan(ifname string) error {
FilterAttrs: netlink.FilterAttrs{
LinkIndex: link.Attrs().Index,
Parent: netlink.HANDLE_MIN_INGRESS,
Handle: netlink.MakeHandle(0x2023, 1),
Handle: netlink.MakeHandle(0x2023, 0b010+uint16(c.flip)),
Protocol: unix.ETH_P_ALL,
Priority: 1,
},
@ -423,7 +446,7 @@ func (c *ControlPlaneCore) bindWan(ifname string) error {
// BatchUpdateDomainRouting update bpf map domain_routing. Since one IP may have multiple domains, this function should
// be invoked every A/AAAA-record lookup.
func (c *ControlPlaneCore) BatchUpdateDomainRouting(cache *DnsCache) error {
func (c *controlPlaneCore) BatchUpdateDomainRouting(cache *DnsCache) error {
// Parse ips from DNS resp answers.
var ips []netip.Addr
for _, ans := range cache.Answers {
@ -459,3 +482,9 @@ func (c *ControlPlaneCore) BatchUpdateDomainRouting(cache *DnsCache) error {
}
return nil
}
// EjectBpf will resect bpf from destroying life-cycle of control plane core.
func (c *controlPlaneCore) EjectBpf() *bpfObjects {
c.deferFuncs = c.deferFuncs[1:]
return c.bpf
}

View File

@ -89,7 +89,8 @@ static const __u32 disable_l4_tx_checksum_key
static const __u32 disable_l4_rx_checksum_key
__attribute__((unused, deprecated)) = 3;
static const __u32 control_plane_pid_key = 4;
static const __u32 control_plane_nat_direct_key = 5;
static const __u32 control_plane_nat_direct_key
__attribute__((unused, deprecated)) = 5;
static const __u32 control_plane_dns_routing_key = 6;
// Outbound Connectivity Map:
@ -1358,13 +1359,6 @@ new_connection:
#endif
if (routing_result.outbound == OUTBOUND_DIRECT ||
routing_result.outbound == OUTBOUND_MUST_DIRECT) {
__u32 *nat;
if ((nat =
bpf_map_lookup_elem(&param_map, &control_plane_nat_direct_key)) &&
*nat) {
// Do not mark if packet is sent to control_plane.
goto control_plane_tproxy;
}
skb->mark = routing_result.mark;
goto direct;
} else if (unlikely(routing_result.outbound == OUTBOUND_BLOCK)) {

View File

@ -45,7 +45,7 @@ func (c *ControlPlane) Route(src, dst netip.AddrPort, domain string, l4proto con
return outboundIndex, mark, nil
}
func (c *ControlPlaneCore) RetrieveRoutingResult(src, dst netip.AddrPort, l4proto uint8) (result *bpfRoutingResult, err error) {
func (c *controlPlaneCore) RetrieveRoutingResult(src, dst netip.AddrPort, l4proto uint8) (result *bpfRoutingResult, err error) {
srcIp6 := src.Addr().As16()
dstIp6 := dst.Addr().As16()

View File

@ -1,5 +1,5 @@
global {
# tproxy port to listen at. It is NOT a HTTP/SOCKS port, and is just used by eBPF program.
# tproxy port to listen on. It is NOT a HTTP/SOCKS port, and is just used by eBPF program.
# In normal case, you do not need to use it.
tproxy_port: 12345