///////////////////////////////////////////////////////
| 712 | |
| 713 | //////////////////////////////////////////////////////////// |
| 714 | std::vector<Dns::SrvRecord> Dns::querySrv(const String& hostname, const std::vector<IpAddress>& servers, std::optional<Time> timeout) |
| 715 | { |
| 716 | std::vector<SrvRecord> srvRecords; |
| 717 | |
| 718 | if (hostname.isEmpty()) |
| 719 | return srvRecords; |
| 720 | |
| 721 | auto encoded = encodeHostname(hostname); |
| 722 | |
| 723 | // On Android the libc provided resolv API doesn't work, we will have to do the work ourselves |
| 724 | #if defined(SFML_SYSTEM_ANDROID) |
| 725 | const auto& serversToQuery = servers.empty() ? getAndroidServers() : servers; |
| 726 | #else |
| 727 | const auto& serversToQuery = servers; |
| 728 | #endif |
| 729 | |
| 730 | if (!serversToQuery.empty()) |
| 731 | { |
| 732 | queryDns( |
| 733 | [&](const char* data, std::size_t length, const char* messageBegin, std::uint16_t responseType, std::uint16_t responseClass) |
| 734 | { |
| 735 | // SRV, IN |
| 736 | if ((responseType != 33) || (responseClass != 1)) |
| 737 | return; |
| 738 | |
| 739 | const auto priority = readU16(data, data + length); |
| 740 | const auto weight = readU16(data, data + length); |
| 741 | const auto port = readU16(data, data + length); |
| 742 | auto target = readName(data, data + length, messageBegin); |
| 743 | |
| 744 | if (!target.empty()) |
| 745 | srvRecords.emplace_back(SrvRecord{decodeHostname(target), port, weight, priority}); |
| 746 | }, |
| 747 | timeout, |
| 748 | {{serversToQuery, |
| 749 | 33, // SRV |
| 750 | 1, // IN |
| 751 | encoded}}); |
| 752 | |
| 753 | return srvRecords; |
| 754 | } |
| 755 | |
| 756 | #if defined(SFML_SYSTEM_WINDOWS) |
| 757 | const auto records = getRecords(encoded, DNS_TYPE_SRV); |
| 758 | for (const auto* ptr = records.get(); ptr; ptr = ptr->pNext) |
| 759 | { |
| 760 | if ((ptr->wType == DNS_TYPE_SRV) && (ptr->Data.SRV.pNameTarget != nullptr)) |
| 761 | { |
| 762 | srvRecords.emplace_back(SrvRecord{decodeHostname(sf::String(ptr->Data.SRV.pNameTarget).toAnsiString()), |
| 763 | ptr->Data.SRV.wPort, |
| 764 | ptr->Data.SRV.wWeight, |
| 765 | ptr->Data.SRV.wPriority}); |
| 766 | } |
| 767 | } |
| 768 | #else |
| 769 | getRecords(encoded, |
| 770 | ns_t_srv, |
| 771 | [&srvRecords](const ns_msg& handle, const ns_rr& record) |
nothing calls this directly
no test coverage detected