github.com/database64128/shadowsocks-go@v1.7.0/dns/dns.go (about) 1 package dns 2 3 import ( 4 "encoding/binary" 5 "errors" 6 "fmt" 7 "io" 8 "math" 9 "net" 10 "net/netip" 11 "os" 12 "sync" 13 "time" 14 15 "github.com/database64128/shadowsocks-go/conn" 16 "github.com/database64128/shadowsocks-go/zerocopy" 17 "go.uber.org/zap" 18 "golang.org/x/net/dns/dnsmessage" 19 ) 20 21 const ( 22 // maxDNSPacketSize is the maximum packet size to advertise in EDNS(0). 23 // We use the same value as Go itself. 24 maxDNSPacketSize = 1232 25 26 lookupTimeout = 20 * time.Second 27 ) 28 29 var ErrLookup = errors.New("name lookup failed") 30 31 // ResolverConfig configures a DNS resolver. 32 type ResolverConfig struct { 33 // Name is the resolver's name. 34 // The name must be unique among all resolvers. 35 Name string `json:"name"` 36 37 // AddrPort is the upstream server's address and port. 38 AddrPort netip.AddrPort `json:"addrPort"` 39 40 // TCPClientName is the name of the TCPClient to use. 41 // Leave empty to disable TCP. 42 TCPClientName string `json:"tcpClientName"` 43 44 // UDPClientName is the name of the UDPClient to use. 45 // Leave empty to disable UDP. 46 UDPClientName string `json:"udpClientName"` 47 } 48 49 func (rc *ResolverConfig) Resolver(tcpClientMap map[string]zerocopy.TCPClient, udpClientMap map[string]zerocopy.UDPClient, logger *zap.Logger) (*Resolver, error) { 50 var ( 51 tcpClient zerocopy.TCPClient 52 udpClient zerocopy.UDPClient 53 ) 54 55 if rc.TCPClientName != "" { 56 tcpClient = tcpClientMap[rc.TCPClientName] 57 if tcpClient == nil { 58 return nil, fmt.Errorf("unknown TCP client: %s", rc.TCPClientName) 59 } 60 } 61 62 if rc.UDPClientName != "" { 63 udpClient = udpClientMap[rc.UDPClientName] 64 if udpClient == nil { 65 return nil, fmt.Errorf("unknown UDP client: %s", rc.UDPClientName) 66 } 67 } 68 69 return NewResolver(rc.Name, rc.AddrPort, tcpClient, udpClient, logger), nil 70 } 71 72 // Result represents the result of name resolution. 73 type Result struct { 74 IPv4 []netip.Addr 75 IPv6 []netip.Addr 76 77 // TTL is the minimum TTL of A and AAAA RRs. 78 TTL time.Time 79 } 80 81 type Resolver struct { 82 // name stores the resolver's name to make its log messages more useful. 83 name string 84 85 // mu protects the DNS cache map. 86 mu sync.RWMutex 87 88 // cache is the DNS cache map. 89 cache map[string]Result 90 91 // serverAddr is the upstream server's address and port. 92 serverAddr conn.Addr 93 94 // serverAddrPort is the upstream server's address and port. 95 serverAddrPort netip.AddrPort 96 97 // tcpClient is the TCPClient to use for sending queries and receiving replies. 98 tcpClient zerocopy.TCPClient 99 100 // udpClient is the UDPClient to use for sending queries and receiving replies. 101 udpClient zerocopy.UDPClient 102 103 // logger is the shared logger instance. 104 logger *zap.Logger 105 } 106 107 func NewResolver(name string, serverAddrPort netip.AddrPort, tcpClient zerocopy.TCPClient, udpClient zerocopy.UDPClient, logger *zap.Logger) *Resolver { 108 return &Resolver{ 109 name: name, 110 cache: make(map[string]Result), 111 serverAddr: conn.AddrFromIPPort(serverAddrPort), 112 serverAddrPort: serverAddrPort, 113 tcpClient: tcpClient, 114 udpClient: udpClient, 115 logger: logger, 116 } 117 } 118 119 func (r *Resolver) Lookup(name string) (Result, error) { 120 // Lookup cache first. 121 r.mu.RLock() 122 result, ok := r.cache[name] 123 r.mu.RUnlock() 124 125 if ok && result.TTL.After(time.Now()) { 126 if ce := r.logger.Check(zap.DebugLevel, "DNS lookup got result from cache"); ce != nil { 127 ce.Write( 128 zap.String("resolver", r.name), 129 zap.String("name", name), 130 zap.Time("ttl", result.TTL), 131 zap.Stringers("v4", result.IPv4), 132 zap.Stringers("v6", result.IPv6), 133 ) 134 } 135 return result, nil 136 } 137 138 // Send queries to upstream server. 139 return r.sendQueries(name) 140 } 141 142 func (r *Resolver) sendQueries(nameString string) (result Result, err error) { 143 name, err := dnsmessage.NewName(nameString + ".") 144 if err != nil { 145 return 146 } 147 148 var ( 149 rh dnsmessage.ResourceHeader 150 rb dnsmessage.OPTResource 151 ) 152 153 err = rh.SetEDNS0(maxDNSPacketSize, dnsmessage.RCodeSuccess, false) 154 if err != nil { 155 return 156 } 157 158 qBuf := make([]byte, 2+512+2+512) 159 160 q4 := dnsmessage.Message{ 161 Header: dnsmessage.Header{ 162 ID: 4, 163 RecursionDesired: true, 164 }, 165 Questions: []dnsmessage.Question{ 166 { 167 Name: name, 168 Type: dnsmessage.TypeA, 169 Class: dnsmessage.ClassINET, 170 }, 171 }, 172 Additionals: []dnsmessage.Resource{ 173 { 174 Header: rh, 175 Body: &rb, 176 }, 177 }, 178 } 179 q4Pkt := qBuf[2:2] 180 q4Pkt, err = q4.AppendPack(q4Pkt) 181 if err != nil { 182 return 183 } 184 q4PktEnd := 2 + len(q4Pkt) 185 186 q6 := dnsmessage.Message{ 187 Header: dnsmessage.Header{ 188 ID: 6, 189 RecursionDesired: true, 190 }, 191 Questions: []dnsmessage.Question{ 192 { 193 Name: name, 194 Type: dnsmessage.TypeAAAA, 195 Class: dnsmessage.ClassINET, 196 }, 197 }, 198 Additionals: []dnsmessage.Resource{ 199 { 200 Header: rh, 201 Body: &rb, 202 }, 203 }, 204 } 205 q6PktStart := q4PktEnd + 2 206 q6Pkt := qBuf[q6PktStart:q6PktStart] 207 q6Pkt, err = q6.AppendPack(q6Pkt) 208 if err != nil { 209 return 210 } 211 q6PktEnd := q6PktStart + len(q6Pkt) 212 213 var ( 214 minTTL uint32 215 handled bool 216 ) 217 218 // Try UDP first if available. 219 if r.udpClient != nil { 220 result, minTTL, handled = r.sendQueriesUDP(nameString, q4Pkt, q6Pkt) 221 222 if ce := r.logger.Check(zap.DebugLevel, "DNS lookup sent queries via UDP"); ce != nil { 223 ce.Write( 224 zap.String("resolver", r.name), 225 zap.String("name", nameString), 226 zap.Uint32("minTTL", minTTL), 227 zap.Bool("handled", handled), 228 zap.Stringers("v4", result.IPv4), 229 zap.Stringers("v6", result.IPv6), 230 ) 231 } 232 } 233 234 // Fallback to TCP if UDP failed or is unavailable. 235 if !handled && r.tcpClient != nil { 236 // Write length fields. 237 q4LenBuf := qBuf[:2] 238 q6LenBuf := qBuf[q4PktEnd:q6PktStart] 239 binary.BigEndian.PutUint16(q4LenBuf, uint16(len(q4Pkt))) 240 binary.BigEndian.PutUint16(q6LenBuf, uint16(len(q6Pkt))) 241 242 result, minTTL, handled = r.sendQueriesTCP(nameString, qBuf[:q6PktEnd]) 243 244 if ce := r.logger.Check(zap.DebugLevel, "DNS lookup sent queries via TCP"); ce != nil { 245 ce.Write( 246 zap.String("resolver", r.name), 247 zap.String("name", nameString), 248 zap.Uint32("minTTL", minTTL), 249 zap.Bool("handled", handled), 250 zap.Stringers("v4", result.IPv4), 251 zap.Stringers("v6", result.IPv6), 252 ) 253 } 254 } 255 256 if !handled { 257 err = ErrLookup 258 return 259 } 260 261 // Add result to cache if minTTL != 0. 262 if minTTL != 0 { 263 result.TTL = time.Now().Add(time.Duration(minTTL) * time.Second) 264 265 r.mu.Lock() 266 r.cache[nameString] = result 267 r.mu.Unlock() 268 } 269 270 return 271 } 272 273 // sendQueriesUDP sends queries using the resolver's UDP client and returns the result, a detached minTTL, 274 // and whether the lookup was successful. 275 // 276 // It's the caller's responsibility to examine the minTTL and decide whether to cache the result. 277 func (r *Resolver) sendQueriesUDP(nameString string, q4Pkt, q6Pkt []byte) (result Result, minTTL uint32, handled bool) { 278 // Create client session. 279 clientInfo, packer, unpacker, err := r.udpClient.NewSession() 280 if err != nil { 281 r.logger.Warn("Failed to create new UDP client session", 282 zap.String("resolver", r.name), 283 zap.Error(err), 284 ) 285 return 286 } 287 288 packerInfo := packer.ClientPackerInfo() 289 290 // Prepare UDP socket. 291 udpConn, err := conn.ListenUDP(clientInfo.ListenConfig, "udp", "") 292 if err != nil { 293 r.logger.Warn("Failed to create UDP socket for DNS lookup", 294 zap.String("resolver", r.name), 295 zap.Error(err), 296 ) 297 return 298 } 299 defer udpConn.Close() 300 301 // Set read deadline. 302 err = udpConn.SetReadDeadline(time.Now().Add(lookupTimeout)) 303 if err != nil { 304 r.logger.Warn("Failed to set read deadline", 305 zap.String("resolver", r.name), 306 zap.Error(err), 307 ) 308 return 309 } 310 311 // Spin up senders. 312 // Each sender will keep sending at 2s intervals until the stop signal 313 // is received or after 10 iterations. 314 sendFunc := func(pkt []byte, ctrlCh <-chan struct{}) { 315 b := make([]byte, packerInfo.Headroom.Front+len(pkt)+packerInfo.Headroom.Rear) 316 317 write: 318 for i := 0; i < 10; i++ { 319 copy(b[packerInfo.Headroom.Front:], pkt) 320 destAddrPort, packetStart, packetLength, err := packer.PackInPlace(b, r.serverAddr, packerInfo.Headroom.Front, len(pkt)) 321 if err != nil { 322 r.logger.Warn("Failed to pack packet", 323 zap.String("resolver", r.name), 324 zap.String("name", nameString), 325 zap.Stringer("serverAddrPort", r.serverAddrPort), 326 zap.Error(err), 327 ) 328 goto cleanup 329 } 330 331 _, err = udpConn.WriteToUDPAddrPort(b[packetStart:packetStart+packetLength], destAddrPort) 332 if err != nil { 333 r.logger.Warn("Failed to write query", 334 zap.String("resolver", r.name), 335 zap.String("name", nameString), 336 zap.Stringer("serverAddrPort", r.serverAddrPort), 337 zap.Stringer("destAddrPort", destAddrPort), 338 zap.Error(err), 339 ) 340 goto cleanup 341 } 342 343 time.Sleep(2 * time.Second) 344 345 select { 346 case <-ctrlCh: 347 break write 348 default: 349 continue write 350 } 351 352 cleanup: 353 err = udpConn.SetReadDeadline(time.Now()) 354 if err != nil { 355 r.logger.Warn("Failed to set read deadline", 356 zap.String("resolver", r.name), 357 zap.String("name", nameString), 358 zap.Stringer("serverAddrPort", r.serverAddrPort), 359 zap.Stringer("destAddrPort", destAddrPort), 360 zap.Error(err), 361 ) 362 } 363 break 364 } 365 } 366 367 ctrlCh4 := make(chan struct{}, 1) 368 ctrlCh6 := make(chan struct{}, 1) 369 go sendFunc(q4Pkt, ctrlCh4) 370 go sendFunc(q6Pkt, ctrlCh6) 371 372 // Receive replies. 373 minTTL = math.MaxUint32 374 recvBuf := make([]byte, clientInfo.MaxPacketSize) 375 376 var ( 377 v4done, v6done bool 378 parser dnsmessage.Parser 379 ) 380 381 read: 382 for { 383 n, _, flags, packetSourceAddress, err := udpConn.ReadMsgUDPAddrPort(recvBuf, nil) 384 if err != nil { 385 if errors.Is(err, os.ErrDeadlineExceeded) { 386 r.logger.Warn("DNS lookup via UDP timed out", 387 zap.String("resolver", r.name), 388 zap.String("name", nameString), 389 zap.Stringer("serverAddrPort", r.serverAddrPort), 390 ) 391 break 392 } 393 r.logger.Warn("Failed to read query response", 394 zap.String("resolver", r.name), 395 zap.String("name", nameString), 396 zap.Stringer("serverAddrPort", r.serverAddrPort), 397 zap.Stringer("packetSourceAddress", packetSourceAddress), 398 zap.Int("packetLength", n), 399 zap.Error(err), 400 ) 401 continue 402 } 403 if err = conn.ParseFlagsForError(flags); err != nil { 404 r.logger.Warn("Failed to read query response", 405 zap.String("resolver", r.name), 406 zap.String("name", nameString), 407 zap.Stringer("serverAddrPort", r.serverAddrPort), 408 zap.Stringer("packetSourceAddress", packetSourceAddress), 409 zap.Int("packetLength", n), 410 zap.Error(err), 411 ) 412 continue 413 } 414 415 payloadSourceAddrPort, payloadStart, payloadLength, err := unpacker.UnpackInPlace(recvBuf, packetSourceAddress, 0, n) 416 if err != nil { 417 r.logger.Warn("Failed to unpack packet", 418 zap.String("resolver", r.name), 419 zap.String("name", nameString), 420 zap.Stringer("serverAddrPort", r.serverAddrPort), 421 zap.Stringer("packetSourceAddress", packetSourceAddress), 422 zap.Int("packetLength", n), 423 zap.Error(err), 424 ) 425 continue 426 } 427 if !conn.AddrPortMappedEqual(payloadSourceAddrPort, r.serverAddrPort) { 428 r.logger.Warn("Ignoring packet from unknown server", 429 zap.String("resolver", r.name), 430 zap.String("name", nameString), 431 zap.Stringer("serverAddrPort", r.serverAddrPort), 432 zap.Stringer("payloadSourceAddrPort", payloadSourceAddrPort), 433 ) 434 continue 435 } 436 payload := recvBuf[payloadStart : payloadStart+payloadLength] 437 438 // Parse header. 439 header, err := parser.Start(payload) 440 if err != nil { 441 r.logger.Warn("Failed to parse query response header", 442 zap.String("resolver", r.name), 443 zap.String("name", nameString), 444 zap.Stringer("serverAddrPort", r.serverAddrPort), 445 zap.Error(err), 446 ) 447 break 448 } 449 450 // Check transaction ID. 451 switch header.ID { 452 case 4: 453 if v4done { 454 continue 455 } 456 case 6: 457 if v6done { 458 continue 459 } 460 default: 461 r.logger.Warn("Unexpected transaction ID", 462 zap.String("resolver", r.name), 463 zap.String("name", nameString), 464 zap.Stringer("serverAddrPort", r.serverAddrPort), 465 zap.Uint16("transactionID", header.ID), 466 ) 467 break read 468 } 469 470 // Check response bit. 471 if !header.Response { 472 r.logger.Warn("Received non-response reply", 473 zap.String("resolver", r.name), 474 zap.String("name", nameString), 475 zap.Stringer("serverAddrPort", r.serverAddrPort), 476 ) 477 break 478 } 479 480 // Check truncated bit. 481 if header.Truncated { 482 r.logger.Warn("Received truncated reply", 483 zap.String("resolver", r.name), 484 zap.String("name", nameString), 485 zap.Stringer("serverAddrPort", r.serverAddrPort), 486 ) 487 break 488 } 489 490 // Check RCode. 491 if header.RCode != dnsmessage.RCodeSuccess { 492 r.logger.Warn("DNS failure", 493 zap.String("resolver", r.name), 494 zap.String("name", nameString), 495 zap.Stringer("serverAddrPort", r.serverAddrPort), 496 zap.Stringer("RCode", header.RCode), 497 ) 498 break 499 } 500 501 // Skip questions. 502 err = parser.SkipAllQuestions() 503 if err != nil { 504 r.logger.Warn("Failed to skip questions", 505 zap.String("resolver", r.name), 506 zap.String("name", nameString), 507 zap.Stringer("serverAddrPort", r.serverAddrPort), 508 zap.Error(err), 509 ) 510 break 511 } 512 513 // Parse answers and add to result. 514 for { 515 answerHeader, err := parser.AnswerHeader() 516 if err != nil { 517 if err == dnsmessage.ErrSectionDone { 518 break 519 } 520 r.logger.Warn("Failed to parse answer header", 521 zap.String("resolver", r.name), 522 zap.String("name", nameString), 523 zap.Stringer("serverAddrPort", r.serverAddrPort), 524 zap.Error(err), 525 ) 526 break read 527 } 528 529 // Set minimum TTL. 530 if answerHeader.TTL < minTTL { 531 if ce := r.logger.Check(zap.DebugLevel, "Updating minimum TTL"); ce != nil { 532 ce.Write( 533 zap.String("resolver", r.name), 534 zap.String("name", nameString), 535 zap.Stringer("serverAddrPort", r.serverAddrPort), 536 zap.Stringer("answerType", answerHeader.Type), 537 zap.Uint32("oldMinTTL", minTTL), 538 zap.Uint32("newMinTTL", answerHeader.TTL), 539 ) 540 } 541 minTTL = answerHeader.TTL 542 } 543 544 // Skip non-A/AAAA RRs. 545 switch answerHeader.Type { 546 case dnsmessage.TypeA: 547 arr, err := parser.AResource() 548 if err != nil { 549 r.logger.Warn("Failed to parse A resource", 550 zap.String("resolver", r.name), 551 zap.String("name", nameString), 552 zap.Stringer("serverAddrPort", r.serverAddrPort), 553 zap.Error(err), 554 ) 555 break read 556 } 557 558 addr4 := netip.AddrFrom4(arr.A) 559 result.IPv4 = append(result.IPv4, addr4) 560 561 if ce := r.logger.Check(zap.DebugLevel, "Processing A RR"); ce != nil { 562 ce.Write( 563 zap.String("resolver", r.name), 564 zap.String("name", nameString), 565 zap.Stringer("serverAddrPort", r.serverAddrPort), 566 zap.Stringer("addr", addr4), 567 ) 568 } 569 570 case dnsmessage.TypeAAAA: 571 aaaarr, err := parser.AAAAResource() 572 if err != nil { 573 r.logger.Warn("Failed to parse AAAA resource", 574 zap.String("resolver", r.name), 575 zap.String("name", nameString), 576 zap.Stringer("serverAddrPort", r.serverAddrPort), 577 zap.Error(err), 578 ) 579 break read 580 } 581 582 addr6 := netip.AddrFrom16(aaaarr.AAAA) 583 result.IPv6 = append(result.IPv6, addr6) 584 585 if ce := r.logger.Check(zap.DebugLevel, "Processing AAAA RR"); ce != nil { 586 ce.Write( 587 zap.String("resolver", r.name), 588 zap.String("name", nameString), 589 zap.Stringer("serverAddrPort", r.serverAddrPort), 590 zap.Stringer("addr", addr6), 591 ) 592 } 593 594 default: 595 err = parser.SkipAnswer() 596 if err != nil { 597 r.logger.Warn("Failed to skip answer", 598 zap.String("resolver", r.name), 599 zap.String("name", nameString), 600 zap.Stringer("serverAddrPort", r.serverAddrPort), 601 zap.Stringer("answerType", answerHeader.Type), 602 zap.Error(err), 603 ) 604 break read 605 } 606 } 607 } 608 609 // Stop corresponding sender and mark as done. 610 switch header.ID { 611 case 4: 612 ctrlCh4 <- struct{}{} 613 close(ctrlCh4) 614 v4done = true 615 case 6: 616 ctrlCh6 <- struct{}{} 617 close(ctrlCh6) 618 v6done = true 619 } 620 621 // Break out of loop if both v4 and v6 are done. 622 if v4done && v6done { 623 break 624 } 625 } 626 627 // Clean up in case of error. 628 if !v4done { 629 ctrlCh4 <- struct{}{} 630 close(ctrlCh4) 631 } 632 if !v6done { 633 ctrlCh6 <- struct{}{} 634 close(ctrlCh6) 635 } 636 637 handled = v4done && v6done 638 return 639 } 640 641 // sendQueriesTCP sends queries using the resolver's TCP client and returns the result, a detached minTTL, 642 // and whether the lookup was successful. 643 // 644 // It's the caller's responsibility to examine the minTTL and decide whether to cache the result. 645 func (r *Resolver) sendQueriesTCP(nameString string, queries []byte) (result Result, minTTL uint32, handled bool) { 646 // Write. 647 rawRW, rw, err := r.tcpClient.Dial(r.serverAddr, queries) 648 if err != nil { 649 r.logger.Warn("Failed to dial DNS server", 650 zap.String("resolver", r.name), 651 zap.String("name", nameString), 652 zap.Stringer("serverAddrPort", r.serverAddrPort), 653 zap.Error(err), 654 ) 655 return 656 } 657 defer rawRW.Close() 658 659 // Set read deadline. 660 if tc, ok := rawRW.(*net.TCPConn); ok { 661 if err = tc.SetReadDeadline(time.Now().Add(lookupTimeout)); err != nil { 662 r.logger.Warn("Failed to set read deadline", 663 zap.String("resolver", r.name), 664 zap.String("name", nameString), 665 zap.Stringer("serverAddrPort", r.serverAddrPort), 666 zap.Error(err), 667 ) 668 return 669 } 670 } 671 672 // Read. 673 crw := zerocopy.NewCopyReadWriter(rw) 674 lengthBuf := make([]byte, 2) 675 minTTL = math.MaxUint32 676 677 var ( 678 v4done, v6done bool 679 parser dnsmessage.Parser 680 ) 681 682 for i := 0; i < 2; i++ { 683 // Read length field. 684 _, err = io.ReadFull(crw, lengthBuf) 685 if err != nil { 686 r.logger.Warn("Failed to read DNS response length", 687 zap.String("resolver", r.name), 688 zap.String("name", nameString), 689 zap.Stringer("serverAddrPort", r.serverAddrPort), 690 zap.Error(err), 691 ) 692 return 693 } 694 695 msgLen := binary.BigEndian.Uint16(lengthBuf) 696 if msgLen == 0 { 697 r.logger.Warn("DNS response length is zero", 698 zap.String("resolver", r.name), 699 zap.String("name", nameString), 700 zap.Stringer("serverAddrPort", r.serverAddrPort), 701 ) 702 return 703 } 704 705 // Read message. 706 msg := make([]byte, msgLen) 707 _, err = io.ReadFull(crw, msg) 708 if err != nil { 709 r.logger.Warn("Failed to read DNS response", 710 zap.String("resolver", r.name), 711 zap.String("name", nameString), 712 zap.Stringer("serverAddrPort", r.serverAddrPort), 713 zap.Error(err), 714 ) 715 return 716 } 717 718 // Parse header. 719 header, err := parser.Start(msg) 720 if err != nil { 721 r.logger.Warn("Failed to parse query response header", 722 zap.String("resolver", r.name), 723 zap.String("name", nameString), 724 zap.Stringer("serverAddrPort", r.serverAddrPort), 725 zap.Error(err), 726 ) 727 return 728 } 729 730 // Check transaction ID. 731 switch header.ID { 732 case 4, 6: 733 default: 734 r.logger.Warn("Unexpected transaction ID", 735 zap.String("resolver", r.name), 736 zap.String("name", nameString), 737 zap.Stringer("serverAddrPort", r.serverAddrPort), 738 zap.Uint16("transactionID", header.ID), 739 ) 740 return 741 } 742 743 // Check response bit. 744 if !header.Response { 745 r.logger.Warn("Received non-response reply", 746 zap.String("resolver", r.name), 747 zap.String("name", nameString), 748 zap.Stringer("serverAddrPort", r.serverAddrPort), 749 ) 750 return 751 } 752 753 // Check RCode. 754 if header.RCode != dnsmessage.RCodeSuccess { 755 r.logger.Warn("DNS failure", 756 zap.String("resolver", r.name), 757 zap.String("name", nameString), 758 zap.Stringer("serverAddrPort", r.serverAddrPort), 759 zap.Stringer("RCode", header.RCode), 760 ) 761 return 762 } 763 764 // Skip questions. 765 err = parser.SkipAllQuestions() 766 if err != nil { 767 r.logger.Warn("Failed to skip questions", 768 zap.String("resolver", r.name), 769 zap.String("name", nameString), 770 zap.Stringer("serverAddrPort", r.serverAddrPort), 771 zap.Error(err), 772 ) 773 return 774 } 775 776 // Parse answers and add to result. 777 for { 778 answerHeader, err := parser.AnswerHeader() 779 if err != nil { 780 if err == dnsmessage.ErrSectionDone { 781 break 782 } 783 r.logger.Warn("Failed to parse answer header", 784 zap.String("resolver", r.name), 785 zap.String("name", nameString), 786 zap.Stringer("serverAddrPort", r.serverAddrPort), 787 zap.Error(err), 788 ) 789 return 790 } 791 792 // Set minimum TTL. 793 if answerHeader.TTL < minTTL { 794 if ce := r.logger.Check(zap.DebugLevel, "Updating minimum TTL"); ce != nil { 795 ce.Write( 796 zap.String("resolver", r.name), 797 zap.String("name", nameString), 798 zap.Stringer("serverAddrPort", r.serverAddrPort), 799 zap.Stringer("answerType", answerHeader.Type), 800 zap.Uint32("oldMinTTL", minTTL), 801 zap.Uint32("newMinTTL", answerHeader.TTL), 802 ) 803 } 804 minTTL = answerHeader.TTL 805 } 806 807 // Skip non-A/AAAA RRs. 808 switch answerHeader.Type { 809 case dnsmessage.TypeA: 810 arr, err := parser.AResource() 811 if err != nil { 812 r.logger.Warn("Failed to parse A resource", 813 zap.String("resolver", r.name), 814 zap.String("name", nameString), 815 zap.Stringer("serverAddrPort", r.serverAddrPort), 816 zap.Error(err), 817 ) 818 return 819 } 820 821 addr4 := netip.AddrFrom4(arr.A) 822 result.IPv4 = append(result.IPv4, addr4) 823 824 if ce := r.logger.Check(zap.DebugLevel, "Processing A RR"); ce != nil { 825 ce.Write( 826 zap.String("resolver", r.name), 827 zap.String("name", nameString), 828 zap.Stringer("serverAddrPort", r.serverAddrPort), 829 zap.Stringer("addr", addr4), 830 ) 831 } 832 833 case dnsmessage.TypeAAAA: 834 aaaarr, err := parser.AAAAResource() 835 if err != nil { 836 r.logger.Warn("Failed to parse AAAA resource", 837 zap.String("resolver", r.name), 838 zap.String("name", nameString), 839 zap.Stringer("serverAddrPort", r.serverAddrPort), 840 zap.Error(err), 841 ) 842 return 843 } 844 845 addr6 := netip.AddrFrom16(aaaarr.AAAA) 846 result.IPv6 = append(result.IPv6, addr6) 847 848 if ce := r.logger.Check(zap.DebugLevel, "Processing AAAA RR"); ce != nil { 849 ce.Write( 850 zap.String("resolver", r.name), 851 zap.String("name", nameString), 852 zap.Stringer("serverAddrPort", r.serverAddrPort), 853 zap.Stringer("addr", addr6), 854 ) 855 } 856 857 default: 858 err = parser.SkipAnswer() 859 if err != nil { 860 r.logger.Warn("Failed to skip answer", 861 zap.String("resolver", r.name), 862 zap.String("name", nameString), 863 zap.Stringer("serverAddrPort", r.serverAddrPort), 864 zap.Stringer("answerType", answerHeader.Type), 865 zap.Error(err), 866 ) 867 return 868 } 869 } 870 } 871 872 // Mark v4 or v6 as done. 873 switch header.ID { 874 case 4: 875 v4done = true 876 case 6: 877 v6done = true 878 } 879 } 880 881 handled = v4done && v6done 882 return 883 }