diff --git a/src/def.go b/src/def.go index a2a7cd4..acb7bdd 100644 --- a/src/def.go +++ b/src/def.go @@ -43,7 +43,7 @@ const ( /* Build Constants */ SYSTEM_NAME = "Zoraxy" SYSTEM_VERSION = "3.1.5" - DEVELOPMENT_BUILD = true /* Development: Set to false to use embedded web fs */ + DEVELOPMENT_BUILD = false /* Development: Set to false to use embedded web fs */ /* System Constants */ DATABASE_PATH = "sys.db" @@ -89,6 +89,9 @@ var ( staticWebServerRoot = flag.String("webroot", "./www", "Static web server root folder. Only allow chnage in start paramters") allowWebFileManager = flag.Bool("webfm", true, "Enable web file manager for static web server root folder") enableAutoUpdate = flag.Bool("cfgupgrade", true, "Enable auto config upgrade if breaking change is detected") + + /* Maintaince Function Flags */ + geoDbUpdate = flag.Bool("update_geoip", false, "Download the latest GeoIP data and exit") ) /* Global Variables and Handlers */ diff --git a/src/main.go b/src/main.go index 48d6c60..0fd0618 100644 --- a/src/main.go +++ b/src/main.go @@ -42,6 +42,7 @@ import ( "github.com/google/uuid" "github.com/gorilla/csrf" + "imuslab.com/zoraxy/mod/geodb" "imuslab.com/zoraxy/mod/update" "imuslab.com/zoraxy/mod/utils" ) @@ -60,11 +61,18 @@ func SetupCloseHandler() { func main() { //Parse startup flags flag.Parse() + + /* Maintaince Function Modes */ if *showver { fmt.Println(SYSTEM_NAME + " - Version " + SYSTEM_VERSION) os.Exit(0) } + if *geoDbUpdate { + geodb.DownloadGeoDBUpdate("./conf/geodb") + os.Exit(0) + } + /* Main Zoraxy Routines */ if !utils.ValidateListeningAddress(*webUIPort) { fmt.Println("Malformed -port (listening address) paramter. Do you mean -port=:" + *webUIPort + "?") os.Exit(0) diff --git a/src/mod/geodb/geodb.go b/src/mod/geodb/geodb.go index 314a75e..cf35c2c 100644 --- a/src/mod/geodb/geodb.go +++ b/src/mod/geodb/geodb.go @@ -3,11 +3,14 @@ package geodb import ( _ "embed" "net/http" + "os" "sync" "time" "imuslab.com/zoraxy/mod/database" + "imuslab.com/zoraxy/mod/info/logger" "imuslab.com/zoraxy/mod/netutils" + "imuslab.com/zoraxy/mod/utils" ) //go:embed geoipv4.csv @@ -32,6 +35,7 @@ type Store struct { type StoreOptions struct { AllowSlowIpv4LookUp bool AllowSlowIpv6Lookup bool + Logger *logger.Logger SlowLookupCacheClearInterval time.Duration //Clear slow lookup cache interval } @@ -41,6 +45,23 @@ type CountryInfo struct { } func NewGeoDb(sysdb *database.Database, option *StoreOptions) (*Store, error) { + //Check if external geoDB data is available + if utils.FileExists("./conf/geodb/geoipv4.csv") { + externalV4Db, err := os.ReadFile("./conf/geodb/geoipv4.csv") + if err == nil { + option.Logger.PrintAndLog("GeoDB", "External GeoDB data found, using external IPv4 GeoIP data", nil) + geoipv4 = externalV4Db + } + } + + if utils.FileExists("./conf/geodb/geoipv6.csv") { + externalV6Db, err := os.ReadFile("./conf/geodb/geoipv6.csv") + if err == nil { + option.Logger.PrintAndLog("GeoDB", "External GeoDB data found, using external IPv6 GeoIP data", nil) + geoipv6 = externalV6Db + } + } + parsedGeoData, err := parseCSV(geoipv4) if err != nil { return nil, err diff --git a/src/mod/geodb/geodb_test.go b/src/mod/geodb/geodb_test.go index d778e8a..a5e1c4f 100644 --- a/src/mod/geodb/geodb_test.go +++ b/src/mod/geodb/geodb_test.go @@ -4,6 +4,7 @@ import ( "testing" "imuslab.com/zoraxy/mod/geodb" + "imuslab.com/zoraxy/mod/info/logger" ) /* @@ -44,6 +45,7 @@ func TestResolveCountryCodeFromIP(t *testing.T) { store, err := geodb.NewGeoDb(nil, &geodb.StoreOptions{ true, true, + &logger.Logger{}, 0, }) if err != nil { diff --git a/src/mod/geodb/updater.go b/src/mod/geodb/updater.go new file mode 100644 index 0000000..38d5915 --- /dev/null +++ b/src/mod/geodb/updater.go @@ -0,0 +1,56 @@ +package geodb + +import ( + "io" + "log" + "net/http" + "os" + + "imuslab.com/zoraxy/mod/utils" +) + +const ( + ipv4UpdateSource = "https://cdn.jsdelivr.net/npm/@ip-location-db/geo-whois-asn-country/geo-whois-asn-country-ipv4.csv" + ipv6UpdateSource = "https://cdn.jsdelivr.net/npm/@ip-location-db/geo-whois-asn-country/geo-whois-asn-country-ipv6.csv" +) + +// DownloadGeoDBUpdate download the latest geodb update +func DownloadGeoDBUpdate(externalGeoDBStoragePath string) { + //Create the storage path if not exist + if !utils.FileExists(externalGeoDBStoragePath) { + os.MkdirAll(externalGeoDBStoragePath, 0755) + } + + //Download the update + log.Println("Downloading IPv4 database update...") + err := downloadFile(ipv4UpdateSource, externalGeoDBStoragePath+"/geoipv4.csv") + if err != nil { + log.Println(err) + return + } + + log.Println("Downloading IPv6 database update...") + err = downloadFile(ipv6UpdateSource, externalGeoDBStoragePath+"/geoipv6.csv") + if err != nil { + log.Println(err) + return + } + + log.Println("GeoDB update stored at: " + externalGeoDBStoragePath) + log.Println("Exiting...") +} + +// Utility functions +func downloadFile(url string, savepath string) error { + resp, err := http.Get(url) + if err != nil { + return err + } + defer resp.Body.Close() + + fileContent, err := io.ReadAll(resp.Body) + if err != nil { + return err + } + return os.WriteFile(savepath, fileContent, 0644) +} diff --git a/src/start.go b/src/start.go index 45866dc..bdf0a90 100644 --- a/src/start.go +++ b/src/start.go @@ -114,6 +114,7 @@ func startupSequence() { geodbStore, err = geodb.NewGeoDb(sysdb, &geodb.StoreOptions{ AllowSlowIpv4LookUp: !*enableHighSpeedGeoIPLookup, AllowSlowIpv6Lookup: !*enableHighSpeedGeoIPLookup, + Logger: SystemWideLogger, SlowLookupCacheClearInterval: GEODB_CACHE_CLEAR_INTERVAL * time.Minute, }) if err != nil {