///////////////////////////////////////////////////////
| 436 | { |
| 437 | //////////////////////////////////////////////////////////// |
| 438 | std::optional<std::vector<IpAddress>> Dns::resolve(const String& hostname, |
| 439 | const std::vector<IpAddress>& servers, |
| 440 | std::optional<Time> timeout) |
| 441 | { |
| 442 | std::vector<IpAddress> addresses; |
| 443 | |
| 444 | if (hostname.isEmpty()) |
| 445 | return std::nullopt; |
| 446 | |
| 447 | // Check if the hostname is actually the string representation of an IP address |
| 448 | if (const auto address = IpAddress::fromString(hostname.toAnsiString()); address) |
| 449 | { |
| 450 | addresses.emplace_back(*address); |
| 451 | return addresses; |
| 452 | } |
| 453 | |
| 454 | // Not a string representation of an IP address, do a full lookup |
| 455 | |
| 456 | auto encoded = encodeHostname(hostname); |
| 457 | |
| 458 | if (!servers.empty()) |
| 459 | { |
| 460 | // Use user provided servers |
| 461 | auto querySuccess = false; |
| 462 | |
| 463 | queryDns( |
| 464 | [&](const char* data, std::size_t length, const char*, std::uint16_t responseType, std::uint16_t responseClass) |
| 465 | { |
| 466 | querySuccess = true; |
| 467 | |
| 468 | // AAAA, IN |
| 469 | if ((responseType != 28) || (responseClass != 1)) |
| 470 | return; |
| 471 | |
| 472 | if (length == 16) |
| 473 | { |
| 474 | std::array<std::uint8_t, 16> bytes{}; |
| 475 | std::memcpy(bytes.data(), data, 16); |
| 476 | if (std::any_of(bytes.begin(), bytes.end(), [](auto b) { return b != 0; })) |
| 477 | addresses.emplace_back(bytes); |
| 478 | } |
| 479 | }, |
| 480 | timeout, |
| 481 | {{servers, |
| 482 | 28, // AAAA |
| 483 | 1, // IN |
| 484 | encoded}}); |
| 485 | |
| 486 | queryDns( |
| 487 | [&](const char* data, std::size_t length, const char*, std::uint16_t responseType, std::uint16_t responseClass) |
| 488 | { |
| 489 | querySuccess = true; |
| 490 | |
| 491 | // A, IN |
| 492 | if ((responseType != 1) || (responseClass != 1)) |
| 493 | return; |
| 494 | |
| 495 | if (const auto bytes = readU32(data, data + length); bytes != 0) |
nothing calls this directly
no test coverage detected