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