MCPcopy Create free account
hub / github.com/SFML/SFML / getPublicAddress

Method getPublicAddress

src/SFML/Network/Dns.cpp:894–981  ·  view source on GitHub ↗

///////////////////////////////////////////////////////

Source from the content-addressed store, hash-verified

892
893////////////////////////////////////////////////////////////
894std::optional<IpAddress> Dns::getPublicAddress(std::optional<Time> timeout, IpAddress::Type type)
895{
896 std::optional<IpAddress> address;
897
898 const auto handler =
899 [&](const char* data, std::size_t length, const char*, std::uint16_t responseType, std::uint16_t responseClass)
900 {
901 // No need to handle this response if we already have an address
902 if (address.has_value())
903 return;
904
905 // AAAA, IN
906 if ((responseType == 28) && (responseClass == 1) && (length == 16))
907 {
908 std::array<std::uint8_t, 16> bytes{};
909 std::memcpy(bytes.data(), data, 16);
910 if (std::any_of(bytes.begin(), bytes.end(), [](auto b) { return b != 0; }))
911 address.emplace(bytes);
912 }
913
914 // A, IN
915 if ((responseType == 1) && (responseClass == 1))
916 {
917 if (const auto bytes = readU32(data, data + length); bytes != 0)
918 address.emplace(bytes);
919 }
920
921 // TXT, IN or CH
922 if ((responseType == 16) && ((responseClass == 1) || (responseClass == 3)))
923 {
924 if (const auto txtLength = readU8(data, data + length); (std::size_t{1} + txtLength) == length)
925 {
926 std::string str(data, txtLength);
927 str.erase(std::remove(str.begin(), str.end(), '"'), str.end()); // Remove quotes if any
928 if (const auto ipAddress = IpAddress::fromString(str); ipAddress)
929 address.emplace(*ipAddress);
930 }
931 }
932 };
933
934 const auto filter = [&type](auto filteredAddresses)
935 {
936 filteredAddresses.erase(std::remove_if(filteredAddresses.begin(),
937 filteredAddresses.end(),
938 [&type](const auto& filteredAddress)
939 { return filteredAddress.getType() != type; }),
940 filteredAddresses.end());
941 return filteredAddresses;
942 };
943
944 const auto addressQueryType = static_cast<std::uint16_t>((type == IpAddress::Type::IpV4) ? 1 : 28); // A/AAAA
945
946 std::vector<Query> queries;
947
948 // Attempt to query Cloudflare and OpenDNS first since those don't require their server hostnames to be looked up and resolved
949 queries.emplace_back(Query{filter(cloudflareAddresses), 16, 3, "whoami.cloudflare"}); // TXT, CH
950 queries.emplace_back(Query{filter(opendnsAddresses), addressQueryType, 1, "myip.opendns.com"}); // A/AAAA, IN
951

Callers

nothing calls this directly

Calls 9

readU32Function · 0.85
readU8Function · 0.85
queryDnsFunction · 0.85
eraseMethod · 0.80
getTypeMethod · 0.80
insertMethod · 0.80
beginMethod · 0.45
endMethod · 0.45
clearMethod · 0.45

Tested by

no test coverage detected