@@ -11,6 +11,7 @@ import (
11
11
"net"
12
12
"net/http"
13
13
"strconv"
14
+ "strings"
14
15
"time"
15
16
16
17
"github.com/m-lab/go/logx"
@@ -140,7 +141,11 @@ func AnnotateLegacy(date time.Time, ips []api.RequestData) (map[string]*api.GeoD
140
141
request := ips [i ]
141
142
metrics .TotalLookups .Inc ()
142
143
data := api.GeoData {}
143
- err := ann .Annotate (request .IP , & data )
144
+ requestIP := request .IP
145
+ if strings .HasPrefix (request .IP , "2002:" ) {
146
+ requestIP = Ip6to4 (request .IP )
147
+ }
148
+ err := ann .Annotate (requestIP , & data )
144
149
if err != nil {
145
150
// TODO need better error handling.
146
151
continue
@@ -156,6 +161,20 @@ func AnnotateLegacy(date time.Time, ips []api.RequestData) (map[string]*api.GeoD
156
161
157
162
var v2errorLogger = logx .NewLogEvery (nil , time .Second )
158
163
164
+ // Ip6to4 converts "2002:" ipv6 address back to ipv4.
165
+ func Ip6to4 (ipv6 string ) string {
166
+ ipnet := & net.IPNet {
167
+ Mask : net .CIDRMask (16 , 128 ),
168
+ IP : net .ParseIP ("2002::" ),
169
+ }
170
+ ip := net .ParseIP (ipv6 )
171
+ if ip == nil || ! ipnet .Contains (ip ) {
172
+ return ""
173
+ }
174
+
175
+ return fmt .Sprintf ("%d.%d.%d.%d" , ip [2 ], ip [3 ], ip [4 ], ip [5 ])
176
+ }
177
+
159
178
// AnnotateV2 finds an appropriate Annotator based on the requested Date, and creates a
160
179
// response with annotations for all parseable IPs.
161
180
func AnnotateV2 (date time.Time , ips []string , reqInfo string ) (v2.Response , error ) {
@@ -174,7 +193,12 @@ func AnnotateV2(date time.Time, ips []string, reqInfo string) (v2.Response, erro
174
193
metrics .TotalLookups .Inc ()
175
194
176
195
annotation := api.GeoData {}
177
- err := ann .Annotate (ips [i ], & annotation )
196
+ // special handling of "2002:" ip address
197
+ requestIP := ips [i ]
198
+ if strings .HasPrefix (ips [i ], "2002:" ) {
199
+ requestIP = Ip6to4 (ips [i ])
200
+ }
201
+ err := ann .Annotate (requestIP , & annotation )
178
202
if err != nil {
179
203
switch err .Error {
180
204
// TODO - enumerate interesting error types here...
@@ -331,7 +355,14 @@ func handleV2(w http.ResponseWriter, tStart time.Time, jsonBuffer []byte) {
331
355
response := v2.Response {}
332
356
333
357
if len (request .IPs ) > 0 {
334
- response , err = AnnotateV2 (request .Date , request .IPs , request .RequestInfo )
358
+ requestIPs := make ([]string , len (request .IPs ))
359
+ for i := range request .IPs {
360
+ requestIPs [i ] = request .IPs [i ]
361
+ if strings .HasPrefix (request .IPs [i ], "2002:" ) {
362
+ requestIPs [i ] = Ip6to4 (request .IPs [i ])
363
+ }
364
+ }
365
+ response , err = AnnotateV2 (request .Date , requestIPs , request .RequestInfo )
335
366
if checkError (err , w , request .RequestInfo , len (request .IPs ), "v2" , tStart ) {
336
367
return
337
368
}
@@ -410,7 +441,10 @@ func GetMetadataForSingleIP(request *api.RequestData) (result api.GeoData, err e
410
441
if err != nil {
411
442
return
412
443
}
413
-
414
- err = ann .Annotate (request .IP , & result )
444
+ requestIP := request .IP
445
+ if strings .HasPrefix (request .IP , "2002:" ) {
446
+ requestIP = Ip6to4 (request .IP )
447
+ }
448
+ err = ann .Annotate (requestIP , & result )
415
449
return
416
450
}
0 commit comments