NekoBoxForAndroid/libcore/geoip.go
2024-02-17 17:02:17 +08:00

79 lines
1.8 KiB
Go

package libcore
import (
"github.com/oschwald/maxminddb-golang"
"github.com/sagernet/sing-box/common/srs"
C "github.com/sagernet/sing-box/constant"
"github.com/sagernet/sing-box/option"
"log"
"net"
"os"
"strings"
)
type Geoip struct {
geoipReader *maxminddb.Reader
}
func (g *Geoip) OpenGeosite(path string) bool {
geoipReader, err := maxminddb.Open(path)
g.geoipReader = geoipReader
if err != nil {
log.Println("failed to open geoip file:", err)
return false
} else {
log.Println("loaded geoip database")
}
return true
}
func (g *Geoip) ConvertGeoip(countryCode, outputPath string) {
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 {
log.Println("failed to get network:", err)
return
}
countryMap[nextCountryCode] = append(countryMap[nextCountryCode], ipNet)
}
ipNets := countryMap[strings.ToLower(countryCode)]
if len(ipNets) == 0 {
log.Println("no networks found for country code:", countryCode)
return
}
var headlessRule option.DefaultHeadlessRule
headlessRule.IPCIDR = make([]string, 0, len(ipNets))
for _, cidr := range ipNets {
headlessRule.IPCIDR = append(headlessRule.IPCIDR, cidr.String())
}
var plainRuleSet option.PlainRuleSetCompat
plainRuleSet.Version = C.RuleSetVersion1
plainRuleSet.Options.Rules = []option.HeadlessRule{
{
Type: C.RuleTypeDefault,
DefaultOptions: headlessRule,
},
}
outputFile, err := os.Create(outputPath)
err = srs.Write(outputFile, plainRuleSet.Upgrade())
if err != nil {
log.Println("failed to write geosite file:", err)
return
}
}
func NewGeoip() *Geoip {
return new(Geoip)
}