#include "iphelper.h"
#include <boost/asio.hpp>
+#include <boost/regex.hpp>
using namespace std;
*/
string IPHelper::webcheck_ip() const
{
- string ip_addr = "127.0.0.1";
+ string ip_addr = "";
+
+ // Init CURL buffers
+ string curl_writedata_buff;
+ char curl_err_buff[CURL_ERROR_SIZE];
+ int curl_err_code=1;
+
+ // Init URL List
+ list<string> url_list;
+ url_list.push_back(WebcheckIpUrl);
+ url_list.push_back(WebcheckIpUrlAlt);
+ string actual_url;
+
+ // Init CURL
+ CURL * curl_easy_handle = init_curl(curl_writedata_buff,curl_err_buff);
+
+ // If perform_curl_operation returns a connection problem indicating return code, try the next ip webcheck url if there is one.
+ while ( (curl_err_code == 1) && (url_list.size() != 0) && (url_list.front() != "") )
+ {
+ // Set URL
+ actual_url = url_list.front();
+ url_list.pop_front();
+ set_curl_url(curl_easy_handle,actual_url);
+
+ // Perform curl operation
+ curl_err_code = perform_curl_operation(curl_easy_handle, curl_err_buff, actual_url);
+ }
+
+ // Cleanup CURL handle
+ curl_easy_cleanup(curl_easy_handle);
+
+ // If curl_err_code is not 0, the ip couldn't be determined through any configured webcheck url.
+ if ( curl_err_code != 0 )
+ {
+ Log->print_webcheck_no_ip();
+ // error handling
+ return ip_addr;
+ }
+
+ Log->print_received_curl_data(curl_writedata_buff);
+
+ ip_addr = parse_ip(curl_writedata_buff);
return ip_addr;
}
+
+
+/**
+ * Tries to find a valid IPv4 Address in dottet format in a given string and returns the IP-Address found.
+ * @param data The string data to search in for a valid IPv4-Address.
+ * @return The IP Address found or an empty string.
+ */
+string IPHelper::parse_ip(const string& data) const
+{
+ string ip = "";
+
+ // regex for valid ip address
+ boost::regex expr("([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})");
+
+ boost::smatch matches;
+
+ if ( boost::regex_search(data,matches,expr) )
+ {
+ ip = matches[1];
+ Log->print_regex_found_ip(ip);
+ }
+ else
+ {
+ Log->print_regex_ip_not_found(data);
+ }
+
+ return ip;
+}
+
+
+/**
+ * Performs the curl operation.
+ * @param curl_easy_handle The initialized and configured curl handle.
+ * @param curl_err_buff The pointer to the curl error buffer to get error messages from.
+ * @param actual_url The actual configured URL.
+ * @return 0 if all is fine, 1 if an connection problem to the configured url occurs, -1 on other errors.
+ */
+int IPHelper::perform_curl_operation(CURL * curl_easy_handle, char* curl_err_buff, const string& actual_url) const
+{
+ int curl_err_code;
+ if ( (curl_err_code = curl_easy_perform(curl_easy_handle) ) != 0 )
+ {
+ // CURL error occured
+ if ( (curl_err_code == CURLE_COULDNT_CONNECT) || (curl_err_code == CURLE_OPERATION_TIMEOUTED) || (curl_err_code == CURLE_COULDNT_RESOLVE_HOST) )
+ {
+ // In case of connection problems we should return 1, that the fallback url will be used.
+ Log->print_webcheck_url_connection_problem(curl_err_buff, actual_url);
+ return 1;
+ }
+ else
+ {
+ // other error
+ Log->print_webcheck_error(curl_err_buff, actual_url);
+ return -1;
+ }
+ }
+ // Operation performed without any problems
+ return 0;
+}
+
+
+/**
+ * Sets a url to the easy curl handle
+ * @param curl_easy_handle The easy curl handle to set the url for.
+ * @param url The url to set.
+ */
+void IPHelper::set_curl_url(CURL * curl_easy_handle, const string& url) const
+{
+ curl_easy_setopt(curl_easy_handle,CURLOPT_URL,url.c_str());
+}
+
+
+/**
+ * Initialized curl easy handle with a few options.
+ * @param curl_writedata_buff Reference to a string wich will be filled with the curl result
+ * @param curl_err_buff A pointer to an char array which will be filled with error message.
+ * @return A pointer to the easy curl handle.
+ */
+CURL * IPHelper::init_curl(string& curl_writedata_buff,char* curl_err_buff) const
+{
+ CURL *curl_easy_handle = curl_easy_init();
+
+ curl_easy_setopt(curl_easy_handle,CURLOPT_NOPROGRESS,1);
+ curl_easy_setopt(curl_easy_handle,CURLOPT_CONNECTTIMEOUT,5);
+ curl_easy_setopt(curl_easy_handle,CURLOPT_TIMEOUT,10);
+ curl_easy_setopt(curl_easy_handle,CURLOPT_BUFFERSIZE,1024);
+ curl_easy_setopt(curl_easy_handle,CURLOPT_ERRORBUFFER,curl_err_buff);
+ curl_easy_setopt(curl_easy_handle,CURLOPT_WRITEFUNCTION,http_receive);
+ curl_easy_setopt(curl_easy_handle,CURLOPT_WRITEDATA,&curl_writedata_buff);
+
+ return curl_easy_handle;
+}
+
+
+/**
+ * Callback Function is called every time CURL is receiving data from HTTPS-Server and will copy all received Data to the given stream pointer
+ * @param inBuffer Pointer to input.
+ * @param size How many mem blocks are received
+ * @param nmemb size of each memblock
+ * @param outBuffer Pointer to output stream.
+ * @return The size received.
+ */
+int IPHelper::http_receive( char *inBuffer, size_t size, size_t nmemb, string *outBuffer )
+{
+ outBuffer->append(inBuffer);
+ return (size*nmemb);
+}
* @param exception The exception caught.
* @param hostname The hostname.
*/
-void Logger::print_error_hostname_to_ip(const std::string& exception, const std::string& hostname) const
+void Logger::print_error_hostname_to_ip(const string& exception, const string& hostname) const
{
if ( 1 <= Loglevel )
{
}
-void Logger::print_update_service_successful(const std::string& service)
+/**
+ * The update of the given service was successful.
+ * @param service The service.
+ */
+void Logger::print_update_service_successful(const string& service) const
{
if ( 0 <= Loglevel )
{
ostringstream msg;
msg << "Updated service successful: " << service << endl;
+ log_notice(msg.str());
+ }
+}
+
+
+/**
+ * No ip could be determined through webcheck
+ */
+void Logger::print_webcheck_no_ip() const
+{
+ if ( 0 <= Loglevel )
+ {
+ ostringstream msg;
+ msg << "This hosts' IP could not be determined through any configured webcheck url." << endl;
+ log_error(msg.str());
+ }
+}
+
+
+/**
+ * Connection problem while trying to get ip through webcheck url
+ * @param curl_err_buff Curl error message
+ * @param url the url
+ */
+void Logger::print_webcheck_url_connection_problem(const char * curl_err_buff, const string& url) const
+{
+ if ( 1 <= Loglevel )
+ {
+ ostringstream msg;
+ msg << "There was a problem while trying to connect to following URL: " << url << " CURL error: " << curl_err_buff << endl;
+ log_warning(msg.str());
+ }
+}
+
+
+/**
+ * Prints out curl error.
+ * @param curl_err_buff Curl error message.
+ * @param url URL
+ */
+void Logger::print_webcheck_error(const char * curl_err_buff, const string& url) const
+{
+ if ( 0 <= Loglevel )
+ {
+ ostringstream msg;
+ msg << "There was an error while trying to connect to following URL: " << url << " CURL error: " << curl_err_buff << endl;
log_error(msg.str());
}
}
+
+
+/**
+ * Prints out the received data through curl.
+ * @param curl_data Data string
+ */
+void Logger::print_received_curl_data(const string& curl_data) const
+{
+ if ( 1 <= Loglevel )
+ {
+ ostringstream msg;
+ msg << "Received CURL data: " << curl_data << endl;
+ log_notice(msg.str());
+ }
+}
+
+
+/**
+ * IP was foudn through regex
+ * @param ip The IP found.
+ */
+void Logger::print_regex_found_ip(const string& ip) const
+{
+ if ( 1 <= Loglevel )
+ {
+ ostringstream msg;
+ msg << "Found IP-Address via regex: " << ip << endl;
+ log_notice(msg.str());
+ }
+}
+
+
+/**
+ * No IP was found through regex.
+ * @param data The data string which should contain a valid IP.s
+ */
+void Logger::print_regex_ip_not_found(const string& data) const
+{
+ if ( 0 <= Loglevel )
+ {
+ ostringstream msg;
+ msg << "Could not extract an IP-Address via regex from following data:\n" << data << endl;
+ log_warning(msg.str());
+ }
+}