mirror of
https://github.com/daeuniverse/dae.git
synced 2025-07-22 22:01:00 +07:00
optimize(memory): reuse kernel lpm tries in userspace
This commit is contained in:
@ -26,6 +26,7 @@ import (
|
|||||||
"net/netip"
|
"net/netip"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -322,6 +323,9 @@ func NewControlPlane(
|
|||||||
c.dnsUpstream.FinishInitCallback = c.finishInitDnsUpstreamResolve
|
c.dnsUpstream.FinishInitCallback = c.finishInitDnsUpstreamResolve
|
||||||
// Try to invoke once to avoid dns leaking at the very beginning.
|
// Try to invoke once to avoid dns leaking at the very beginning.
|
||||||
_, _ = c.dnsUpstream.GetUpstream()
|
_, _ = c.dnsUpstream.GetUpstream()
|
||||||
|
|
||||||
|
// Call GC to release memory.
|
||||||
|
runtime.GC()
|
||||||
return c, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,7 +8,6 @@ package control
|
|||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Asphaltt/lpmtrie"
|
|
||||||
"github.com/cilium/ebpf"
|
"github.com/cilium/ebpf"
|
||||||
"github.com/v2rayA/dae/common"
|
"github.com/v2rayA/dae/common"
|
||||||
"github.com/v2rayA/dae/common/consts"
|
"github.com/v2rayA/dae/common/consts"
|
||||||
@ -26,7 +25,6 @@ type RoutingMatcherBuilder struct {
|
|||||||
rules []bpfMatchSet
|
rules []bpfMatchSet
|
||||||
simulatedLpmTries [][]netip.Prefix
|
simulatedLpmTries [][]netip.Prefix
|
||||||
simulatedDomainSet []routing.DomainSet
|
simulatedDomainSet []routing.DomainSet
|
||||||
Fallback string
|
|
||||||
|
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
@ -215,7 +213,6 @@ func (b *RoutingMatcherBuilder) AddFallback(outbound string) {
|
|||||||
if b.err != nil {
|
if b.err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
b.Fallback = outbound
|
|
||||||
b.rules = append(b.rules, bpfMatchSet{
|
b.rules = append(b.rules, bpfMatchSet{
|
||||||
Type: uint8(consts.MatchType_Fallback),
|
Type: uint8(consts.MatchType_Fallback),
|
||||||
Outbound: b.OutboundToId(outbound),
|
Outbound: b.OutboundToId(outbound),
|
||||||
@ -266,18 +263,6 @@ func (b *RoutingMatcherBuilder) BuildUserspace() (matcher *RoutingMatcher, err e
|
|||||||
return nil, b.err
|
return nil, b.err
|
||||||
}
|
}
|
||||||
var m RoutingMatcher
|
var m RoutingMatcher
|
||||||
// Update lpms.
|
|
||||||
m.lpms = make([]lpmtrie.LpmTrie, len(b.simulatedLpmTries))
|
|
||||||
for i, cidrs := range b.simulatedLpmTries {
|
|
||||||
lpm, err := lpmtrie.New(128)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
for _, cidr := range cidrs {
|
|
||||||
lpm.Update(cidrToLpmTrieKey(cidr), 1)
|
|
||||||
}
|
|
||||||
m.lpms[i] = lpm
|
|
||||||
}
|
|
||||||
// Build domainMatcher
|
// Build domainMatcher
|
||||||
m.domainMatcher = domain_matcher.NewAhocorasickSlimtrie(consts.MaxMatchSetLen)
|
m.domainMatcher = domain_matcher.NewAhocorasickSlimtrie(consts.MaxMatchSetLen)
|
||||||
for _, domains := range b.simulatedDomainSet {
|
for _, domains := range b.simulatedDomainSet {
|
||||||
|
@ -9,6 +9,8 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Asphaltt/lpmtrie"
|
"github.com/Asphaltt/lpmtrie"
|
||||||
|
"github.com/cilium/ebpf"
|
||||||
|
"github.com/v2rayA/dae/common"
|
||||||
"github.com/v2rayA/dae/common/consts"
|
"github.com/v2rayA/dae/common/consts"
|
||||||
"github.com/v2rayA/dae/component/routing"
|
"github.com/v2rayA/dae/component/routing"
|
||||||
"net"
|
"net"
|
||||||
@ -16,7 +18,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type RoutingMatcher struct {
|
type RoutingMatcher struct {
|
||||||
lpms []lpmtrie.LpmTrie
|
lpmArrayMap *ebpf.Map
|
||||||
domainMatcher routing.DomainMatcher // All domain matchSets use one DomainMatcher.
|
domainMatcher routing.DomainMatcher // All domain matchSets use one DomainMatcher.
|
||||||
|
|
||||||
matches []bpfMatchSet
|
matches []bpfMatchSet
|
||||||
@ -37,18 +39,18 @@ func (m *RoutingMatcher) Match(
|
|||||||
if len(sourceAddr) != net.IPv6len || len(destAddr) != net.IPv6len || len(mac) != net.IPv6len {
|
if len(sourceAddr) != net.IPv6len || len(destAddr) != net.IPv6len || len(mac) != net.IPv6len {
|
||||||
return 0, fmt.Errorf("bad address length")
|
return 0, fmt.Errorf("bad address length")
|
||||||
}
|
}
|
||||||
lpmKeys := make([]*lpmtrie.Key, consts.MatchType_Mac+1)
|
lpmKeys := make([]*_bpfLpmKey, consts.MatchType_Mac+1)
|
||||||
lpmKeys[consts.MatchType_IpSet] = &lpmtrie.Key{
|
lpmKeys[consts.MatchType_IpSet] = &_bpfLpmKey{
|
||||||
PrefixLen: 128,
|
PrefixLen: 128,
|
||||||
Data: destAddr,
|
Data: common.Ipv6ByteSliceToUint32Array(destAddr),
|
||||||
}
|
}
|
||||||
lpmKeys[consts.MatchType_SourceIpSet] = &lpmtrie.Key{
|
lpmKeys[consts.MatchType_SourceIpSet] = &_bpfLpmKey{
|
||||||
PrefixLen: 128,
|
PrefixLen: 128,
|
||||||
Data: sourceAddr,
|
Data: common.Ipv6ByteSliceToUint32Array(sourceAddr),
|
||||||
}
|
}
|
||||||
lpmKeys[consts.MatchType_Mac] = &lpmtrie.Key{
|
lpmKeys[consts.MatchType_Mac] = &_bpfLpmKey{
|
||||||
PrefixLen: 128,
|
PrefixLen: 128,
|
||||||
Data: mac,
|
Data: common.Ipv6ByteSliceToUint32Array(mac),
|
||||||
}
|
}
|
||||||
var domainMatchBitmap []uint32
|
var domainMatchBitmap []uint32
|
||||||
if domain != "" {
|
if domain != "" {
|
||||||
@ -63,11 +65,18 @@ func (m *RoutingMatcher) Match(
|
|||||||
}
|
}
|
||||||
switch consts.MatchType(match.Type) {
|
switch consts.MatchType(match.Type) {
|
||||||
case consts.MatchType_IpSet, consts.MatchType_SourceIpSet, consts.MatchType_Mac:
|
case consts.MatchType_IpSet, consts.MatchType_SourceIpSet, consts.MatchType_Mac:
|
||||||
lpmIndex := int(binary.LittleEndian.Uint16(match.Value[:]))
|
lpmIndex := uint32(binary.LittleEndian.Uint16(match.Value[:]))
|
||||||
_, hit := m.lpms[lpmIndex].Lookup(*lpmKeys[int(match.Type)])
|
var lpm *ebpf.Map
|
||||||
if hit {
|
if err = m.lpmArrayMap.Lookup(lpmIndex, &lpm); err != nil {
|
||||||
goodSubrule = true
|
break
|
||||||
}
|
}
|
||||||
|
var v uint32
|
||||||
|
if err = lpm.Lookup(*lpmKeys[int(match.Type)], &v); err != nil {
|
||||||
|
_ = lpm.Close()
|
||||||
|
break
|
||||||
|
}
|
||||||
|
_ = lpm.Close()
|
||||||
|
goodSubrule = true
|
||||||
case consts.MatchType_DomainSet:
|
case consts.MatchType_DomainSet:
|
||||||
if domainMatchBitmap != nil && (domainMatchBitmap[i/32]>>(i%32))&1 > 0 {
|
if domainMatchBitmap != nil && (domainMatchBitmap[i/32]>>(i%32))&1 > 0 {
|
||||||
goodSubrule = true
|
goodSubrule = true
|
||||||
|
Reference in New Issue
Block a user