diff options
| -rw-r--r-- | go.mod | 2 | ||||
| -rw-r--r-- | go.sum | 4 | ||||
| -rw-r--r-- | pkg/api/api0/api.go | 6 | ||||
| -rw-r--r-- | pkg/api/api0/server.go | 3 | ||||
| -rw-r--r-- | pkg/atlas/server.go | 8 | ||||
| -rw-r--r-- | pkg/atlas/util.go | 25 | ||||
| -rw-r--r-- | pkg/regionmap/region.go | 38 |
7 files changed, 50 insertions, 36 deletions
@@ -10,7 +10,7 @@ require ( github.com/jmoiron/sqlx v1.3.5 github.com/klauspost/compress v1.15.12 github.com/mattn/go-sqlite3 v1.14.16 - github.com/pg9182/ip2x v0.0.7 + github.com/pg9182/ip2x v0.1.1 github.com/rs/zerolog v1.28.0 github.com/spf13/pflag v1.0.5 golang.org/x/mod v0.7.0 @@ -26,8 +26,8 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -github.com/pg9182/ip2x v0.0.7 h1:fQkCMKqAMUEzFisWbxXS8TAWB3xHmdrxD1BnjFjTPpk= -github.com/pg9182/ip2x v0.0.7/go.mod h1:iJzts7yWZDWUaldqNGFVOZ0MW9uYrGk1hv9R/wTJdNQ= +github.com/pg9182/ip2x v0.1.1 h1:J++3N8OV+k7zK3xAY5mSZWE73EbwgqIxpzeloL7Zqyk= +github.com/pg9182/ip2x v0.1.1/go.mod h1:iJzts7yWZDWUaldqNGFVOZ0MW9uYrGk1hv9R/wTJdNQ= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= diff --git a/pkg/api/api0/api.go b/pkg/api/api0/api.go index 3fe1f3c..fb557ad 100644 --- a/pkg/api/api0/api.go +++ b/pkg/api/api0/api.go @@ -25,7 +25,7 @@ import ( "time" "github.com/klauspost/compress/gzip" - "github.com/pg9182/ip2x/ip2location" + "github.com/pg9182/ip2x" "github.com/r2northstar/atlas/pkg/origin" "github.com/rs/zerolog/hlog" "golang.org/x/mod/semver" @@ -83,7 +83,7 @@ type Handler struct { // LookupIP looks up an IP2Location record for an IP. If not provided, // server regions are disabled. - LookupIP func(netip.Addr, ip2location.Field) (ip2location.Record, error) + LookupIP func(netip.Addr) (ip2x.Record, error) // GetRegion gets the region name from an IP2Location record. If not // provided, server regions are disabled. @@ -94,7 +94,7 @@ type Handler struct { // // Note that it is valid to return an // empty region and no error if no region is to be assigned. - GetRegion func(netip.Addr, ip2location.Record) (string, error) + GetRegion func(netip.Addr, ip2x.Record) (string, error) metricsInit sync.Once metricsObj apiMetrics diff --git a/pkg/api/api0/server.go b/pkg/api/api0/server.go index 9daf2aa..ba04bc0 100644 --- a/pkg/api/api0/server.go +++ b/pkg/api/api0/server.go @@ -11,7 +11,6 @@ import ( "strings" "time" - "github.com/pg9182/ip2x/ip2location" "github.com/r2northstar/atlas/pkg/a2s" "github.com/r2northstar/atlas/pkg/api/api0/api0gameserver" "github.com/rs/zerolog/hlog" @@ -161,7 +160,7 @@ func (h *Handler) handleServerUpsert(w http.ResponseWriter, r *http.Request) { if canCreate || canUpdate { if h.LookupIP != nil && h.GetRegion != nil { - if rec, err := h.LookupIP(raddr.Addr(), ip2location.CountryLong|ip2location.CountryShort|ip2location.Region|ip2location.City|ip2location.Latitude|ip2location.Longitude); err == nil { + if rec, err := h.LookupIP(raddr.Addr()); err == nil { region, err := h.GetRegion(raddr.Addr(), rec) if err == nil || region != "" { // if an error occurs, we may still have a best-effort region if canCreate { diff --git a/pkg/atlas/server.go b/pkg/atlas/server.go index 7b25dad..55f1b5c 100644 --- a/pkg/atlas/server.go +++ b/pkg/atlas/server.go @@ -21,7 +21,7 @@ import ( "github.com/VictoriaMetrics/metrics" "github.com/klauspost/compress/gzip" - "github.com/pg9182/ip2x/ip2location" + "github.com/pg9182/ip2x" "github.com/r2northstar/atlas/db/atlasdb" "github.com/r2northstar/atlas/db/pdatadb" "github.com/r2northstar/atlas/pkg/api/api0" @@ -630,15 +630,15 @@ func configureMainMenuPromos(c *Config) (func(*http.Request) api0.MainMenuPromos } } -func configureIP2Location(c *Config) (*ip2locationMgr, error) { +func configureIP2Location(c *Config) (*ip2xMgr, error) { if c.IP2Location == "" { return nil, nil } - mgr := new(ip2locationMgr) + mgr := new(ip2xMgr) return mgr, mgr.Load(c.IP2Location) } -func configureRegionMap(c *Config) (func(netip.Addr, ip2location.Record) (string, error), error) { +func configureRegionMap(c *Config) (func(netip.Addr, ip2x.Record) (string, error), error) { switch m := c.API0_RegionMap; m { case "", "none": return nil, nil diff --git a/pkg/atlas/util.go b/pkg/atlas/util.go index d5f71e1..7ea8b14 100644 --- a/pkg/atlas/util.go +++ b/pkg/atlas/util.go @@ -8,20 +8,20 @@ import ( "os" "sync" - "github.com/pg9182/ip2x/ip2location" + "github.com/pg9182/ip2x" "github.com/rs/zerolog" ) -// ip2locationMgr wraps a file-backed IP2Location database. -type ip2locationMgr struct { +// ip2xMgr wraps a file-backed IP2Location database. +type ip2xMgr struct { file *os.File - db *ip2location.DB + db *ip2x.DB mu sync.RWMutex } // Load replaces the currently loaded database with the specified file. If name // is empty, the existing database, if any, is reopened. -func (m *ip2locationMgr) Load(name string) error { +func (m *ip2xMgr) Load(name string) error { if name == "" { m.mu.RLock() if m.file == nil { @@ -36,12 +36,17 @@ func (m *ip2locationMgr) Load(name string) error { return err } - db, err := ip2location.New(f) + db, err := ip2x.New(f) if err != nil { f.Close() return err } + if p, _ := db.Info(); p != ip2x.IP2Location { + f.Close() + return fmt.Errorf("not an ip2location database") + } + m.mu.Lock() defer m.mu.Unlock() @@ -51,14 +56,14 @@ func (m *ip2locationMgr) Load(name string) error { return nil } -// LookupFields calls (*ip2location.DB).LookupFields if a database is loaded. -func (m *ip2locationMgr) LookupFields(ip netip.Addr, mask ip2location.Field) (ip2location.Record, error) { +// Lookup calls [ip2x.DB.Lookup] if a database is loaded. +func (m *ip2xMgr) LookupFields(ip netip.Addr) (ip2x.Record, error) { m.mu.RLock() defer m.mu.RUnlock() if m.db == nil { - return ip2location.Record{}, fmt.Errorf("no ip2location database loaded") + return ip2x.Record{}, fmt.Errorf("no ip2location database loaded") } - return m.db.LookupFields(ip, mask) + return m.db.Lookup(ip) } type zerologWriterLevel struct { diff --git a/pkg/regionmap/region.go b/pkg/regionmap/region.go index 539449b..fdbdf12 100644 --- a/pkg/regionmap/region.go +++ b/pkg/regionmap/region.go @@ -18,24 +18,34 @@ import ( "fmt" "net/netip" - "github.com/pg9182/ip2x/ip2location" + "github.com/pg9182/ip2x" ) // GetRegion gets the region name for the provided IP address and IP2Location // record. The IP2Location record should have at least CountryShort and Region // fields. If the location is unrecognized, a best-effort region and an error is // returned. -func GetRegion(ip netip.Addr, r ip2location.Record) (string, error) { +func GetRegion(ip netip.Addr, r ip2x.Record) (string, error) { // RFC 1918/4193 -> "Local" if ip.IsPrivate() { return "Local", nil } + country, ok := r.GetString(ip2x.CountryCode) + if !ok { + return "", fmt.Errorf("missing country field in ip2location data") + } + + region, ok := r.GetString(ip2x.Region) + if !ok { + return "", fmt.Errorf("missing region field in ip2location data") + } + // for Canada, use the 3-region model - if r.CountryShort == "CA" { + if country == "CA" { // province names: https://www.ip2location.com/free/iso3166-2 @ 2022-11-20 // 3-region model: https://en.wikipedia.org/wiki/List_of_regions_of_Canada @ 2022-11-20 - switch r.Region { + switch region { case "British Columbia", "Alberta", "Saskatchewan", "Manitoba": return "CA West", nil @@ -50,15 +60,15 @@ func GetRegion(ip netip.Addr, r ip2location.Record) (string, error) { return "CA", nil default: - return "CA", fmt.Errorf("unhandled Canada province %q", r.Region) + return "CA", fmt.Errorf("unhandled Canada province %q", region) } } // for the United States, use the census regions - if r.CountryShort == "US" { + if country == "US" { // state names: https://www.ip2location.com/free/iso3166-2 @ 2022-11-20 // census region: https://www2.census.gov/geo/pdfs/maps-data/maps/reference/us_regdiv.pdf @ 2022-11-20 - switch r.Region { + switch region { case "Connecticut", "Maine", "Massachusetts", "New Hampshire", "Rhode Island", "Vermont", "New Jersey", "New York", "Pennsylvania": return "US East", nil @@ -83,34 +93,34 @@ func GetRegion(ip netip.Addr, r ip2location.Record) (string, error) { return "US", nil default: - return "US", fmt.Errorf("unhandled US state %q", r.Region) + return "US", fmt.Errorf("unhandled US state %q", region) } } // for China, use "CN" - if r.CountryShort == "CN" { + if country == "CN" { return "CN", nil } // for Russia, use "RU" - if r.CountryShort == "RU" { + if country == "RU" { return "RU", nil } // for Antartica, use Antartica (this won't really get hit in practice though) - if r.CountryShort == "AQ" { + if country == "AQ" { return "Antartica", nil } // for Taiwan, use "Asia East" (it isn't in the UN M.49 mapping) - if r.CountryShort == "TW" { + if country == "TW" { return "Asia East", nil } // the rest are based on the M.49 mapping - m49region, m49subRegion, _, ok := m49(r.CountryShort) + m49region, m49subRegion, _, ok := m49(country) if !ok { - return "", fmt.Errorf("unhandled UN M.49 mapping for ISO 3166-2 code %q", r.CountryShort) + return "", fmt.Errorf("unhandled UN M.49 mapping for ISO 3166-2 code %q", country) } // for other parts of America, use "Americas" |
