| 269 | } |
| 270 | |
| 271 | func (e ExtResolver) AuthLookupIPAddr(ctx context.Context, host string) (ad bool, addrs []net.IPAddr, err error) { |
| 272 | // First, query IPv6. |
| 273 | msg := new(dns.Msg) |
| 274 | msg.SetQuestion(dns.Fqdn(host), dns.TypeAAAA) |
| 275 | msg.SetEdns0(4096, false) |
| 276 | msg.AuthenticatedData = true |
| 277 | |
| 278 | resp, err := e.exchange(ctx, msg) |
| 279 | aaaaFailed := false |
| 280 | var ( |
| 281 | v6ad bool |
| 282 | v6addrs []net.IPAddr |
| 283 | ) |
| 284 | if err != nil { |
| 285 | // Disregard the error for AAAA lookups. |
| 286 | aaaaFailed = true |
| 287 | log.DefaultLogger.Error("Network I/O error during AAAA lookup", err, "host", host) |
| 288 | } else { |
| 289 | v6addrs = make([]net.IPAddr, 0, len(resp.Answer)) |
| 290 | v6ad = resp.AuthenticatedData |
| 291 | for _, rr := range resp.Answer { |
| 292 | aaaaRR, ok := rr.(*dns.AAAA) |
| 293 | if !ok { |
| 294 | continue |
| 295 | } |
| 296 | v6addrs = append(v6addrs, net.IPAddr{IP: aaaaRR.AAAA}) |
| 297 | } |
| 298 | } |
| 299 | |
| 300 | // Then repeat query with IPv4. |
| 301 | msg = new(dns.Msg) |
| 302 | msg.SetQuestion(dns.Fqdn(host), dns.TypeA) |
| 303 | msg.SetEdns0(4096, false) |
| 304 | msg.AuthenticatedData = true |
| 305 | |
| 306 | resp, err = e.exchange(ctx, msg) |
| 307 | var ( |
| 308 | v4ad bool |
| 309 | v4addrs []net.IPAddr |
| 310 | ) |
| 311 | if err != nil { |
| 312 | if aaaaFailed { |
| 313 | return false, nil, err |
| 314 | } |
| 315 | // Disregard A lookup error if AAAA succeeded. |
| 316 | log.DefaultLogger.Error("Network I/O error during A lookup, using AAAA records", err, "host", host) |
| 317 | } else { |
| 318 | v4ad = resp.AuthenticatedData |
| 319 | v4addrs = make([]net.IPAddr, 0, len(resp.Answer)) |
| 320 | for _, rr := range resp.Answer { |
| 321 | aRR, ok := rr.(*dns.A) |
| 322 | if !ok { |
| 323 | continue |
| 324 | } |
| 325 | v4addrs = append(v4addrs, net.IPAddr{IP: aRR.A}) |
| 326 | } |
| 327 | } |
| 328 | |