feat: Add sing-geoip database support

This commit is contained in:
H1JK
2023-07-14 22:28:24 +08:00
parent 5dd57bab67
commit 081e94c738
7 changed files with 73 additions and 19 deletions

View File

@ -12,42 +12,59 @@ import (
C "github.com/Dreamacro/clash/constant"
"github.com/Dreamacro/clash/log"
"github.com/oschwald/geoip2-golang"
"github.com/oschwald/maxminddb-golang"
)
type databaseType = uint8
const (
typeMaxmind databaseType = iota
typeSing
)
var (
mmdb *geoip2.Reader
once sync.Once
reader Reader
once sync.Once
)
func LoadFromBytes(buffer []byte) {
once.Do(func() {
var err error
mmdb, err = geoip2.FromBytes(buffer)
mmdb, err := maxminddb.FromBytes(buffer)
if err != nil {
log.Fatalln("Can't load mmdb: %s", err.Error())
}
reader = Reader{Reader: mmdb}
if mmdb.Metadata.DatabaseType == "sing-geoip" {
reader.databaseType = typeSing
} else {
reader.databaseType = typeMaxmind
}
})
}
func Verify() bool {
instance, err := geoip2.Open(C.Path.MMDB())
instance, err := maxminddb.Open(C.Path.MMDB())
if err == nil {
instance.Close()
}
return err == nil
}
func Instance() *geoip2.Reader {
func Instance() Reader {
once.Do(func() {
var err error
mmdb, err = geoip2.Open(C.Path.MMDB())
mmdb, err := maxminddb.Open(C.Path.MMDB())
if err != nil {
log.Fatalln("Can't load mmdb: %s", err.Error())
}
reader = Reader{Reader: mmdb}
if mmdb.Metadata.DatabaseType == "sing-geoip" {
reader.databaseType = typeSing
} else {
reader.databaseType = typeMaxmind
}
})
return mmdb
return reader
}
func DownloadMMDB(path string) (err error) {

36
component/mmdb/reader.go Normal file
View File

@ -0,0 +1,36 @@
package mmdb
import (
"fmt"
"net"
"github.com/oschwald/maxminddb-golang"
)
type geoip2Country struct {
Country struct {
IsoCode string `maxminddb:"iso_code"`
} `maxminddb:"country"`
}
type Reader struct {
*maxminddb.Reader
databaseType
}
func (r Reader) LookupCode(ipAddress net.IP) string {
switch r.databaseType {
case typeMaxmind:
var country geoip2Country
_ = r.Lookup(ipAddress, &country)
return country.Country.IsoCode
case typeSing:
var code string
_ = r.Lookup(ipAddress, &code)
return code
default:
panic(fmt.Sprint("unknown geoip database type:", r.databaseType))
}
}