blob: 5e526cabc590b554c112d07584a56a863dcc96ae [file] [log] [blame]
Sunitha Harish29a82b02021-02-18 15:54:16 +05301#pragma once
Ed Tanousf8ca6d72022-06-28 12:12:03 -07002#ifdef BMCWEB_DBUS_DNS_RESOLVER
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08003#include "dbus_singleton.hpp"
4#include "logging.hpp"
5
Sunitha Harish29a82b02021-02-18 15:54:16 +05306#include <boost/asio/ip/address.hpp>
7#include <boost/asio/ip/basic_endpoint.hpp>
Carson Labrado7e8890c2022-11-23 23:58:01 +00008#include <boost/asio/ip/tcp.hpp>
Sunitha Harish29a82b02021-02-18 15:54:16 +05309#include <sdbusplus/message.hpp>
10
11#include <charconv>
12#include <iostream>
13#include <memory>
14
15namespace crow
16{
17
18namespace async_resolve
19{
20
21class Resolver
22{
23 public:
Ed Tanousf8ca6d72022-06-28 12:12:03 -070024 // unused io param used to keep interface identical to
25 // boost::asio::tcp:::resolver
26 explicit Resolver(boost::asio::io_context& /*io*/) {}
Sunitha Harish29a82b02021-02-18 15:54:16 +053027
28 ~Resolver() = default;
29
Ed Tanousecd6a3a2022-01-07 09:18:40 -080030 Resolver(const Resolver&) = delete;
31 Resolver(Resolver&&) = delete;
32 Resolver& operator=(const Resolver&) = delete;
33 Resolver& operator=(Resolver&&) = delete;
34
Ed Tanousf8ca6d72022-06-28 12:12:03 -070035 using results_type = std::vector<boost::asio::ip::tcp::endpoint>;
36
Sunitha Harish29a82b02021-02-18 15:54:16 +053037 template <typename ResolveHandler>
Ed Tanousf8ca6d72022-06-28 12:12:03 -070038 // This function is kept using snake case so that it is interoperable with
39 // boost::asio::ip::tcp::resolver
40 // NOLINTNEXTLINE(readability-identifier-naming)
41 void async_resolve(const std::string& host, std::string_view port,
42 ResolveHandler&& handler)
Sunitha Harish29a82b02021-02-18 15:54:16 +053043 {
44 BMCWEB_LOG_DEBUG << "Trying to resolve: " << host << ":" << port;
Ed Tanousf8ca6d72022-06-28 12:12:03 -070045
46 uint16_t portNum = 0;
47
48 auto it = std::from_chars(&*port.begin(), &*port.end(), portNum);
49 if (it.ec != std::errc())
50 {
51 BMCWEB_LOG_ERROR << "Failed to get the Port";
52 handler(std::make_error_code(std::errc::invalid_argument),
53 results_type{});
54
55 return;
56 }
57
Sunitha Harish29a82b02021-02-18 15:54:16 +053058 uint64_t flag = 0;
59 crow::connections::systemBus->async_method_call(
Ed Tanousf8ca6d72022-06-28 12:12:03 -070060 [host, portNum, handler{std::forward<ResolveHandler>(handler)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -080061 const boost::system::error_code& ec,
Sunitha Harish29a82b02021-02-18 15:54:16 +053062 const std::vector<
63 std::tuple<int32_t, int32_t, std::vector<uint8_t>>>& resp,
64 const std::string& hostName, const uint64_t flagNum) {
Ed Tanousf8ca6d72022-06-28 12:12:03 -070065 results_type endpointList;
Ed Tanous002d39b2022-05-31 08:59:27 -070066 if (ec)
67 {
68 BMCWEB_LOG_ERROR << "Resolve failed: " << ec.message();
69 handler(ec, endpointList);
70 return;
71 }
72 BMCWEB_LOG_DEBUG << "ResolveHostname returned: " << hostName << ":"
73 << flagNum;
74 // Extract the IP address from the response
Ed Tanousf8ca6d72022-06-28 12:12:03 -070075 for (const std::tuple<int32_t, int32_t, std::vector<uint8_t>>&
76 resolveList : resp)
Ed Tanous002d39b2022-05-31 08:59:27 -070077 {
Ed Tanousf8ca6d72022-06-28 12:12:03 -070078 const std::vector<uint8_t>& ipAddress =
79 std::get<2>(resolveList);
Ed Tanous002d39b2022-05-31 08:59:27 -070080 boost::asio::ip::tcp::endpoint endpoint;
81 if (ipAddress.size() == 4) // ipv4 address
Sunitha Harish29a82b02021-02-18 15:54:16 +053082 {
Ed Tanous002d39b2022-05-31 08:59:27 -070083 BMCWEB_LOG_DEBUG << "ipv4 address";
84 boost::asio::ip::address_v4 ipv4Addr(
85 {ipAddress[0], ipAddress[1], ipAddress[2],
86 ipAddress[3]});
87 endpoint.address(ipv4Addr);
88 }
89 else if (ipAddress.size() == 16) // ipv6 address
90 {
91 BMCWEB_LOG_DEBUG << "ipv6 address";
92 boost::asio::ip::address_v6 ipv6Addr(
93 {ipAddress[0], ipAddress[1], ipAddress[2], ipAddress[3],
94 ipAddress[4], ipAddress[5], ipAddress[6], ipAddress[7],
95 ipAddress[8], ipAddress[9], ipAddress[10],
96 ipAddress[11], ipAddress[12], ipAddress[13],
97 ipAddress[14], ipAddress[15]});
98 endpoint.address(ipv6Addr);
99 }
100 else
101 {
102 BMCWEB_LOG_ERROR
103 << "Resolve failed to fetch the IP address";
Sunitha Harish29a82b02021-02-18 15:54:16 +0530104 handler(ec, endpointList);
105 return;
106 }
Ed Tanousf8ca6d72022-06-28 12:12:03 -0700107 endpoint.port(portNum);
Ed Tanous002d39b2022-05-31 08:59:27 -0700108 BMCWEB_LOG_DEBUG << "resolved endpoint is : " << endpoint;
109 endpointList.push_back(endpoint);
110 }
111 // All the resolved data is filled in the endpointList
112 handler(ec, endpointList);
Sunitha Harish29a82b02021-02-18 15:54:16 +0530113 },
114 "org.freedesktop.resolve1", "/org/freedesktop/resolve1",
115 "org.freedesktop.resolve1.Manager", "ResolveHostname", 0, host,
116 AF_UNSPEC, flag);
117 }
118};
119
120} // namespace async_resolve
121} // namespace crow
Ed Tanousf8ca6d72022-06-28 12:12:03 -0700122#endif