plugin/geoip: Add ASN schema support (#7730)

Adds the ability to query ASN .mmdb databases, in addition to the existing City db functionality.

Signed-off-by: Eric Case <eric.case@gmail.com>
This commit is contained in:
Eric Case
2025-11-30 08:36:33 -08:00
committed by GitHub
parent 604e1675cf
commit 54dd258d57
7 changed files with 213 additions and 37 deletions

View File

@@ -1,4 +1,4 @@
// Package geoip implements a max mind database plugin.
// Package geoip implements an MMDB database plugin for geo/network IP lookups.
package geoip
import (
@@ -17,8 +17,8 @@ import (
var log = clog.NewWithPlugin(pluginName)
// GeoIP is a plugin that add geo location data to the request context by looking up a maxmind
// geoIP2 database, and which data can be later consumed by other middlewares.
// GeoIP is a plugin that adds geo location and network data to the request context by looking up
// an MMDB format database, and which data can be later consumed by other middlewares.
type GeoIP struct {
Next plugin.Handler
db db
@@ -34,6 +34,7 @@ type db struct {
const (
city = 1 << iota
asn
)
var probingIP = net.ParseIP("127.0.0.1")
@@ -50,6 +51,7 @@ func newGeoIP(dbPath string, edns0 bool) (*GeoIP, error) {
validate func() error
}{
{name: "city", provides: city, validate: func() error { _, err := reader.City(probingIP); return err }},
{name: "asn", provides: asn, validate: func() error { _, err := reader.ASN(probingIP); return err }},
}
// Query the database to figure out the database type.
for _, schema := range schemas {
@@ -63,8 +65,8 @@ func newGeoIP(dbPath string, edns0 bool) (*GeoIP, error) {
}
}
if db.provides&city == 0 {
return nil, fmt.Errorf("database does not provide city schema")
if db.provides == 0 {
return nil, fmt.Errorf("database does not provide any supported schema (city, asn)")
}
return &GeoIP{db: db, edns0: edns0}, nil
@@ -91,14 +93,21 @@ func (g GeoIP) Metadata(ctx context.Context, state request.Request) context.Cont
}
}
switch g.db.provides & city {
case city:
if g.db.provides&city != 0 {
data, err := g.db.City(srcIP)
if err != nil {
log.Debugf("Setting up metadata failed due to database lookup error: %v", err)
return ctx
log.Debugf("Setting up city metadata failed due to database lookup error: %v", err)
} else {
g.setCityMetadata(ctx, data)
}
}
if g.db.provides&asn != 0 {
data, err := g.db.ASN(srcIP)
if err != nil {
log.Debugf("Setting up asn metadata failed due to database lookup error: %v", err)
} else {
g.setASNMetadata(ctx, data)
}
g.setCityMetadata(ctx, data)
}
return ctx
}