safing-portmaster/network/geoip/database.go
2019-07-02 13:00:44 +02:00

96 lines
1.7 KiB
Go

package geoip
import (
"fmt"
"sync"
maxminddb "github.com/oschwald/maxminddb-golang"
"github.com/Safing/portbase/log"
"github.com/Safing/portmaster/updates"
)
var (
dbCity *maxminddb.Reader
dbASN *maxminddb.Reader
dbLock sync.Mutex
dbInUse = false // only activate if used for first time
dbDoReload = true // if database should be reloaded
)
func ReloadDatabases() error {
dbLock.Lock()
defer dbLock.Unlock()
// don't do anything if the database isn't actually used
if !dbInUse {
return nil
}
dbDoReload = true
return doReload()
}
func prepDatabaseForUse() error {
dbInUse = true
return doReload()
}
func doReload() error {
// reload if needed
if dbDoReload {
defer func() {
dbDoReload = false
}()
closeDBs()
return openDBs()
}
return nil
}
func openDBs() error {
var err error
file, err := updates.GetFile("intel/geoip-city.mmdb")
if err != nil {
return fmt.Errorf("could not get GeoIP City database file: %s", err)
}
dbCity, err = maxminddb.Open(file.Path())
if err != nil {
return err
}
file, err = updates.GetFile("intel/geoip-asn.mmdb")
if err != nil {
return fmt.Errorf("could not get GeoIP ASN database file: %s", err)
}
dbASN, err = maxminddb.Open(file.Path())
if err != nil {
return err
}
return nil
}
func handleError(err error) {
log.Warningf("network/geoip: lookup failed, reloading databases...")
dbDoReload = true
}
func closeDBs() {
if dbCity != nil {
err := dbCity.Close()
if err != nil {
log.Warningf("network/geoip: failed to close database: %s", err)
}
}
dbCity = nil
if dbASN != nil {
err := dbASN.Close()
if err != nil {
log.Warningf("network/geoip: failed to close database: %s", err)
}
}
dbASN = nil
}