* @license GPLv2
*/
-#include "ip_addr_helper.h"
+#include "ip_addr_helper.hpp"
#include <boost/asio.hpp>
#include <boost/regex.hpp>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>
#include <ifaddrs.h>
+#include "version_info.h"
using namespace std;
/**
* Constructor.
*/
-IPAddrHelper::IPAddrHelper(const Logger::Ptr _log, const string& _webcheck_url, const string& _webcheck_url_alt, const int _webcheck_interval, const int _last_webcheck ,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 time_t _last_webcheck ,const bool _use_ipv6, const string& _proxy, const int _proxy_port)
: Log(_log)
, WebcheckIpUrl(_webcheck_url)
, WebcheckIpUrlAlt(_webcheck_url_alt)
/**
* Get the actual IP of this host through a conventional DNS query or through a IP webcheck URL if configured so.
+ * @param use_webcheck If true: Determine IP via web check
+ * @param changed_to_online Indicates if we just went online
+ * @param wan_override_ip Override automatic WAN IP detection if not empty
* @return A string representation of the actual IP in dotted format or an empty string if something went wrong.
*/
-string IPAddrHelper::get_actual_ip()
+string IPAddrHelper::get_actual_ip( bool use_webcheck, bool changed_to_online, const std::string &wan_override_ip )
{
string ip;
- if ( WebcheckIpUrl.empty() )
- ip = get_local_wan_nic_ip();
+ if ( !WebcheckIpUrl.empty() && use_webcheck )
+ ip = webcheck_ip(changed_to_online);
+ else if (!wan_override_ip.empty())
+ ip = wan_override_ip;
else
- ip = webcheck_ip();
+ ip = get_local_wan_nic_ip();
return ip;
}
// Iterate through the linked list.
for ( ifa = if_addr_struct; ifa != NULL; ifa = ifa->ifa_next)
{
+ // Skip interfaces without IP addresses
+ if (!ifa->ifa_addr)
+ continue;
+
// Get the address family of the actual address.
address_family = ifa->ifa_addr->sa_family;
if ( address_family == AF_INET )
{
// Translate the address to a protocol independent representation (dottet format). Copy address into ip_addr_buff.
- ret_val = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in), ip_addr_buff, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
+ ret_val = getnameinfo(ifa->ifa_addr, (socklen_t)sizeof(struct sockaddr_in), ip_addr_buff, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if ( ret_val != 0 )
{
Log->print_error_getting_local_wan_ip("getnameinfo", gai_strerror(ret_val));
else if ( (address_family == AF_INET6) && (UseIPv6) )
{
// Translate the address to a protocol independent representation (dottet format). Copy address into ip_addr_buff.
- ret_val = getnameinfo(ifa->ifa_addr, sizeof(struct sockaddr_in6), ip_addr_buff, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
+ ret_val = getnameinfo(ifa->ifa_addr, (socklen_t)sizeof(struct sockaddr_in6), ip_addr_buff, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
if ( ret_val != 0 )
{
Log->print_error_getting_local_wan_ip("getnameinfo", gai_strerror(ret_val));
Log->print_own_ipv4(ipv4_addr, hostname);
// If it is not a local address then push it in the external ipv4 address list.
- if ( !is_local_ipv4(ipv4_addr) )
+ //if ( !is_local_ipv4(ipv4_addr) )
external_ipv4_addresses.push_back(ipv4_addr);
- else
- Log->print_ip_is_local(ipv4_addr);
+ //else
+ // Log->print_ip_is_local(ipv4_addr);
}
// Test if it is a IPv6 address and if IPv6 is enabled.
else if ( (ip.is_v6()) && (UseIPv6) )
Log->print_own_ipv6(ipv6_addr, hostname);
// If it is not a local address then push it in the external ipv6 address list.
- if ( !is_local_ipv6(ipv6_addr) )
+ //if ( !is_local_ipv6(ipv6_addr) )
external_ipv6_addresses.push_back(ipv6_addr);
- else
- Log->print_ip_is_local(ipv6_addr);
+ //else
+ // Log->print_ip_is_local(ipv6_addr);
}
endpoint_iterator++;
}
/**
* Get the actual IP of this host through a IP webcheck URL.
+ * @param changed_to_online Indicates if we just went online
* @return A string representation of the actual IP in dotted format or an empty string if something went wrong.
*/
-string IPAddrHelper::webcheck_ip()
+string IPAddrHelper::webcheck_ip(bool changed_to_online)
{
// Init IPAddress with a empty string.
string ip_addr = "";
time_t current_time = time(NULL);
// Test if webcheck is allowed due to webcheck_interval.
- if ( (LastWebcheck + ((time_t)WebcheckInterval*60)) >= current_time )
+ // Ignored if we just went online.
+ if ( !changed_to_online && (LastWebcheck + ((time_t)WebcheckInterval*60)) >= current_time )
{
// Webcheck not allowed, log it and return empty string.
Log->print_webcheck_exceed_interval( LastWebcheck, (WebcheckInterval*60), current_time );
return "";
}
+ // Set the LastWebcheck time to current time.
+ LastWebcheck = current_time;
+
// 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() != "") )
{
return "";
}
- // Set the LastWebcheck time to current time.
- LastWebcheck = current_time;
-
// If IP is within a private range then return ""
if ( is_local_ipv4(ip_addr) )
{
CURLcode curl_err_code;
if ( (curl_err_code = curl_easy_perform(curl_easy_handle) ) != CURLE_OK )
{
- // CURL error occured
+ // CURL error occurred
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.
*/
CURL * IPAddrHelper::init_curl(string& curl_writedata_buff,char* curl_err_buff) const
{
- string user_agent = "Bullet Proof DYNDNS Daemon 0.1.1 - Intra2net AG 2009";
+ ostringstream user_agent_stream;
+ user_agent_stream << "Intra2net AG - Bullet Proof DYNDNS Daemon - " << MAJOR_VERSION << "." << MINOR_VERSION;
+ string user_agent = user_agent_stream.str();
CURL *curl_easy_handle = curl_easy_init();
if ( curl_easy_handle == NULL )
return NULL;
}
- CURLcode curlError = CURLE_OK;
-
- if ( curlError == CURLE_OK )
- curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_NOPROGRESS,1);
+ CURLcode curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_NOPROGRESS,1);
if ( curlError == CURLE_OK)
curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_CONNECTTIMEOUT,5);
if ( curlError == CURLE_OK)
if ( curlError == CURLE_OK)
curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_WRITEDATA,&curl_writedata_buff);
if ( curlError == CURLE_OK)
- curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_USERAGENT,&user_agent);
+ curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_USERAGENT,user_agent.c_str());
if ( !Proxy.empty() )
{
* @param outBuffer Pointer to output stream.
* @return The size received.
*/
-size_t IPAddrHelper::http_receive( const char *inBuffer, size_t size, size_t nmemb, string *outBuffer )
+size_t IPAddrHelper::http_receive( void *inBuffer, size_t size, size_t nmemb, string *outBuffer )
{
- outBuffer->append(inBuffer);
+ outBuffer->append(static_cast<char *>(inBuffer), size*nmemb);
return (size*nmemb);
-}
+} //lint !e818
/**
* Get member LastWebcheck
* @return LastWebcheck
*/
-int IPAddrHelper::get_last_webcheck() const
+time_t IPAddrHelper::get_last_webcheck() const
{
return LastWebcheck;
}