diff --git a/control/control_plane.go b/control/control_plane.go index 392162b..4ca7181 100644 --- a/control/control_plane.go +++ b/control/control_plane.go @@ -26,6 +26,7 @@ import ( "net/netip" "os" "path/filepath" + "runtime" "strconv" "strings" "sync" @@ -322,6 +323,9 @@ func NewControlPlane( c.dnsUpstream.FinishInitCallback = c.finishInitDnsUpstreamResolve // Try to invoke once to avoid dns leaking at the very beginning. _, _ = c.dnsUpstream.GetUpstream() + + // Call GC to release memory. + runtime.GC() return c, nil } diff --git a/control/routing_matcher_builder.go b/control/routing_matcher_builder.go index 3689e72..d526a6f 100644 --- a/control/routing_matcher_builder.go +++ b/control/routing_matcher_builder.go @@ -8,7 +8,6 @@ package control import ( "encoding/binary" "fmt" - "github.com/Asphaltt/lpmtrie" "github.com/cilium/ebpf" "github.com/v2rayA/dae/common" "github.com/v2rayA/dae/common/consts" @@ -26,7 +25,6 @@ type RoutingMatcherBuilder struct { rules []bpfMatchSet simulatedLpmTries [][]netip.Prefix simulatedDomainSet []routing.DomainSet - Fallback string err error } @@ -215,7 +213,6 @@ func (b *RoutingMatcherBuilder) AddFallback(outbound string) { if b.err != nil { return } - b.Fallback = outbound b.rules = append(b.rules, bpfMatchSet{ Type: uint8(consts.MatchType_Fallback), Outbound: b.OutboundToId(outbound), @@ -266,18 +263,6 @@ func (b *RoutingMatcherBuilder) BuildUserspace() (matcher *RoutingMatcher, err e return nil, b.err } 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 m.domainMatcher = domain_matcher.NewAhocorasickSlimtrie(consts.MaxMatchSetLen) for _, domains := range b.simulatedDomainSet { diff --git a/control/routing_matcher_userspace.go b/control/routing_matcher_userspace.go index 58c875a..5cd1b85 100644 --- a/control/routing_matcher_userspace.go +++ b/control/routing_matcher_userspace.go @@ -9,6 +9,8 @@ import ( "encoding/binary" "fmt" "github.com/Asphaltt/lpmtrie" + "github.com/cilium/ebpf" + "github.com/v2rayA/dae/common" "github.com/v2rayA/dae/common/consts" "github.com/v2rayA/dae/component/routing" "net" @@ -16,7 +18,7 @@ import ( ) type RoutingMatcher struct { - lpms []lpmtrie.LpmTrie + lpmArrayMap *ebpf.Map domainMatcher routing.DomainMatcher // All domain matchSets use one DomainMatcher. matches []bpfMatchSet @@ -37,18 +39,18 @@ func (m *RoutingMatcher) Match( if len(sourceAddr) != net.IPv6len || len(destAddr) != net.IPv6len || len(mac) != net.IPv6len { return 0, fmt.Errorf("bad address length") } - lpmKeys := make([]*lpmtrie.Key, consts.MatchType_Mac+1) - lpmKeys[consts.MatchType_IpSet] = &lpmtrie.Key{ + lpmKeys := make([]*_bpfLpmKey, consts.MatchType_Mac+1) + lpmKeys[consts.MatchType_IpSet] = &_bpfLpmKey{ PrefixLen: 128, - Data: destAddr, + Data: common.Ipv6ByteSliceToUint32Array(destAddr), } - lpmKeys[consts.MatchType_SourceIpSet] = &lpmtrie.Key{ + lpmKeys[consts.MatchType_SourceIpSet] = &_bpfLpmKey{ PrefixLen: 128, - Data: sourceAddr, + Data: common.Ipv6ByteSliceToUint32Array(sourceAddr), } - lpmKeys[consts.MatchType_Mac] = &lpmtrie.Key{ + lpmKeys[consts.MatchType_Mac] = &_bpfLpmKey{ PrefixLen: 128, - Data: mac, + Data: common.Ipv6ByteSliceToUint32Array(mac), } var domainMatchBitmap []uint32 if domain != "" { @@ -63,11 +65,18 @@ func (m *RoutingMatcher) Match( } switch consts.MatchType(match.Type) { case consts.MatchType_IpSet, consts.MatchType_SourceIpSet, consts.MatchType_Mac: - lpmIndex := int(binary.LittleEndian.Uint16(match.Value[:])) - _, hit := m.lpms[lpmIndex].Lookup(*lpmKeys[int(match.Type)]) - if hit { - goodSubrule = true + lpmIndex := uint32(binary.LittleEndian.Uint16(match.Value[:])) + var lpm *ebpf.Map + if err = m.lpmArrayMap.Lookup(lpmIndex, &lpm); err != nil { + 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: if domainMatchBitmap != nil && (domainMatchBitmap[i/32]>>(i%32))&1 > 0 { goodSubrule = true