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