mirror of
https://github.com/SagerNet/sing-box.git
synced 2024-11-13 20:33:16 +00:00
Improve load geosite
This commit is contained in:
parent
9c256afc1a
commit
d45007b501
|
@ -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)
|
||||||
|
|
|
@ -24,6 +24,3 @@ func TLSClientHello(ctx context.Context, reader io.Reader) (*adapter.InboundCont
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func Packet() {
|
|
||||||
}
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue