///////////////////////////////////////////////////////
| 635 | |
| 636 | //////////////////////////////////////////////////////////// |
| 637 | std::vector<Dns::MxRecord> Dns::queryMx(const String& hostname, const std::vector<IpAddress>& servers, std::optional<Time> timeout) |
| 638 | { |
| 639 | std::vector<MxRecord> mxRecords; |
| 640 | |
| 641 | if (hostname.isEmpty()) |
| 642 | return mxRecords; |
| 643 | |
| 644 | auto encoded = encodeHostname(hostname); |
| 645 | |
| 646 | // On Android the libc provided resolv API doesn't work, we will have to do the work ourselves |
| 647 | #if defined(SFML_SYSTEM_ANDROID) |
| 648 | const auto& serversToQuery = servers.empty() ? getAndroidServers() : servers; |
| 649 | #else |
| 650 | const auto& serversToQuery = servers; |
| 651 | #endif |
| 652 | |
| 653 | if (!serversToQuery.empty()) |
| 654 | { |
| 655 | queryDns( |
| 656 | [&](const char* data, std::size_t length, const char* messageBegin, std::uint16_t responseType, std::uint16_t responseClass) |
| 657 | { |
| 658 | // MX, IN |
| 659 | if ((responseType != 15) || (responseClass != 1)) |
| 660 | return; |
| 661 | |
| 662 | const auto preference = readU16(data, data + length); |
| 663 | auto exchange = readName(data, data + length, messageBegin); |
| 664 | |
| 665 | if (!exchange.empty()) |
| 666 | mxRecords.emplace_back(MxRecord{decodeHostname(exchange), preference}); |
| 667 | }, |
| 668 | timeout, |
| 669 | {{serversToQuery, |
| 670 | 15, // MX |
| 671 | 1, // IN |
| 672 | encoded}}); |
| 673 | |
| 674 | return mxRecords; |
| 675 | } |
| 676 | |
| 677 | #if defined(SFML_SYSTEM_WINDOWS) |
| 678 | const auto records = getRecords(encoded, DNS_TYPE_MX); |
| 679 | for (const auto* ptr = records.get(); ptr; ptr = ptr->pNext) |
| 680 | { |
| 681 | if ((ptr->wType == DNS_TYPE_MX) && (ptr->Data.MX.pNameExchange != nullptr)) |
| 682 | { |
| 683 | mxRecords.emplace_back( |
| 684 | MxRecord{decodeHostname(sf::String(ptr->Data.MX.pNameExchange).toAnsiString()), ptr->Data.MX.wPreference}); |
| 685 | } |
| 686 | } |
| 687 | #else |
| 688 | getRecords(encoded, |
| 689 | ns_t_mx, |
| 690 | [&mxRecords](const ns_msg& handle, const ns_rr& record) |
| 691 | { |
| 692 | const auto preference = static_cast<std::uint16_t>(ns_get16(ns_rr_rdata(record) + 0 * NS_INT16SZ)); |
| 693 | |
| 694 | std::array<char, NS_MAXCDNAME> exchange{}; |
nothing calls this directly
no test coverage detected