1
0
mirror of https://github.com/v2fly/v2ray-core.git synced 2024-11-10 06:16:53 -05:00
v2fly/infra/conf/geodata/memconservative/cache.go

142 lines
3.4 KiB
Go
Raw Normal View History

2021-05-04 06:19:03 -04:00
package memconservative
import (
2021-05-04 06:21:49 -04:00
"io/ioutil"
"strings"
2021-05-04 09:52:35 -04:00
"google.golang.org/protobuf/proto"
"github.com/v2fly/v2ray-core/v5/app/router/routercommon"
"github.com/v2fly/v2ray-core/v5/common/platform"
2021-05-04 06:19:03 -04:00
)
type GeoIPCache map[string]*routercommon.GeoIP
2021-05-04 06:19:03 -04:00
func (g GeoIPCache) Has(key string) bool {
return !(g.Get(key) == nil)
}
func (g GeoIPCache) Get(key string) *routercommon.GeoIP {
2021-05-04 06:19:03 -04:00
if g == nil {
return nil
}
return g[key]
}
func (g GeoIPCache) Set(key string, value *routercommon.GeoIP) {
2021-05-04 06:19:03 -04:00
if g == nil {
g = make(map[string]*routercommon.GeoIP)
2021-05-04 06:19:03 -04:00
}
g[key] = value
}
func (g GeoIPCache) Unmarshal(filename, code string) (*routercommon.GeoIP, error) {
2021-05-04 06:19:03 -04:00
asset := platform.GetAssetLocation(filename)
2021-05-04 09:51:38 -04:00
idx := strings.ToLower(asset + ":" + code)
2021-05-04 06:19:03 -04:00
if g.Has(idx) {
return g.Get(idx), nil
}
geoipBytes, err := Decode(asset, code)
switch err {
case nil:
var geoip routercommon.GeoIP
2021-05-04 06:19:03 -04:00
if err := proto.Unmarshal(geoipBytes, &geoip); err != nil {
return nil, err
}
g.Set(idx, &geoip)
return &geoip, nil
case errCodeNotFound:
2021-05-04 09:51:38 -04:00
return nil, newError("country code ", code, " not found in ", filename)
2021-05-04 06:19:03 -04:00
case errFailedToReadBytes, errFailedToReadExpectedLenBytes,
errInvalidGeodataFile, errInvalidGeodataVarintLength:
2021-05-04 09:51:38 -04:00
newError("failed to decode geoip file: ", filename, ", fallback to the original ReadFile method")
2021-05-04 06:19:03 -04:00
geoipBytes, err = ioutil.ReadFile(asset)
if err != nil {
return nil, err
}
var geoipList routercommon.GeoIPList
2021-05-04 06:19:03 -04:00
if err := proto.Unmarshal(geoipBytes, &geoipList); err != nil {
return nil, err
}
for _, geoip := range geoipList.GetEntry() {
if strings.EqualFold(code, geoip.GetCountryCode()) {
g.Set(idx, geoip)
return geoip, nil
}
}
default:
return nil, err
}
2021-05-04 09:51:38 -04:00
return nil, newError("country code ", code, " not found in ", filename)
2021-05-04 06:19:03 -04:00
}
type GeoSiteCache map[string]*routercommon.GeoSite
2021-05-04 06:19:03 -04:00
func (g GeoSiteCache) Has(key string) bool {
return !(g.Get(key) == nil)
}
func (g GeoSiteCache) Get(key string) *routercommon.GeoSite {
2021-05-04 06:19:03 -04:00
if g == nil {
return nil
}
return g[key]
}
func (g GeoSiteCache) Set(key string, value *routercommon.GeoSite) {
2021-05-04 06:19:03 -04:00
if g == nil {
g = make(map[string]*routercommon.GeoSite)
2021-05-04 06:19:03 -04:00
}
g[key] = value
}
func (g GeoSiteCache) Unmarshal(filename, code string) (*routercommon.GeoSite, error) {
2021-05-04 06:19:03 -04:00
asset := platform.GetAssetLocation(filename)
2021-05-04 09:51:38 -04:00
idx := strings.ToLower(asset + ":" + code)
2021-05-04 06:19:03 -04:00
if g.Has(idx) {
return g.Get(idx), nil
}
geositeBytes, err := Decode(asset, code)
switch err {
case nil:
var geosite routercommon.GeoSite
2021-05-04 06:19:03 -04:00
if err := proto.Unmarshal(geositeBytes, &geosite); err != nil {
return nil, err
}
g.Set(idx, &geosite)
return &geosite, nil
case errCodeNotFound:
2021-05-04 09:51:38 -04:00
return nil, newError("list ", code, " not found in ", filename)
2021-05-04 06:19:03 -04:00
case errFailedToReadBytes, errFailedToReadExpectedLenBytes,
errInvalidGeodataFile, errInvalidGeodataVarintLength:
2021-05-04 09:51:38 -04:00
newError("failed to decode geoip file: ", filename, ", fallback to the original ReadFile method")
2021-05-04 06:19:03 -04:00
geositeBytes, err = ioutil.ReadFile(asset)
if err != nil {
return nil, err
}
var geositeList routercommon.GeoSiteList
2021-05-04 06:19:03 -04:00
if err := proto.Unmarshal(geositeBytes, &geositeList); err != nil {
return nil, err
}
for _, geosite := range geositeList.GetEntry() {
if strings.EqualFold(code, geosite.GetCountryCode()) {
g.Set(idx, geosite)
return geosite, nil
}
}
default:
return nil, err
}
2021-05-04 09:51:38 -04:00
return nil, newError("list ", code, " not found in ", filename)
2021-05-04 06:19:03 -04:00
}