From 2b0f7c119d61f227c132a8c6793dce63d41b01b3 Mon Sep 17 00:00:00 2001 From: Bjoern Sikora Date: Mon, 21 Sep 2009 15:05:16 +0200 Subject: [PATCH] Do not invoke any webcheck url to often (once every 10 minutes will be the default). --- src/config.cpp | 18 ++++++++++++++++++ src/config.h | 3 +++ src/ip_addr_helper.cpp | 33 +++++++++++++++++++++++++++------ src/ip_addr_helper.h | 8 +++++--- src/logger.cpp | 18 ++++++++++++++++++ src/logger.h | 2 ++ src/main.cpp | 2 +- src/updater.cpp | 2 +- 8 files changed, 75 insertions(+), 11 deletions(-) diff --git a/src/config.cpp b/src/config.cpp index 3ab375b..af543b2 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -47,6 +47,7 @@ Config::Config(Logger::Ptr _log, Serviceholder::Ptr _serviceholder) , EnableIPv6(false) , Loglevel(0) , ConfigPath("/etc/bpdyndnsd") + , WebcheckInterval(0) , ProxyPort(0) , ExternalWarningLog("") , ExternalWarningLevel(0) @@ -81,6 +82,7 @@ Config::Config(Logger::Ptr _log, Serviceholder::Ptr _serviceholder) ("enable_ipv6",po::value()->default_value(false),"Try to use IPv6.") ("webcheck_url",po::value()->default_value(""),"Use this URL to determine IP.") ("webcheck_url_alt",po::value()->default_value(""),"Use this alternative URL to determine IP.") + ("webcheck_interval",po::value()->default_value(10),"The webcheck interval in minutes.") ("http_proxy",po::value(),"Use this proxy for all http requests.") ("http_proxy_port",po::value(),"Port of the proxy.") ("external_warning_log",po::value()->default_value(""),"External programm to pass warning log messages to.") @@ -211,6 +213,9 @@ int Config::parse_cmd_line(int argc, char *argv[]) if ( VariablesMap.count("webcheck_url_alt") ) WebcheckIpUrlAlt = VariablesMap["webcheck_url_alt"].as(); + if ( VariablesMap.count("webcheck_interval") ) + WebcheckInterval = VariablesMap["webcheck_interval"].as(); + if ( VariablesMap.count("http_proxy") && VariablesMap.count("http_proxy_port") ) { Proxy = VariablesMap["http_proxy"].as(); @@ -459,6 +464,9 @@ int Config::load_main_config_file(const string& full_filename) if ( VariablesMap.count("webcheck_url_alt") ) WebcheckIpUrlAlt = VariablesMap["webcheck_url_alt"].as(); + if ( VariablesMap.count("webcheck_interval") ) + WebcheckInterval = VariablesMap["webcheck_interval"].as(); + if ( VariablesMap.count("http_proxy") && VariablesMap.count("http_proxy_port") ) { Proxy = VariablesMap["http_proxy"].as(); @@ -646,6 +654,16 @@ string Config::get_webcheck_ip_url_alt() const /** + * Get member WebcheckInterval + * @return WebcheckInterval + */ +int Config::get_webcheck_interval() const +{ + return WebcheckInterval; +} + + +/** * Get member Proxy * @return Proxy */ diff --git a/src/config.h b/src/config.h index b5a54de..51590a5 100644 --- a/src/config.h +++ b/src/config.h @@ -41,6 +41,7 @@ private: std::string ConfigPath; std::string WebcheckIpUrl; std::string WebcheckIpUrlAlt; + int WebcheckInterval; std::string Proxy; int ProxyPort; std::string ExternalWarningLog; @@ -84,6 +85,8 @@ public: std::string get_webcheck_ip_url_alt() const; + int get_webcheck_interval() const; + void delete_variables_map(); int get_external_warning_level() const; diff --git a/src/ip_addr_helper.cpp b/src/ip_addr_helper.cpp index 44497ba..b31df36 100644 --- a/src/ip_addr_helper.cpp +++ b/src/ip_addr_helper.cpp @@ -20,6 +20,7 @@ namespace net = boost::asio; */ IPAddrHelper::IPAddrHelper() : Log(new Logger) + , WebcheckInterval(0) , ProxyPort(0) , UseIPv6(false) { @@ -29,10 +30,12 @@ IPAddrHelper::IPAddrHelper() /** * Constructor. */ -IPAddrHelper::IPAddrHelper(const Logger::Ptr _log, const string& _webcheck_url, const string& _webcheck_url_alt, const bool _use_ipv6, const string& _proxy, const int _proxy_port) +IPAddrHelper::IPAddrHelper(const Logger::Ptr _log, const string& _webcheck_url, const string& _webcheck_url_alt, const int _webcheck_interval ,const bool _use_ipv6, const string& _proxy, const int _proxy_port) : Log(_log) , WebcheckIpUrl(_webcheck_url) , WebcheckIpUrlAlt(_webcheck_url_alt) + , WebcheckInterval(_webcheck_interval) + , LastWebcheck(0) , Proxy(_proxy) , ProxyPort(_proxy_port) , UseIPv6(_use_ipv6) @@ -119,7 +122,7 @@ bool IPAddrHelper::is_local(const string ip) const * Get the actual IP of this host through a conventional DNS query or through a IP webcheck URL if configured so. * @return A string representation of the actual IP in dotted format or an empty string if something went wrong. */ -string IPAddrHelper::get_actual_ip() const +string IPAddrHelper::get_actual_ip() { string ip; if ( WebcheckIpUrl.empty() ) @@ -196,10 +199,22 @@ string IPAddrHelper::dns_query(const string& _hostname) const * Get the actual IP of this host through a IP webcheck URL. * @return A string representation of the actual IP in dotted format or an empty string if something went wrong. */ -string IPAddrHelper::webcheck_ip() const +string IPAddrHelper::webcheck_ip() { + // Init IPAddress with a empty string. string ip_addr = ""; + // Get the current time. + int current_time = time(NULL); + + // Test if webcheck is allowed due to webcheck_interval. + if ( (LastWebcheck + (WebcheckInterval*60)) >= current_time ) + { + // Webcheck not allowed, log it and return empty string. + Log->print_webcheck_exceed_interval( LastWebcheck, (WebcheckInterval*60), current_time ); + return ip_addr; + } + // Init CURL buffers string curl_writedata_buff; char curl_err_buff[CURL_ERROR_SIZE]; @@ -222,7 +237,7 @@ string IPAddrHelper::webcheck_ip() const url_list.pop_front(); set_curl_url(curl_easy_handle,actual_url); - // Perform curl operation + // Perform curl operation, err_code of 1 indicated connection problem, so try next url. curl_err_code = perform_curl_operation(curl_easy_handle, curl_err_buff, actual_url); } @@ -232,15 +247,21 @@ string IPAddrHelper::webcheck_ip() const // If curl_err_code is not 0, the ip couldn't be determined through any configured webcheck url. if ( curl_err_code != 0 ) { + // Log it and return the empty string. Log->print_webcheck_no_ip(); - // error handling return ip_addr; } + // Log the received curl data. Log->print_received_curl_data(curl_writedata_buff); + // Try to parse a IPAddress out of the received data. ip_addr = parse_ip(curl_writedata_buff); + // Set the LastWebcheck time to current time. + LastWebcheck = current_time; + + // Return the parsed IPAddress. return ip_addr; } @@ -254,7 +275,7 @@ string IPAddrHelper::parse_ip(const string& data) const { string ip = ""; - // regex for valid ip address + // 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; diff --git a/src/ip_addr_helper.h b/src/ip_addr_helper.h index 9d50ccc..14b89ca 100644 --- a/src/ip_addr_helper.h +++ b/src/ip_addr_helper.h @@ -24,13 +24,15 @@ private: Logger::Ptr Log; std::string WebcheckIpUrl; std::string WebcheckIpUrlAlt; + int WebcheckInterval; + int LastWebcheck; std::string Proxy; int ProxyPort; bool UseIPv6; std::string Hostname; bool is_local(const std::string ip) const; - std::string webcheck_ip() const; + std::string webcheck_ip(); CURL * init_curl(std::string& curl_writedata_buff, char* curl_err_buff) const; int perform_curl_operation(CURL * curl_easy_handle, char* curl_err_buff, const std::string& actual_url) const; std::string parse_ip(const std::string& data) const; @@ -41,13 +43,13 @@ public: IPAddrHelper(); - IPAddrHelper(const Logger::Ptr _log, const std::string& _webcheck_url, const std::string& _webcheck_url_alt, const bool _use_ipv6, const std::string& _proxy, const int _proxy_port); + IPAddrHelper(const Logger::Ptr _log, const std::string& _webcheck_url, const std::string& _webcheck_url_alt, const int _webcheck_interval, const bool _use_ipv6, const std::string& _proxy, const int _proxy_port); ~IPAddrHelper(); std::string dns_query(const std::string& _hostname) const; - std::string get_actual_ip() const; + std::string get_actual_ip(); // libcurl is a C library, so we have to make the callback member function static :-( static int http_receive(char *inBuffer, size_t size, size_t nmemb, std::string *outBuffer); diff --git a/src/logger.cpp b/src/logger.cpp index 5986e70..5c7d8c7 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -1502,3 +1502,21 @@ void Logger::print_error_parsing_cmd(const string& error) const log_error(msg.str(),level); } } + + +/** + * The webcheck interval was exceeded, so webcheck not allowed. + * @param last_webcheck Time of last webcheck. + * @param webcheck_interval Webcheck interval time. + * @param current_time Current system time. + */ +void Logger::print_webcheck_exceed_interval( const int last_webcheck, const int webcheck_interval, const int current_time ) const +{ + int level = 0; + if ( level <= Loglevel ) + { + ostringstream msg; + msg << "Exceeding webcheck interval: LastWebcheck " << last_webcheck << " + WebcheckInterval(sec) " << webcheck_interval << " >= CurrentTime " << current_time << endl; + log_notice(msg.str(),level); + } +} diff --git a/src/logger.h b/src/logger.h index 6381142..e326906 100644 --- a/src/logger.h +++ b/src/logger.h @@ -217,6 +217,8 @@ public: void print_error_parsing_config_file(const std::string& filename, const std::string& error) const; void print_error_parsing_cmd(const std::string& error) const; + + void print_webcheck_exceed_interval( const int last_webcheck, const int webcheck_interval, const int current_time ) const; }; #endif diff --git a/src/main.cpp b/src/main.cpp index 48513ce..1bb6764 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -294,7 +294,7 @@ int main(int argc, char *argv[]) // Snore, snore... don't hug the cpu if we are in daemon_mode. if ( updater->get_config()->get_daemon_mode() == 1 ) - sleep(5); + sleep(10); }while ( updater->get_config()->get_daemon_mode() == 1 ); diff --git a/src/updater.cpp b/src/updater.cpp index 7b76c0a..8872535 100644 --- a/src/updater.cpp +++ b/src/updater.cpp @@ -164,7 +164,7 @@ int Updater::init_helper_classes() int Updater::init_ip_helper() { // initialize IPHelper - IPAddrHelper::Ptr _ipaddrhelp(new IPAddrHelper(Log,Conf->get_webcheck_ip_url(),Conf->get_webcheck_ip_url_alt(),Conf->get_enable_ipv6(),Conf->get_proxy(),Conf->get_proxy_port())); + IPAddrHelper::Ptr _ipaddrhelp( new IPAddrHelper( Log, Conf->get_webcheck_ip_url(), Conf->get_webcheck_ip_url_alt(), Conf->get_webcheck_interval(), Conf->get_enable_ipv6(), Conf->get_proxy(), Conf->get_proxy_port() ) ); IPAddrHelp.swap(_ipaddrhelp); return 0; -- 1.7.1