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