diff options
-rw-r--r-- | http/app.hpp | 5 | ||||
-rw-r--r-- | http/http_client.hpp | 32 | ||||
-rw-r--r-- | include/async_resolve.hpp | 40 | ||||
-rw-r--r-- | meson.build | 4 | ||||
-rw-r--r-- | meson_options.txt | 11 | ||||
-rw-r--r-- | redfish-core/include/event_service_manager.hpp | 33 | ||||
-rw-r--r-- | redfish-core/include/redfish_aggregator.hpp | 16 | ||||
-rw-r--r-- | redfish-core/lib/event_service.hpp | 4 | ||||
-rw-r--r-- | src/webserver_main.cpp | 4 |
9 files changed, 99 insertions, 50 deletions
diff --git a/http/app.hpp b/http/app.hpp index a3a6e16255..d3cf48c1b1 100644 --- a/http/app.hpp +++ b/http/app.hpp @@ -183,6 +183,11 @@ class App } #endif + boost::asio::io_context& ioContext() + { + return *io; + } + private: std::shared_ptr<boost::asio::io_context> io; #ifdef BMCWEB_ENABLE_SSL diff --git a/http/http_client.hpp b/http/http_client.hpp index 2b498b7fb8..7a98b54497 100644 --- a/http/http_client.hpp +++ b/http/http_client.hpp @@ -146,7 +146,14 @@ class ConnectionInfo : public std::enable_shared_from_this<ConnectionInfo> // Ascync callables std::function<void(bool, uint32_t, Response&)> callback; - crow::async_resolve::Resolver resolver; + +#ifdef BMCWEB_DBUS_DNS_RESOLVER + using Resolver = crow::async_resolve::Resolver; +#else + using Resolver = boost::asio::ip::tcp::resolver; +#endif + Resolver resolver; + boost::asio::ip::tcp::socket conn; std::optional<boost::beast::ssl_stream<boost::asio::ip::tcp::socket&>> sslConn; @@ -162,15 +169,14 @@ class ConnectionInfo : public std::enable_shared_from_this<ConnectionInfo> << std::to_string(port) << ", id: " << std::to_string(connId); - resolver.asyncResolve(host, port, - std::bind_front(&ConnectionInfo::afterResolve, - this, shared_from_this())); + resolver.async_resolve(host, std::to_string(port), + std::bind_front(&ConnectionInfo::afterResolve, + this, shared_from_this())); } - void afterResolve( - const std::shared_ptr<ConnectionInfo>& /*self*/, - const boost::beast::error_code& ec, - const std::vector<boost::asio::ip::tcp::endpoint>& endpointList) + void afterResolve(const std::shared_ptr<ConnectionInfo>& /*self*/, + const boost::system::error_code& ec, + const Resolver::results_type& endpointList) { if (ec || (endpointList.empty())) { @@ -591,7 +597,7 @@ class ConnectionInfo : public std::enable_shared_from_this<ConnectionInfo> unsigned int connIdIn) : subId(idIn), connPolicy(connPolicyIn), host(destIPIn), port(destPortIn), - connId(connIdIn), conn(iocIn), timer(iocIn) + connId(connIdIn), resolver(iocIn), conn(iocIn), timer(iocIn) { if (useSSL) { @@ -833,8 +839,7 @@ class HttpClient private: std::unordered_map<std::string, std::shared_ptr<ConnectionPool>> connectionPools; - boost::asio::io_context& ioc = - crow::connections::systemBus->get_io_context(); + boost::asio::io_context& ioc; std::shared_ptr<ConnectionPolicy> connPolicy; // Used as a dummy callback by sendData() in order to call @@ -847,9 +852,12 @@ class HttpClient public: HttpClient() = delete; - explicit HttpClient(const std::shared_ptr<ConnectionPolicy>& connPolicyIn) : + explicit HttpClient(boost::asio::io_context& iocIn, + const std::shared_ptr<ConnectionPolicy>& connPolicyIn) : + ioc(iocIn), connPolicy(connPolicyIn) {} + HttpClient(const HttpClient&) = delete; HttpClient& operator=(const HttpClient&) = delete; HttpClient(HttpClient&&) = delete; diff --git a/include/async_resolve.hpp b/include/async_resolve.hpp index f44be4b73f..5e526cabc5 100644 --- a/include/async_resolve.hpp +++ b/include/async_resolve.hpp @@ -1,4 +1,5 @@ #pragma once +#ifdef BMCWEB_DBUS_DNS_RESOLVER #include "dbus_singleton.hpp" #include "logging.hpp" @@ -20,7 +21,9 @@ namespace async_resolve class Resolver { public: - Resolver() = default; + // unused io param used to keep interface identical to + // boost::asio::tcp:::resolver + explicit Resolver(boost::asio::io_context& /*io*/) {} ~Resolver() = default; @@ -29,19 +32,37 @@ class Resolver Resolver& operator=(const Resolver&) = delete; Resolver& operator=(Resolver&&) = delete; + using results_type = std::vector<boost::asio::ip::tcp::endpoint>; + template <typename ResolveHandler> - void asyncResolve(const std::string& host, uint16_t port, - ResolveHandler&& handler) + // This function is kept using snake case so that it is interoperable with + // boost::asio::ip::tcp::resolver + // NOLINTNEXTLINE(readability-identifier-naming) + void async_resolve(const std::string& host, std::string_view port, + ResolveHandler&& handler) { BMCWEB_LOG_DEBUG << "Trying to resolve: " << host << ":" << port; + + uint16_t portNum = 0; + + auto it = std::from_chars(&*port.begin(), &*port.end(), portNum); + if (it.ec != std::errc()) + { + BMCWEB_LOG_ERROR << "Failed to get the Port"; + handler(std::make_error_code(std::errc::invalid_argument), + results_type{}); + + return; + } + uint64_t flag = 0; crow::connections::systemBus->async_method_call( - [host, port, handler{std::forward<ResolveHandler>(handler)}]( + [host, portNum, handler{std::forward<ResolveHandler>(handler)}]( const boost::system::error_code& ec, const std::vector< std::tuple<int32_t, int32_t, std::vector<uint8_t>>>& resp, const std::string& hostName, const uint64_t flagNum) { - std::vector<boost::asio::ip::tcp::endpoint> endpointList; + results_type endpointList; if (ec) { BMCWEB_LOG_ERROR << "Resolve failed: " << ec.message(); @@ -51,9 +72,11 @@ class Resolver BMCWEB_LOG_DEBUG << "ResolveHostname returned: " << hostName << ":" << flagNum; // Extract the IP address from the response - for (auto resolveList : resp) + for (const std::tuple<int32_t, int32_t, std::vector<uint8_t>>& + resolveList : resp) { - std::vector<uint8_t> ipAddress = std::get<2>(resolveList); + const std::vector<uint8_t>& ipAddress = + std::get<2>(resolveList); boost::asio::ip::tcp::endpoint endpoint; if (ipAddress.size() == 4) // ipv4 address { @@ -81,7 +104,7 @@ class Resolver handler(ec, endpointList); return; } - endpoint.port(port); + endpoint.port(portNum); BMCWEB_LOG_DEBUG << "resolved endpoint is : " << endpoint; endpointList.push_back(endpoint); } @@ -96,3 +119,4 @@ class Resolver } // namespace async_resolve } // namespace crow +#endif diff --git a/meson.build b/meson.build index 05e5e2effa..46d6e03557 100644 --- a/meson.build +++ b/meson.build @@ -41,6 +41,10 @@ if(get_option('buildtype') == 'minsize') add_project_arguments('-DNDEBUG', language : 'cpp') endif +if(get_option('dns-resolver') == 'systemd-dbus') + add_project_arguments('-DBMCWEB_DBUS_DNS_RESOLVER', language : 'cpp') +endif + # Disable lto when compiling with no optimization if(get_option('optimization') == '0') add_project_arguments('-fno-lto', language: 'cpp') diff --git a/meson_options.txt b/meson_options.txt index 8a440f98c9..3c2d3f78dd 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -236,6 +236,17 @@ option( ) option( + 'dns-resolver', + type: 'combo', + choices: ['systemd-dbus', 'asio'], + value: 'systemd-dbus', + description: '''Sets which DNS resolver backend should be used. + systemd-dbus uses the Systemd ResolveHostname on dbus, but requires dbus + support. asio relies on boost::asio::tcp::resolver, but cannot resolve + names when boost threading is disabled.''' +) + +option( 'redfish-aggregation', type: 'feature', value: 'disabled', diff --git a/redfish-core/include/event_service_manager.hpp b/redfish-core/include/event_service_manager.hpp index 6c2a569112..7ae47dd224 100644 --- a/redfish-core/include/event_service_manager.hpp +++ b/redfish-core/include/event_service_manager.hpp @@ -378,22 +378,16 @@ class Subscription : public persistent_data::UserSubscription Subscription& operator=(Subscription&&) = delete; Subscription(const std::string& inHost, uint16_t inPort, - const std::string& inPath, const std::string& inUriProto) : + const std::string& inPath, const std::string& inUriProto, + boost::asio::io_context& ioc) : host(inHost), port(inPort), policy(std::make_shared<crow::ConnectionPolicy>()), - client(policy), path(inPath), uriProto(inUriProto) + client(ioc, policy), path(inPath), uriProto(inUriProto) { // Subscription constructor policy->invalidResp = retryRespHandler; } - explicit Subscription( - const std::shared_ptr<boost::asio::ip::tcp::socket>& adaptor) : - policy(std::make_shared<crow::ConnectionPolicy>()), - client(policy), - sseConn(std::make_shared<crow::ServerSentEvents>(adaptor)) - {} - ~Subscription() = default; bool sendEvent(std::string& msg) @@ -602,12 +596,6 @@ class EventServiceManager uint32_t retryAttempts = 0; uint32_t retryTimeoutInterval = 0; - EventServiceManager() - { - // Load config from persist store. - initConfig(); - } - std::streampos redfishLogFilePosition{0}; size_t noOfEventLogSubscribers{0}; size_t noOfMetricReportSubscribers{0}; @@ -617,6 +605,8 @@ class EventServiceManager uint64_t eventId{1}; + boost::asio::io_context& ioc; + public: EventServiceManager(const EventServiceManager&) = delete; EventServiceManager& operator=(const EventServiceManager&) = delete; @@ -624,9 +614,16 @@ class EventServiceManager EventServiceManager& operator=(EventServiceManager&&) = delete; ~EventServiceManager() = default; - static EventServiceManager& getInstance() + explicit EventServiceManager(boost::asio::io_context& iocIn) : ioc(iocIn) + { + // Load config from persist store. + initConfig(); + } + + static EventServiceManager& + getInstance(boost::asio::io_context* ioc = nullptr) { - static EventServiceManager handler; + static EventServiceManager handler(*ioc); return handler; } @@ -662,7 +659,7 @@ class EventServiceManager continue; } std::shared_ptr<Subscription> subValue = - std::make_shared<Subscription>(host, port, path, urlProto); + std::make_shared<Subscription>(host, port, path, urlProto, ioc); subValue->id = newSub->id; subValue->destinationUrl = newSub->destinationUrl; diff --git a/redfish-core/include/redfish_aggregator.hpp b/redfish-core/include/redfish_aggregator.hpp index 1c514ecced..040733307d 100644 --- a/redfish-core/include/redfish_aggregator.hpp +++ b/redfish-core/include/redfish_aggregator.hpp @@ -374,12 +374,6 @@ class RedfishAggregator private: crow::HttpClient client; - RedfishAggregator() : - client(std::make_shared<crow::ConnectionPolicy>(getAggregationPolicy())) - { - getSatelliteConfigs(constructorCallback); - } - // Dummy callback used by the Constructor so that it can report the number // of satellite configs when the class is first created static void constructorCallback( @@ -735,15 +729,21 @@ class RedfishAggregator } public: + explicit RedfishAggregator(boost::asio::io_context& ioc) : + client(ioc, + std::make_shared<crow::ConnectionPolicy>(getAggregationPolicy())) + { + getSatelliteConfigs(constructorCallback); + } RedfishAggregator(const RedfishAggregator&) = delete; RedfishAggregator& operator=(const RedfishAggregator&) = delete; RedfishAggregator(RedfishAggregator&&) = delete; RedfishAggregator& operator=(RedfishAggregator&&) = delete; ~RedfishAggregator() = default; - static RedfishAggregator& getInstance() + static RedfishAggregator& getInstance(boost::asio::io_context* io = nullptr) { - static RedfishAggregator handler; + static RedfishAggregator handler(*io); return handler; } diff --git a/redfish-core/lib/event_service.hpp b/redfish-core/lib/event_service.hpp index f74f215341..5f57ff761a 100644 --- a/redfish-core/lib/event_service.hpp +++ b/redfish-core/lib/event_service.hpp @@ -281,8 +281,8 @@ inline void requestRoutesEventDestinationCollection(App& app) { path = "/"; } - std::shared_ptr<Subscription> subValue = - std::make_shared<Subscription>(host, port, path, urlProto); + std::shared_ptr<Subscription> subValue = std::make_shared<Subscription>( + host, port, path, urlProto, app.ioContext()); subValue->destinationUrl = destUrl; diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp index d3021a83d0..8150f460ad 100644 --- a/src/webserver_main.cpp +++ b/src/webserver_main.cpp @@ -85,11 +85,11 @@ static int run() redfish::RedfishService redfish(app); // Create EventServiceManager instance and initialize Config - redfish::EventServiceManager::getInstance(); + redfish::EventServiceManager::getInstance(&*io); #ifdef BMCWEB_ENABLE_REDFISH_AGGREGATION // Create RedfishAggregator instance and initialize Config - redfish::RedfishAggregator::getInstance(); + redfish::RedfishAggregator::getInstance(&*io); #endif #endif |