Fix user agent. Don't output a newline after any HTTP header as curl won't filter...
[bpdyndnsd] / src / ip_addr_helper.cpp
CommitLineData
0665b239
BS
1/** @file
2 * @brief IPHelper class implementation. This class represents a Helper to get the actual IP.
3 *
4 *
5 *
6 * @copyright Intra2net AG
7 * @license GPLv2
8*/
9
4de6a9b8 10#include "ip_addr_helper.hpp"
0665b239 11#include <boost/asio.hpp>
1c0908b5 12#include <boost/regex.hpp>
1d2e2f56
BS
13#include <arpa/inet.h>
14#include <sys/socket.h>
15#include <netdb.h>
16#include <ifaddrs.h>
0e080ce3 17#include "version_info.h"
1d2e2f56 18
0665b239
BS
19
20using namespace std;
21
22namespace net = boost::asio;
23
24/**
25 * Default constructor.
26 */
ad0e5016 27IPAddrHelper::IPAddrHelper()
b30f392d 28 : Log(new Logger)
2b0f7c11 29 , WebcheckInterval(0)
20399847 30 , LastWebcheck(0)
b30f392d 31 , ProxyPort(0)
0665b239
BS
32 , UseIPv6(false)
33{
34}
35
36
37/**
38 * Constructor.
39 */
08a5a621 40IPAddrHelper::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)
9a0aff44
BS
41 : Log(_log)
42 , WebcheckIpUrl(_webcheck_url)
b30f392d 43 , WebcheckIpUrlAlt(_webcheck_url_alt)
2b0f7c11 44 , WebcheckInterval(_webcheck_interval)
20399847 45 , LastWebcheck(_last_webcheck)
9a0aff44
BS
46 , Proxy(_proxy)
47 , ProxyPort(_proxy_port)
48 , UseIPv6(_use_ipv6)
0665b239 49{
019dc0d9 50 Hostname = net::ip::host_name();
019dc0d9 51 Log->print_hostname(Hostname);
0665b239
BS
52}
53
54
55/**
56 * Default destructor
57 */
ad0e5016 58IPAddrHelper::~IPAddrHelper()
0665b239
BS
59{
60}
61
62
63/**
1d2e2f56 64 * Tests if a given IP is a local IPv6 address
4ef36a12
BS
65 * @param ip The IP to test
66 * @return true if given IP is local, false if not.
67 */
1d2e2f56
BS
68bool IPAddrHelper::is_local_ipv6(const string ip) const
69{
70 // IPv6 any
71 boost::regex expr_any_ipv6("^::$");
72
73 // IPV6 loopback
74 boost::regex expr_loopback_ipv6("^::1$");
75
76 // IPV6 local unicast address
77 boost::regex expr_local_unicast_ipv6("^fc00:");
78
79 // IPV6 link local
80 boost::regex expr_link_local_ipv6("^fe[8,9,a,b]{1}");
81
82 // IPV6 site local
83 boost::regex expr_site_local_ipv6("^fe[c,d,e,f]{1}");
84
85 // It's time to test against the regex patterns
86 if ( boost::regex_search(ip,expr_any_ipv6) )
87 {
88 Log->print_regex_match(expr_any_ipv6.str(),ip);
89 return true;
90 }
91 else if ( boost::regex_search(ip,expr_loopback_ipv6) )
92 {
93 Log->print_regex_match(expr_loopback_ipv6.str(),ip);
94 return true;
95 }
96 else if ( boost::regex_search(ip,expr_local_unicast_ipv6) )
97 {
98 Log->print_regex_match(expr_local_unicast_ipv6.str(),ip);
99 return true;
100 }
101 else if ( boost::regex_search(ip,expr_link_local_ipv6) )
102 {
103 Log->print_regex_match(expr_link_local_ipv6.str(),ip);
104 return true;
105 }
106 else if ( boost::regex_search(ip,expr_site_local_ipv6) )
107 {
108 Log->print_regex_match(expr_site_local_ipv6.str(),ip);
109 return true;
110 }
111
112 return false;
113}
114
115
116/**
117 * Tests if a given IP is a local IPv4 address
118 * @param ip The IP to test
119 * @return true if given IP is local, false if not.
120 */
121bool IPAddrHelper::is_local_ipv4(const string ip) const
4ef36a12
BS
122{
123 // 127.0.0.1
124 boost::regex expr_loopback("127\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}");
125
126 // 192.168.x.x
127 boost::regex expr_192("192\\.168\\.[0-9]{1,3}\\.[0-9]{1,3}");
128
129 // 10.x.x.x
130 boost::regex expr_10("10\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}");
131
132 // 169.254.x.x
133 boost::regex expr_169_254("169\\.254\\.[0-9]{1,3}\\.[0-9]{1,3}");
134
135 // 172.16.x.x -> 172.31.x.x
136 boost::regex expr_172_1("172\\.1[6-9]{1}\\.[0-9]{1,3}\\.[0-9]{1,3}");
137 boost::regex expr_172_2("172\\.2[0-9]{1}\\.[0-9]{1,3}\\.[0-9]{1,3}");
138 boost::regex expr_172_3("172\\.3[0-1]{1}\\.[0-9]{1,3}\\.[0-9]{1,3}");
139
140 // It's time to test against the regex patterns
141 if ( boost::regex_search(ip,expr_loopback) )
142 {
143 Log->print_regex_match(expr_loopback.str(),ip);
144 return true;
145 }
146 else if ( boost::regex_search(ip,expr_192) )
147 {
148 Log->print_regex_match(expr_192.str(),ip);
149 return true;
150 }
151 else if ( boost::regex_search(ip,expr_10) )
152 {
153 Log->print_regex_match(expr_10.str(),ip);
154 return true;
155 }
156 else if ( boost::regex_search(ip,expr_169_254) )
157 {
158 Log->print_regex_match(expr_169_254.str(),ip);
159 return true;
160 }
161 else if ( boost::regex_search(ip,expr_172_1) )
162 {
163 Log->print_regex_match(expr_172_1.str(),ip);
164 return true;
165 }
166 else if ( boost::regex_search(ip,expr_172_2) )
167 {
168 Log->print_regex_match(expr_172_2.str(),ip);
169 return true;
170 }
171 else if ( boost::regex_search(ip,expr_172_3) )
172 {
173 Log->print_regex_match(expr_172_3.str(),ip);
174 return true;
175 }
176
177 return false;
178}
179
180
181/**
0665b239 182 * Get the actual IP of this host through a conventional DNS query or through a IP webcheck URL if configured so.
3c4705d9 183 * @param changed_to_online Indicates if we just went online
0665b239
BS
184 * @return A string representation of the actual IP in dotted format or an empty string if something went wrong.
185 */
3c4705d9 186string IPAddrHelper::get_actual_ip( bool use_webcheck, bool changed_to_online )
0665b239 187{
3c0cd271 188 string ip;
1d2e2f56 189
46fffdd6 190 if ( !WebcheckIpUrl.empty() && use_webcheck )
3c4705d9 191 ip = webcheck_ip(changed_to_online);
46fffdd6
BS
192 else
193 ip = get_local_wan_nic_ip();
3c0cd271 194
1d2e2f56
BS
195 return ip;
196}
197
198
199/**
200 * Get the IP address of the local wan interface if there is one.
201 * @return The IP address of the wan interface or an empty string if something went wrong.
202 */
ce70569b 203string IPAddrHelper::get_local_wan_nic_ip() const
1d2e2f56
BS
204{
205 struct ifaddrs *if_addr_struct, *ifa;
ce70569b
BS
206 unsigned short address_family;
207 int ret_val;
1d2e2f56
BS
208 char ip_addr_buff[NI_MAXHOST];
209 list<string> external_ipv4_addresses;
210 list<string> external_ipv6_addresses;
211
212 // Get linked list of all interface addresses.
213 if ( getifaddrs(&if_addr_struct) == -1 )
4ef36a12 214 {
1d2e2f56
BS
215 Log->print_error_getting_local_wan_ip("getifaddrs", strerror(errno));
216 freeifaddrs(if_addr_struct);
4ef36a12
BS
217 return "";
218 }
3c0cd271 219
1d2e2f56
BS
220 // Iterate through the linked list.
221 for ( ifa = if_addr_struct; ifa != NULL; ifa = ifa->ifa_next)
222 {
3e0bfbf5
TJ
223 // Skip interfaces without IP addresses
224 if (!ifa->ifa_addr)
225 continue;
226
1d2e2f56
BS
227 // Get the address family of the actual address.
228 address_family = ifa->ifa_addr->sa_family;
229
230 // If it is an IPv4 then process further.
231 if ( address_family == AF_INET )
232 {
233 // Translate the address to a protocol independent representation (dottet format). Copy address into ip_addr_buff.
08a5a621 234 ret_val = getnameinfo(ifa->ifa_addr, (socklen_t)sizeof(struct sockaddr_in), ip_addr_buff, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
1d2e2f56
BS
235 if ( ret_val != 0 )
236 {
237 Log->print_error_getting_local_wan_ip("getnameinfo", gai_strerror(ret_val));
238 freeifaddrs(if_addr_struct);
239 return "";
240 }
241
242 // Generate IPv4 string out of char array.
243 string ipv4_addr(ip_addr_buff);
244
245 Log->print_own_ipv4(ipv4_addr, Hostname);
246
247 // Test if it is a local address.
248 if ( !is_local_ipv4(ipv4_addr) )
249 external_ipv4_addresses.push_back(ipv4_addr);
250 else
251 Log->print_ip_is_local(ipv4_addr);
252 }
253 // If it is an IPv6 address and IPv6 is enabled then process further.
ce70569b 254 else if ( (address_family == AF_INET6) && (UseIPv6) )
1d2e2f56
BS
255 {
256 // Translate the address to a protocol independent representation (dottet format). Copy address into ip_addr_buff.
08a5a621 257 ret_val = getnameinfo(ifa->ifa_addr, (socklen_t)sizeof(struct sockaddr_in6), ip_addr_buff, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
1d2e2f56
BS
258 if ( ret_val != 0 )
259 {
260 Log->print_error_getting_local_wan_ip("getnameinfo", gai_strerror(ret_val));
261 freeifaddrs(if_addr_struct);
262 return "";
263 }
264
265 // Generate IPv6 string out of char array.
266 string ipv6_addr(ip_addr_buff);
267
268 Log->print_own_ipv6(ipv6_addr, Hostname);
269
270 // Test if it is a local address.
271 if ( !is_local_ipv6(ipv6_addr) )
272 external_ipv6_addresses.push_back(ipv6_addr);
273 else
274 Log->print_ip_is_local(ipv6_addr);
275 }
276 }
277 freeifaddrs(if_addr_struct);
278
279 // Return the first element in IPv6 list if IPv6 is enabled, otherwise return first element in IPv4 list.
ce70569b 280 if ( (UseIPv6) && (!external_ipv6_addresses.empty()) )
1d2e2f56
BS
281 return external_ipv6_addresses.front();
282 else if ( !external_ipv4_addresses.empty() )
283 return external_ipv4_addresses.front();
284
285 return "";
0665b239
BS
286}
287
0665b239
BS
288
289/**
687d99fb 290 * Get the actual IP of the given host through a DNS query.
c3dea5dc 291 * @param _hostname The hostname for the dns lookup, if empty string, then perform a dns lookup to the local hostname.
0665b239
BS
292 * @return A string representation of the actual IP in dotted format or an empty string if something went wrong.
293 */
ad0e5016 294string IPAddrHelper::dns_query(const string& _hostname) const
0665b239 295{
1d2e2f56
BS
296 list<string> external_ipv4_addresses;
297 list<string> external_ipv6_addresses;
0665b239 298
1d2e2f56 299 // Init the hostname with the given _hostname or with local Hostname if empty.
c3dea5dc
BS
300 string hostname = Hostname;
301 if ( !_hostname.empty() )
302 hostname = _hostname;
303
0665b239
BS
304 try
305 {
306 // BOOST asio isn't the simplest way to perform a DNS lookup, but it works just fine.
307 net::io_service io_service;
308 net::ip::tcp::resolver resolver(io_service);
1d2e2f56
BS
309
310 // Define the DNS query.
311 net::ip::tcp::resolver::query query(hostname, "0", net::ip::resolver_query_base::address_configured | net::ip::resolver_query_base::all_matching);
312
313 // Perform the DNS query.
0665b239
BS
314 net::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
315 net::ip::tcp::resolver::iterator end;
1d2e2f56
BS
316
317 // Iterate through the returned IP addresses.
0665b239
BS
318 while(endpoint_iterator != end)
319 {
1d2e2f56 320 // Get the IP address out of the endpoint iterator.
687d99fb
BS
321 net::ip::address ip;
322 ip = endpoint_iterator->endpoint().address();
1d2e2f56
BS
323
324 // Test if it is a IPv4 address.
0665b239 325 if ( ip.is_v4() )
1d2e2f56
BS
326 {
327 // Get the string representation.
328 string ipv4_addr = ip.to_string();
329
330 Log->print_own_ipv4(ipv4_addr, hostname);
331
332 // If it is not a local address then push it in the external ipv4 address list.
2f83caa3 333 //if ( !is_local_ipv4(ipv4_addr) )
1d2e2f56 334 external_ipv4_addresses.push_back(ipv4_addr);
2f83caa3
BS
335 //else
336 // Log->print_ip_is_local(ipv4_addr);
1d2e2f56
BS
337 }
338 // Test if it is a IPv6 address and if IPv6 is enabled.
ce70569b 339 else if ( (ip.is_v6()) && (UseIPv6) )
1d2e2f56
BS
340 {
341 // Get the string representation.
342 string ipv6_addr = ip.to_string();
343
344 Log->print_own_ipv6(ipv6_addr, hostname);
345
346 // If it is not a local address then push it in the external ipv6 address list.
2f83caa3 347 //if ( !is_local_ipv6(ipv6_addr) )
1d2e2f56 348 external_ipv6_addresses.push_back(ipv6_addr);
2f83caa3
BS
349 //else
350 // Log->print_ip_is_local(ipv6_addr);
1d2e2f56 351 }
0665b239
BS
352 endpoint_iterator++;
353 }
354 io_service.reset();
355 }
ce70569b 356 catch(const exception& e)
0665b239 357 {
c3dea5dc 358 Log->print_error_hostname_to_ip(e.what(),hostname);
0665b239
BS
359 return "";
360 }
361
1d2e2f56 362 // Return the first element in IPv6 list if IPv6 is enabled, otherwise return first element in IPv4 list.
ce70569b 363 if ( (UseIPv6) && (!external_ipv6_addresses.empty()) )
1d2e2f56
BS
364 return external_ipv6_addresses.front();
365 else if ( !external_ipv4_addresses.empty() )
366 return external_ipv4_addresses.front();
0665b239 367
1d2e2f56
BS
368 // Could not get a external IP address, so return empty string.
369 return "";
0665b239
BS
370}
371
372
373/**
374 * Get the actual IP of this host through a IP webcheck URL.
3c4705d9 375 * @param changed_to_online Indicates if we just went online
0665b239
BS
376 * @return A string representation of the actual IP in dotted format or an empty string if something went wrong.
377 */
3c4705d9 378string IPAddrHelper::webcheck_ip(bool changed_to_online)
0665b239 379{
2b0f7c11 380 // Init IPAddress with a empty string.
1c0908b5
BS
381 string ip_addr = "";
382
2b0f7c11 383 // Get the current time.
ce70569b 384 time_t current_time = time(NULL);
2b0f7c11
BS
385
386 // Test if webcheck is allowed due to webcheck_interval.
3c4705d9
TJ
387 // Ignored if we just went online.
388 if ( !changed_to_online && (LastWebcheck + ((time_t)WebcheckInterval*60)) >= current_time )
2b0f7c11
BS
389 {
390 // Webcheck not allowed, log it and return empty string.
391 Log->print_webcheck_exceed_interval( LastWebcheck, (WebcheckInterval*60), current_time );
1d2e2f56 392 return "";
2b0f7c11
BS
393 }
394
1c0908b5
BS
395 // Init CURL buffers
396 string curl_writedata_buff;
397 char curl_err_buff[CURL_ERROR_SIZE];
398 int curl_err_code=1;
399
400 // Init URL List
401 list<string> url_list;
402 url_list.push_back(WebcheckIpUrl);
403 url_list.push_back(WebcheckIpUrlAlt);
404 string actual_url;
405
406 // Init CURL
407 CURL * curl_easy_handle = init_curl(curl_writedata_buff,curl_err_buff);
ce70569b
BS
408 if ( curl_easy_handle == NULL )
409 {
410 return "";
411 }
1c0908b5 412
d43bb54d
TJ
413 // Set the LastWebcheck time to current time.
414 LastWebcheck = current_time;
415
1c0908b5
BS
416 // If perform_curl_operation returns a connection problem indicating return code, try the next ip webcheck url if there is one.
417 while ( (curl_err_code == 1) && (url_list.size() != 0) && (url_list.front() != "") )
418 {
419 // Set URL
420 actual_url = url_list.front();
421 url_list.pop_front();
c730deea
BS
422 if (set_curl_url(curl_easy_handle,actual_url) == CURLE_OK )
423 {
424 // Perform curl operation, err_code of 1 indicated connection problem, so try next url.
425 curl_err_code = perform_curl_operation(curl_easy_handle, curl_err_buff, actual_url);
426 }
1c0908b5
BS
427 }
428
429 // Cleanup CURL handle
430 curl_easy_cleanup(curl_easy_handle);
431
432 // If curl_err_code is not 0, the ip couldn't be determined through any configured webcheck url.
433 if ( curl_err_code != 0 )
434 {
2b0f7c11 435 // Log it and return the empty string.
1c0908b5 436 Log->print_webcheck_no_ip();
1d2e2f56 437 return "";
1c0908b5
BS
438 }
439
2b0f7c11 440 // Log the received curl data.
1c0908b5
BS
441 Log->print_received_curl_data(curl_writedata_buff);
442
1d2e2f56
BS
443 // Try to parse a IPv4 address out of the received data.
444 ip_addr = parse_ipv4(curl_writedata_buff);
445
5ad93dad
BS
446 // TODO: Parsing of IPv6 address out of received curl data via webcheck IP.
447
1d2e2f56
BS
448 if ( !ip_addr.empty() )
449 {
450 // Got a IPv4 address out of the received data.
451 Log->print_own_ipv4(ip_addr, Hostname);
452 }
453 else
454 {
455 return "";
456 }
0665b239 457
1d2e2f56
BS
458 // If IP is within a private range then return ""
459 if ( is_local_ipv4(ip_addr) )
460 {
461 Log->print_ip_is_local(ip_addr);
462 return "";
463 }
464
2b0f7c11 465 // Return the parsed IPAddress.
0665b239
BS
466 return ip_addr;
467}
1c0908b5
BS
468
469
470/**
1d2e2f56 471 * Tries to find a IPv4 Address in dottet format in a given string and returns the IP-Address found.
1c0908b5
BS
472 * @param data The string data to search in for a valid IPv4-Address.
473 * @return The IP Address found or an empty string.
474 */
1d2e2f56 475string IPAddrHelper::parse_ipv4(const string& data) const
1c0908b5
BS
476{
477 string ip = "";
478
1d2e2f56 479 // Regex for ipv4 address in dottet format
1c0908b5
BS
480 boost::regex expr("([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})");
481
482 boost::smatch matches;
483
484 if ( boost::regex_search(data,matches,expr) )
485 {
486 ip = matches[1];
1d2e2f56 487 Log->print_regex_match(expr.str(),ip);
1c0908b5
BS
488 }
489 else
490 {
491 Log->print_regex_ip_not_found(data);
492 }
493
494 return ip;
495}
496
497
498/**
499 * Performs the curl operation.
500 * @param curl_easy_handle The initialized and configured curl handle.
501 * @param curl_err_buff The pointer to the curl error buffer to get error messages from.
502 * @param actual_url The actual configured URL.
503 * @return 0 if all is fine, 1 if an connection problem to the configured url occurs, -1 on other errors.
504 */
ce70569b 505int IPAddrHelper::perform_curl_operation(CURL * curl_easy_handle, const char* curl_err_buff, const string& actual_url) const
1c0908b5 506{
ce70569b
BS
507 CURLcode curl_err_code;
508 if ( (curl_err_code = curl_easy_perform(curl_easy_handle) ) != CURLE_OK )
1c0908b5
BS
509 {
510 // CURL error occured
511 if ( (curl_err_code == CURLE_COULDNT_CONNECT) || (curl_err_code == CURLE_OPERATION_TIMEOUTED) || (curl_err_code == CURLE_COULDNT_RESOLVE_HOST) )
512 {
513 // In case of connection problems we should return 1, that the fallback url will be used.
514 Log->print_webcheck_url_connection_problem(curl_err_buff, actual_url);
515 return 1;
516 }
517 else
518 {
519 // other error
520 Log->print_webcheck_error(curl_err_buff, actual_url);
521 return -1;
522 }
523 }
524 // Operation performed without any problems
525 return 0;
526}
527
528
529/**
530 * Sets a url to the easy curl handle
531 * @param curl_easy_handle The easy curl handle to set the url for.
532 * @param url The url to set.
c730deea 533 * @return CURLcode Curl Error code, CURLE_OK if everything is right.
1c0908b5 534 */
c730deea 535CURLcode IPAddrHelper::set_curl_url(CURL * curl_easy_handle, const string& url) const
1c0908b5 536{
c730deea
BS
537 CURLcode curl_error = CURLE_OK;
538
539 if ( curl_easy_handle != NULL )
540 {
541 curl_error = curl_easy_setopt(curl_easy_handle,CURLOPT_URL,url.c_str());
542 if ( curl_error != CURLE_OK )
543 {
544 // Some options could not be set, so destroy the CURL handle.
545 Log->print_curl_error_init("Could not set CURL URL properly.",curl_error);
546 }
547 }
548 return curl_error;
1c0908b5
BS
549}
550
551
552/**
553 * Initialized curl easy handle with a few options.
554 * @param curl_writedata_buff Reference to a string wich will be filled with the curl result
555 * @param curl_err_buff A pointer to an char array which will be filled with error message.
556 * @return A pointer to the easy curl handle.
557 */
ad0e5016 558CURL * IPAddrHelper::init_curl(string& curl_writedata_buff,char* curl_err_buff) const
1c0908b5 559{
0e080ce3 560 ostringstream user_agent_stream;
1dc0bc9b 561 user_agent_stream << "Intra2net AG - Bullet Proof DYNDNS Daemon - " << MAJOR_VERSION << "." << MINOR_VERSION;
0e080ce3 562 string user_agent = user_agent_stream.str();
ce70569b 563
1c0908b5 564 CURL *curl_easy_handle = curl_easy_init();
ce70569b
BS
565 if ( curl_easy_handle == NULL )
566 {
567 // something went wrong.
568 Log->print_curl_error_init("Could not initialize CURL object.",CURLE_FAILED_INIT);
569 return NULL;
570 }
1c0908b5 571
08a5a621 572 CURLcode curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_NOPROGRESS,1);
ce70569b
BS
573 if ( curlError == CURLE_OK)
574 curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_CONNECTTIMEOUT,5);
575 if ( curlError == CURLE_OK)
576 curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_TIMEOUT,10);
577 if ( curlError == CURLE_OK)
578 curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_BUFFERSIZE,1024);
579 if ( curlError == CURLE_OK)
580 curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_ERRORBUFFER,curl_err_buff);
581 if ( curlError == CURLE_OK)
582 curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_WRITEFUNCTION,http_receive);
583 if ( curlError == CURLE_OK)
584 curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_WRITEDATA,&curl_writedata_buff);
585 if ( curlError == CURLE_OK)
0e080ce3 586 curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_USERAGENT,user_agent.c_str());
1c0908b5 587
4eb87664
BS
588 if ( !Proxy.empty() )
589 {
ce70569b
BS
590 if ( curlError == CURLE_OK)
591 curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_PROXY,Proxy.c_str());
592 if ( curlError == CURLE_OK)
593 curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_PROXYPORT,ProxyPort);
594 }
595
596 if ( curlError != CURLE_OK )
597 {
598 // Some options could not be set, so destroy the CURL handle.
599 Log->print_curl_error_init("Could not set CURL options properly.",curlError);
600 curl_easy_cleanup(curl_easy_handle);
601 curl_easy_handle = NULL;
4eb87664
BS
602 }
603
1c0908b5
BS
604 return curl_easy_handle;
605}
606
607
608/**
609 * Callback Function is called every time CURL is receiving data from HTTPS-Server and will copy all received Data to the given stream pointer
610 * @param inBuffer Pointer to input.
611 * @param size How many mem blocks are received
612 * @param nmemb size of each memblock
613 * @param outBuffer Pointer to output stream.
614 * @return The size received.
615 */
ce70569b 616size_t IPAddrHelper::http_receive( const char *inBuffer, size_t size, size_t nmemb, string *outBuffer )
1c0908b5
BS
617{
618 outBuffer->append(inBuffer);
619 return (size*nmemb);
620}
20399847
BS
621
622
623/**
624 * Get member LastWebcheck
625 * @return LastWebcheck
626 */
08a5a621 627time_t IPAddrHelper::get_last_webcheck() const
20399847
BS
628{
629 return LastWebcheck;
630}