Improve load geosite

This commit is contained in:
世界 2022-07-08 11:00:46 +08:00
parent 9c256afc1a
commit d45007b501
No known key found for this signature in database
GPG key ID: CD109927C34A63C4
4 changed files with 33 additions and 29 deletions

View file

@ -8,7 +8,6 @@ import (
N "github.com/sagernet/sing/common/network" N "github.com/sagernet/sing/common/network"
"github.com/sagernet/sing-box/common/geoip" "github.com/sagernet/sing-box/common/geoip"
"github.com/sagernet/sing-box/common/geosite"
C "github.com/sagernet/sing-box/constant" C "github.com/sagernet/sing-box/constant"
"golang.org/x/net/dns/dnsmessage" "golang.org/x/net/dns/dnsmessage"
@ -21,7 +20,7 @@ type Router interface {
RouteConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error RouteConnection(ctx context.Context, conn net.Conn, metadata InboundContext) error
RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error RoutePacketConnection(ctx context.Context, conn N.PacketConn, metadata InboundContext) error
GeoIPReader() *geoip.Reader GeoIPReader() *geoip.Reader
GeositeReader() *geosite.Reader LoadGeosite(code string) (Rule, error)
Exchange(ctx context.Context, message *dnsmessage.Message) (*dnsmessage.Message, error) Exchange(ctx context.Context, message *dnsmessage.Message) (*dnsmessage.Message, error)
Lookup(ctx context.Context, domain string, strategy C.DomainStrategy) ([]netip.Addr, error) Lookup(ctx context.Context, domain string, strategy C.DomainStrategy) ([]netip.Addr, error)
LookupDefault(ctx context.Context, domain string) ([]netip.Addr, error) LookupDefault(ctx context.Context, domain string) ([]netip.Addr, error)

View file

@ -24,6 +24,3 @@ func TLSClientHello(ctx context.Context, reader io.Reader) (*adapter.InboundCont
} }
return nil, err return nil, err
} }
func Packet() {
}

View file

@ -53,6 +53,7 @@ type Router struct {
geositeOptions option.GeositeOptions geositeOptions option.GeositeOptions
geoIPReader *geoip.Reader geoIPReader *geoip.Reader
geositeReader *geosite.Reader geositeReader *geosite.Reader
geositeCache map[string]adapter.Rule
dnsClient adapter.DNSClient dnsClient adapter.DNSClient
defaultDomainStrategy C.DomainStrategy defaultDomainStrategy C.DomainStrategy
@ -75,6 +76,7 @@ func NewRouter(ctx context.Context, logger log.Logger, options option.RouteOptio
needGeositeDatabase: hasGeoRule(options.Rules, isGeositeRule) || hasGeoDNSRule(dnsOptions.Rules, isGeositeDNSRule), needGeositeDatabase: hasGeoRule(options.Rules, isGeositeRule) || hasGeoDNSRule(dnsOptions.Rules, isGeositeDNSRule),
geoIPOptions: common.PtrValueOrDefault(options.GeoIP), geoIPOptions: common.PtrValueOrDefault(options.GeoIP),
geositeOptions: common.PtrValueOrDefault(options.Geosite), geositeOptions: common.PtrValueOrDefault(options.Geosite),
geositeCache: make(map[string]adapter.Rule),
defaultDetour: options.Final, defaultDetour: options.Final,
dnsClient: dns.NewClient(dnsOptions.DNSClientOptions), dnsClient: dns.NewClient(dnsOptions.DNSClientOptions),
defaultDomainStrategy: C.DomainStrategy(dnsOptions.Strategy), defaultDomainStrategy: C.DomainStrategy(dnsOptions.Strategy),
@ -285,6 +287,8 @@ func (r *Router) Start() error {
if err != nil { if err != nil {
return err return err
} }
r.geositeCache = nil
r.geositeReader = nil
} }
return nil return nil
} }
@ -311,8 +315,21 @@ func (r *Router) GeoIPReader() *geoip.Reader {
return r.geoIPReader return r.geoIPReader
} }
func (r *Router) GeositeReader() *geosite.Reader { func (r *Router) LoadGeosite(code string) (adapter.Rule, error) {
return r.geositeReader rule, cached := r.geositeCache[code]
if cached {
return rule, nil
}
items, err := r.geositeReader.Read(code)
if err != nil {
return nil, err
}
rule, err = NewDefaultRule(r, nil, geosite.Compile(items))
if err != nil {
return nil, err
}
r.geositeCache[code] = rule
return rule, nil
} }
func (r *Router) Outbound(tag string) (adapter.Outbound, bool) { func (r *Router) Outbound(tag string) (adapter.Outbound, bool) {

View file

@ -6,9 +6,7 @@ import (
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
"github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/adapter"
"github.com/sagernet/sing-box/common/geosite"
"github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/log"
"github.com/sagernet/sing-box/option"
) )
var _ RuleItem = (*GeositeItem)(nil) var _ RuleItem = (*GeositeItem)(nil)
@ -17,7 +15,7 @@ type GeositeItem struct {
router adapter.Router router adapter.Router
logger log.Logger logger log.Logger
codes []string codes []string
matcher *DefaultRule matchers []adapter.Rule
} }
func NewGeositeItem(router adapter.Router, logger log.Logger, codes []string) *GeositeItem { func NewGeositeItem(router adapter.Router, logger log.Logger, codes []string) *GeositeItem {
@ -29,32 +27,25 @@ func NewGeositeItem(router adapter.Router, logger log.Logger, codes []string) *G
} }
func (r *GeositeItem) Update() error { func (r *GeositeItem) Update() error {
geositeReader := r.router.GeositeReader() var matchers []adapter.Rule
if geositeReader == nil {
return E.New("geosite reader is not initialized")
}
var subRules []option.DefaultRule
for _, code := range r.codes { for _, code := range r.codes {
items, err := geositeReader.Read(code) matcher, err := r.router.LoadGeosite(code)
if err != nil { if err != nil {
return E.Cause(err, "read geosite") return E.Cause(err, "read geosite")
} }
subRules = append(subRules, geosite.Compile(items)) matchers = append(matchers, matcher)
} }
matcherRule := geosite.Merge(subRules) r.matchers = matchers
matcher, err := NewDefaultRule(r.router, r.logger, matcherRule)
if err != nil {
return E.Cause(err, "compile geosite")
}
r.matcher = matcher
return nil return nil
} }
func (r *GeositeItem) Match(metadata *adapter.InboundContext) bool { func (r *GeositeItem) Match(metadata *adapter.InboundContext) bool {
if r.matcher == nil { for _, matcher := range r.matchers {
return false if matcher.Match(metadata) {
return true
} }
return r.matcher.Match(metadata) }
return false
} }
func (r *GeositeItem) String() string { func (r *GeositeItem) String() string {