diff --git a/go.mod b/go.mod index 934b6781c..2b0e0fd28 100644 --- a/go.mod +++ b/go.mod @@ -29,11 +29,12 @@ require ( github.com/opentracing/opentracing-go v1.2.0 github.com/openzipkin-contrib/zipkin-go-opentracing v0.5.0 github.com/openzipkin/zipkin-go v0.4.3 - github.com/oschwald/geoip2-golang v1.13.0 + github.com/oschwald/geoip2-golang/v2 v2.0.1 github.com/prometheus/client_golang v1.23.0 github.com/prometheus/client_model v0.6.2 github.com/prometheus/common v0.67.4 - github.com/quic-go/quic-go v0.57.1 + github.com/quic-go/quic-go v0.57.0 + github.com/stretchr/testify v1.11.1 go.etcd.io/etcd/api/v3 v3.6.6 go.etcd.io/etcd/client/v3 v3.6.6 go.uber.org/automaxprocs v1.6.0 @@ -49,8 +50,6 @@ require ( sigs.k8s.io/mcs-api v0.3.0 ) -require github.com/stretchr/testify v1.11.1 - require ( cloud.google.com/go/auth v0.17.0 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.8 // indirect @@ -142,7 +141,7 @@ require ( github.com/onsi/ginkgo/v2 v2.22.1 // indirect github.com/onsi/gomega v1.36.2 // indirect github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492 // indirect - github.com/oschwald/maxminddb-golang v1.13.0 // indirect + github.com/oschwald/maxminddb-golang/v2 v2.1.1 // indirect github.com/outcaste-io/ristretto v0.2.3 // indirect github.com/philhofer/fwd v1.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect diff --git a/go.sum b/go.sum index ff424f651..182870165 100644 --- a/go.sum +++ b/go.sum @@ -290,10 +290,10 @@ github.com/openzipkin-contrib/zipkin-go-opentracing v0.5.0 h1:uhcF5Jd7rP9DVEL10S github.com/openzipkin-contrib/zipkin-go-opentracing v0.5.0/go.mod h1:+oCZ5GXXr7KPI/DNOQORPTq5AWHfALJj9c72b0+YsEY= github.com/openzipkin/zipkin-go v0.4.3 h1:9EGwpqkgnwdEIJ+Od7QVSEIH+ocmm5nPat0G7sjsSdg= github.com/openzipkin/zipkin-go v0.4.3/go.mod h1:M9wCJZFWCo2RiY+o1eBCEMe0Dp2S5LDHcMZmk3RmK7c= -github.com/oschwald/geoip2-golang v1.13.0 h1:Q44/Ldc703pasJeP5V9+aFSZFmBN7DKHbNsSFzQATJI= -github.com/oschwald/geoip2-golang v1.13.0/go.mod h1:P9zG+54KPEFOliZ29i7SeYZ/GM6tfEL+rgSn03hYuUo= -github.com/oschwald/maxminddb-golang v1.13.0 h1:R8xBorY71s84yO06NgTmQvqvTvlS/bnYZrrWX1MElnU= -github.com/oschwald/maxminddb-golang v1.13.0/go.mod h1:BU0z8BfFVhi1LQaonTwwGQlsHUEu9pWNdMfmq4ztm0o= +github.com/oschwald/geoip2-golang/v2 v2.0.1 h1:YcYoG/L+gmSfk7AlToTmoL0JvblNyhGC8NyVhwDzzi8= +github.com/oschwald/geoip2-golang/v2 v2.0.1/go.mod h1:qdVmcPgrTJ4q2eP9tHq/yldMTdp2VMr33uVdFbHBiBc= +github.com/oschwald/maxminddb-golang/v2 v2.1.1 h1:lA8FH0oOrM4u7mLvowq8IT6a3Q/qEnqRzLQn9eH5ojc= +github.com/oschwald/maxminddb-golang/v2 v2.1.1/go.mod h1:PLdx6PR+siSIoXqqy7C7r3SB3KZnhxWr1Dp6g0Hacl8= github.com/outcaste-io/ristretto v0.2.3 h1:AK4zt/fJ76kjlYObOeNwh4T3asEuaCmp26pOvUOL9w0= github.com/outcaste-io/ristretto v0.2.3/go.mod h1:W8HywhmtlopSB1jeMg3JtdIhf+DYkLAr0VN/s4+MHac= github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM= @@ -321,8 +321,8 @@ github.com/puzpuzpuz/xsync/v3 v3.5.1 h1:GJYJZwO6IdxN/IKbneznS6yPkVC+c3zyY/j19c++ github.com/puzpuzpuz/xsync/v3 v3.5.1/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8= github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII= -github.com/quic-go/quic-go v0.57.1 h1:25KAAR9QR8KZrCZRThWMKVAwGoiHIrNbT72ULHTuI10= -github.com/quic-go/quic-go v0.57.1/go.mod h1:ly4QBAjHA2VhdnxhojRsCUOeJwKYg+taDlos92xb1+s= +github.com/quic-go/quic-go v0.57.0 h1:AsSSrrMs4qI/hLrKlTH/TGQeTMY0ib1pAOX7vA3AdqE= +github.com/quic-go/quic-go v0.57.0/go.mod h1:ly4QBAjHA2VhdnxhojRsCUOeJwKYg+taDlos92xb1+s= github.com/richardartoul/molecule v1.0.1-0.20240531184615-7ca0df43c0b3 h1:4+LEVOB87y175cLJC/mbsgKmoDOjrBldtXvioEy96WY= github.com/richardartoul/molecule v1.0.1-0.20240531184615-7ca0df43c0b3/go.mod h1:vl5+MqJ1nBINuSsUI2mGgH79UweUT/B5Fy8857PqyyI= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= diff --git a/plugin/geoip/README.md b/plugin/geoip/README.md index f2b38b00a..b6d593b4a 100644 --- a/plugin/geoip/README.md +++ b/plugin/geoip/README.md @@ -156,3 +156,7 @@ A limited set of fields will be exported as labels, all values are stored using | NA | North America | | OC | Oceania | | SA | South America | + +## Notable changes + +- In CoreDNS v1.13.2, the `geoip` plugin was upgraded to use [`oschwald/geoip2-golang/v2`](https://github.com/oschwald/geoip2-golang/blob/main/MIGRATION.md), the Go library that reads and parses [`.mmdb`](https://maxmind.github.io/MaxMind-DB/) databases. It has a small, but possibly-breaking change, where the `Location.Latitude` and `Location.Longitude` structs changed from value types to pointers (`float64` → `*float64`). In `oschwald/geoip2-golang` v1, missing coordinates returned "0" (which is a [valid location](https://en.wikipedia.org/wiki/Null_Island)), and in v2 they now return an empty string "". diff --git a/plugin/geoip/asn.go b/plugin/geoip/asn.go index 9f1830a5d..184f68050 100644 --- a/plugin/geoip/asn.go +++ b/plugin/geoip/asn.go @@ -6,7 +6,7 @@ import ( "github.com/coredns/coredns/plugin/metadata" - "github.com/oschwald/geoip2-golang" + "github.com/oschwald/geoip2-golang/v2" ) func (g GeoIP) setASNMetadata(ctx context.Context, data *geoip2.ASN) { diff --git a/plugin/geoip/city.go b/plugin/geoip/city.go index 4ebeaf66c..628ddb534 100644 --- a/plugin/geoip/city.go +++ b/plugin/geoip/city.go @@ -7,27 +7,25 @@ import ( "github.com/coredns/coredns/plugin/metadata" - "github.com/oschwald/geoip2-golang" + "github.com/oschwald/geoip2-golang/v2" ) -const defaultLang = "en" - func (g GeoIP) setCityMetadata(ctx context.Context, data *geoip2.City) { // Set labels for city, country and continent names. - cityName := data.City.Names[defaultLang] + cityName := data.City.Names.English metadata.SetValueFunc(ctx, pluginName+"/city/name", func() string { return cityName }) - countryName := data.Country.Names[defaultLang] + countryName := data.Country.Names.English metadata.SetValueFunc(ctx, pluginName+"/country/name", func() string { return countryName }) - continentName := data.Continent.Names[defaultLang] + continentName := data.Continent.Names.English metadata.SetValueFunc(ctx, pluginName+"/continent/name", func() string { return continentName }) - countryCode := data.Country.IsoCode + countryCode := data.Country.ISOCode metadata.SetValueFunc(ctx, pluginName+"/country/code", func() string { return countryCode }) @@ -37,7 +35,7 @@ func (g GeoIP) setCityMetadata(ctx context.Context, data *geoip2.City) { // a comma separated string, with the exact values provided by the database, even if those were empty strings. subdivisionCodes := make([]string, 0, len(data.Subdivisions)) for _, sub := range data.Subdivisions { - subdivisionCodes = append(subdivisionCodes, sub.IsoCode) + subdivisionCodes = append(subdivisionCodes, sub.ISOCode) } metadata.SetValueFunc(ctx, pluginName+"/subdivisions/code", func() string { return strings.Join(subdivisionCodes, ",") @@ -52,11 +50,17 @@ func (g GeoIP) setCityMetadata(ctx context.Context, data *geoip2.City) { return continentCode }) - latitude := strconv.FormatFloat(data.Location.Latitude, 'f', -1, 64) + var latitude string + if data.Location.Latitude != nil { + latitude = strconv.FormatFloat(*data.Location.Latitude, 'f', -1, 64) + } metadata.SetValueFunc(ctx, pluginName+"/latitude", func() string { return latitude }) - longitude := strconv.FormatFloat(data.Location.Longitude, 'f', -1, 64) + var longitude string + if data.Location.Longitude != nil { + longitude = strconv.FormatFloat(*data.Location.Longitude, 'f', -1, 64) + } metadata.SetValueFunc(ctx, pluginName+"/longitude", func() string { return longitude }) diff --git a/plugin/geoip/geoip.go b/plugin/geoip/geoip.go index b817c3522..85bf8f273 100644 --- a/plugin/geoip/geoip.go +++ b/plugin/geoip/geoip.go @@ -4,7 +4,7 @@ package geoip import ( "context" "fmt" - "net" + "net/netip" "path/filepath" "github.com/coredns/coredns/plugin" @@ -12,7 +12,7 @@ import ( "github.com/coredns/coredns/request" "github.com/miekg/dns" - "github.com/oschwald/geoip2-golang" + "github.com/oschwald/geoip2-golang/v2" ) var log = clog.NewWithPlugin(pluginName) @@ -37,7 +37,7 @@ const ( asn ) -var probingIP = net.ParseIP("127.0.0.1") +var probingIP = netip.MustParseAddr("127.0.0.1") func newGeoIP(dbPath string, edns0 bool) (*GeoIP, error) { reader, err := geoip2.Open(dbPath) @@ -80,13 +80,22 @@ func (g GeoIP) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) ( // Metadata implements the metadata.Provider Interface in the metadata plugin, and is used to store // the data associated with the source IP of every request. func (g GeoIP) Metadata(ctx context.Context, state request.Request) context.Context { - srcIP := net.ParseIP(state.IP()) + srcIP, err := netip.ParseAddr(state.IP()) + if err != nil { + log.Debugf("Failed to parse source IP %q: %v", state.IP(), err) + return ctx + } if g.edns0 { if o := state.Req.IsEdns0(); o != nil { for _, s := range o.Option { if e, ok := s.(*dns.EDNS0_SUBNET); ok { - srcIP = e.Address + // e.Address is still a net.IP type + if addr, ok := netip.AddrFromSlice(e.Address); ok { + srcIP = addr + } else { + log.Debugf("Failed to parse EDNS0 subnet address %v", e.Address) + } break } } diff --git a/plugin/geoip/setup_test.go b/plugin/geoip/setup_test.go index ba4848620..c21eea246 100644 --- a/plugin/geoip/setup_test.go +++ b/plugin/geoip/setup_test.go @@ -2,7 +2,6 @@ package geoip import ( "fmt" - "net" "path/filepath" "strings" "testing" @@ -19,7 +18,7 @@ var ( ) func TestProbingIP(t *testing.T) { - if probingIP == nil { + if !probingIP.IsValid() { t.Fatalf("Invalid probing IP: %q", probingIP) } } @@ -96,19 +95,4 @@ func TestGeoIPParse(t *testing.T) { t.Errorf("Test %d: expected db type %d not found, database file provides %d", i, test.expectedDBType, geoIP.db.provides) } } - - // Set nil probingIP to test unexpected validate error() - defer func(ip net.IP) { probingIP = ip }(probingIP) - probingIP = nil - - c = caddy.NewTestController("dns", fmt.Sprintf("%s %s\n", pluginName, cityDBPath)) - _, err := geoipParse(c) - if err != nil { - expectedErr := "unexpected failure looking up database" - if !strings.Contains(err.Error(), expectedErr) { - t.Errorf("expected error to contain: %s", expectedErr) - } - } else { - t.Errorf("with a nil probingIP test is expected to fail") - } }