mirror of
https://github.com/MatsuriDayo/NekoBoxForAndroid.git
synced 2025-12-18 22:20:06 +08:00
70 lines
1.6 KiB
Go
70 lines
1.6 KiB
Go
package libcore
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/oschwald/maxminddb-golang"
|
|
C "github.com/sagernet/sing-box/constant"
|
|
"github.com/sagernet/sing-box/nekoutils"
|
|
"github.com/sagernet/sing-box/option"
|
|
)
|
|
|
|
type geoip struct {
|
|
geoipReader *maxminddb.Reader
|
|
}
|
|
|
|
func (g *geoip) Open(path string) error {
|
|
geoipReader, err := maxminddb.Open(path)
|
|
g.geoipReader = geoipReader
|
|
return err
|
|
}
|
|
|
|
func (g *geoip) Rules(countryCode string) ([]option.HeadlessRule, error) {
|
|
networks := g.geoipReader.Networks(maxminddb.SkipAliasedNetworks)
|
|
countryMap := make(map[string][]*net.IPNet)
|
|
var (
|
|
ipNet *net.IPNet
|
|
nextCountryCode string
|
|
err error
|
|
)
|
|
for networks.Next() {
|
|
ipNet, err = networks.Network(&nextCountryCode)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to get network: %w", err)
|
|
}
|
|
countryMap[nextCountryCode] = append(countryMap[nextCountryCode], ipNet)
|
|
}
|
|
|
|
ipNets := countryMap[strings.ToLower(countryCode)]
|
|
|
|
if len(ipNets) == 0 {
|
|
return nil, fmt.Errorf("no networks found for country code: %s", countryCode)
|
|
}
|
|
|
|
var headlessRule option.DefaultHeadlessRule
|
|
headlessRule.IPCIDR = make([]string, 0, len(ipNets))
|
|
for _, cidr := range ipNets {
|
|
headlessRule.IPCIDR = append(headlessRule.IPCIDR, cidr.String())
|
|
}
|
|
|
|
return []option.HeadlessRule{
|
|
{
|
|
Type: C.RuleTypeDefault,
|
|
DefaultOptions: headlessRule,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func init() {
|
|
nekoutils.GetGeoIPHeadlessRules = func(name string) ([]option.HeadlessRule, error) {
|
|
g := new(geoip)
|
|
if err := g.Open(filepath.Join(externalAssetsPath, "geoip.db")); err != nil {
|
|
return nil, err
|
|
}
|
|
return g.Rules(name)
|
|
}
|
|
}
|