1 #pragma once 2 #include <boost/asio/ip/address.hpp> 3 #include <boost/asio/ip/basic_endpoint.hpp> 4 #include <sdbusplus/message.hpp> 5 6 #include <charconv> 7 #include <iostream> 8 #include <memory> 9 10 namespace crow 11 { 12 13 namespace async_resolve 14 { 15 16 class Resolver 17 { 18 public: 19 Resolver() = default; 20 21 ~Resolver() = default; 22 23 Resolver(const Resolver&) = delete; 24 Resolver(Resolver&&) = delete; 25 Resolver& operator=(const Resolver&) = delete; 26 Resolver& operator=(Resolver&&) = delete; 27 28 template <typename ResolveHandler> 29 void asyncResolve(const std::string& host, uint16_t port, 30 ResolveHandler&& handler) 31 { 32 BMCWEB_LOG_DEBUG << "Trying to resolve: " << host << ":" << port; 33 uint64_t flag = 0; 34 crow::connections::systemBus->async_method_call( 35 [host, port, handler{std::forward<ResolveHandler>(handler)}]( 36 const boost::system::error_code ec, 37 const std::vector< 38 std::tuple<int32_t, int32_t, std::vector<uint8_t>>>& resp, 39 const std::string& hostName, const uint64_t flagNum) { 40 std::vector<boost::asio::ip::tcp::endpoint> endpointList; 41 if (ec) 42 { 43 BMCWEB_LOG_ERROR << "Resolve failed: " << ec.message(); 44 handler(ec, endpointList); 45 return; 46 } 47 BMCWEB_LOG_DEBUG << "ResolveHostname returned: " << hostName 48 << ":" << flagNum; 49 // Extract the IP address from the response 50 for (auto resolveList : resp) 51 { 52 std::vector<uint8_t> ipAddress = std::get<2>(resolveList); 53 boost::asio::ip::tcp::endpoint endpoint; 54 if (ipAddress.size() == 4) // ipv4 address 55 { 56 BMCWEB_LOG_DEBUG << "ipv4 address"; 57 boost::asio::ip::address_v4 ipv4Addr( 58 {ipAddress[0], ipAddress[1], ipAddress[2], 59 ipAddress[3]}); 60 endpoint.address(ipv4Addr); 61 } 62 else if (ipAddress.size() == 16) // ipv6 address 63 { 64 BMCWEB_LOG_DEBUG << "ipv6 address"; 65 boost::asio::ip::address_v6 ipv6Addr( 66 {ipAddress[0], ipAddress[1], ipAddress[2], 67 ipAddress[3], ipAddress[4], ipAddress[5], 68 ipAddress[6], ipAddress[7], ipAddress[8], 69 ipAddress[9], ipAddress[10], ipAddress[11], 70 ipAddress[12], ipAddress[13], ipAddress[14], 71 ipAddress[15]}); 72 endpoint.address(ipv6Addr); 73 } 74 else 75 { 76 BMCWEB_LOG_ERROR 77 << "Resolve failed to fetch the IP address"; 78 handler(ec, endpointList); 79 return; 80 } 81 endpoint.port(port); 82 BMCWEB_LOG_DEBUG << "resolved endpoint is : " << endpoint; 83 endpointList.push_back(endpoint); 84 } 85 // All the resolved data is filled in the endpointList 86 handler(ec, endpointList); 87 }, 88 "org.freedesktop.resolve1", "/org/freedesktop/resolve1", 89 "org.freedesktop.resolve1.Manager", "ResolveHostname", 0, host, 90 AF_UNSPEC, flag); 91 } 92 }; 93 94 } // namespace async_resolve 95 } // namespace crow 96