1 #include "server-conf.hpp" 2 #include "utils.hpp" 3 #include "xyz/openbmc_project/Common/error.hpp" 4 #include <fstream> 5 #include <phosphor-logging/elog.hpp> 6 #if __has_include("../../usr/include/phosphor-logging/elog-errors.hpp") 7 #include "../../usr/include/phosphor-logging/elog-errors.hpp" 8 #else 9 #include <phosphor-logging/elog-errors.hpp> 10 #endif 11 #include <netdb.h> 12 #include <arpa/inet.h> 13 14 namespace phosphor 15 { 16 namespace rsyslog_config 17 { 18 19 namespace utils = phosphor::rsyslog_utils; 20 using namespace phosphor::logging; 21 using namespace sdbusplus::xyz::openbmc_project::Common::Error; 22 23 std::string Server::address(std::string value) 24 { 25 using Argument = xyz::openbmc_project::Common::InvalidArgument; 26 std::string result {}; 27 28 try 29 { 30 auto serverAddress = address(); 31 if (serverAddress == value) 32 { 33 return serverAddress; 34 } 35 36 if (!value.empty() && !addressValid(value)) 37 { 38 elog<InvalidArgument>(Argument::ARGUMENT_NAME("Address"), 39 Argument::ARGUMENT_VALUE(value.c_str())); 40 } 41 42 writeConfig(value, port(), configFilePath.c_str()); 43 result = std::move(NetworkClient::address(value)); 44 } 45 catch (const InvalidArgument& e) 46 { 47 throw; 48 } 49 catch (const InternalFailure& e) 50 { 51 throw; 52 } 53 catch (const std::exception& e) 54 { 55 log<level::ERR>(e.what()); 56 elog<InternalFailure>(); 57 } 58 59 return result; 60 } 61 62 uint16_t Server::port(uint16_t value) 63 { 64 uint16_t result {}; 65 66 try 67 { 68 auto serverPort = port(); 69 if (serverPort == value) 70 { 71 return serverPort; 72 } 73 74 writeConfig(address(), value, configFilePath.c_str()); 75 result = NetworkClient::port(value); 76 } 77 catch (const InternalFailure& e) 78 { 79 throw; 80 } 81 catch (const std::exception& e) 82 { 83 log<level::ERR>(e.what()); 84 elog<InternalFailure>(); 85 } 86 87 return result; 88 } 89 90 void Server::writeConfig( 91 const std::string& serverAddress, 92 uint16_t serverPort, 93 const char* filePath) 94 { 95 std::fstream stream(filePath, std::fstream::out); 96 97 if (serverPort && !serverAddress.empty()) 98 { 99 // write '*.* @@<remote-host>:<port>' 100 stream << "*.* @@" << serverAddress << ":" << serverPort; 101 } 102 else // this is a disable request 103 { 104 // write '#*.* @@remote-host:port' 105 stream << "#*.* @@remote-host:port"; 106 } 107 108 restart(); 109 } 110 111 bool Server::addressValid(const std::string& address) 112 { 113 addrinfo hints{}; 114 addrinfo* res = nullptr; 115 hints.ai_family = AF_UNSPEC; 116 hints.ai_socktype = SOCK_STREAM; 117 hints.ai_flags |= AI_CANONNAME; 118 119 auto result = getaddrinfo(address.c_str(), nullptr, &hints, &res); 120 if (result) 121 { 122 log<level::ERR>("bad address", 123 entry("ADDRESS=%s", address.c_str()), 124 entry("ERRNO=%d", result)); 125 return false; 126 } 127 return true; 128 } 129 130 void Server::restore(const char* filePath) 131 { 132 std::fstream stream(filePath, std::fstream::in); 133 std::string line; 134 135 getline(stream, line); 136 137 // Ignore if line is commented 138 if ('#' != line.at(0)) 139 { 140 auto pos = line.find(':'); 141 if (pos != std::string::npos) 142 { 143 //"*.* @@<address>:<port>" 144 constexpr auto start = 6; // Skip "*.* @@" 145 auto serverAddress = line.substr(start, pos - start); 146 auto serverPort = line.substr(pos + 1); 147 NetworkClient::address(std::move(serverAddress)); 148 NetworkClient::port(std::stoul(serverPort)); 149 } 150 } 151 } 152 153 void Server::restart() 154 { 155 utils::restart(); 156 } 157 158 } // namespace rsyslog_config 159 } // namespace phosphor 160