Fix 'occurred' typo
[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.
6114d87c 183 * @param use_webcheck If true: Determine IP via web check
3c4705d9 184 * @param changed_to_online Indicates if we just went online
6114d87c 185 * @param wan_override_ip Override automatic WAN IP detection if not empty
0665b239
BS
186 * @return A string representation of the actual IP in dotted format or an empty string if something went wrong.
187 */
6114d87c 188string IPAddrHelper::get_actual_ip( bool use_webcheck, bool changed_to_online, const std::string &wan_override_ip )
0665b239 189{
3c0cd271 190 string ip;
1d2e2f56 191
46fffdd6 192 if ( !WebcheckIpUrl.empty() && use_webcheck )
3c4705d9 193 ip = webcheck_ip(changed_to_online);
6114d87c
TJ
194 else if (!wan_override_ip.empty())
195 ip = wan_override_ip;
46fffdd6
BS
196 else
197 ip = get_local_wan_nic_ip();
3c0cd271 198
1d2e2f56
BS
199 return ip;
200}
201
202
203/**
204 * Get the IP address of the local wan interface if there is one.
205 * @return The IP address of the wan interface or an empty string if something went wrong.
206 */
ce70569b 207string IPAddrHelper::get_local_wan_nic_ip() const
1d2e2f56
BS
208{
209 struct ifaddrs *if_addr_struct, *ifa;
ce70569b
BS
210 unsigned short address_family;
211 int ret_val;
1d2e2f56
BS
212 char ip_addr_buff[NI_MAXHOST];
213 list<string> external_ipv4_addresses;
214 list<string> external_ipv6_addresses;
215
216 // Get linked list of all interface addresses.
217 if ( getifaddrs(&if_addr_struct) == -1 )
4ef36a12 218 {
1d2e2f56
BS
219 Log->print_error_getting_local_wan_ip("getifaddrs", strerror(errno));
220 freeifaddrs(if_addr_struct);
4ef36a12
BS
221 return "";
222 }
3c0cd271 223
1d2e2f56
BS
224 // Iterate through the linked list.
225 for ( ifa = if_addr_struct; ifa != NULL; ifa = ifa->ifa_next)
226 {
3e0bfbf5
TJ
227 // Skip interfaces without IP addresses
228 if (!ifa->ifa_addr)
229 continue;
230
1d2e2f56
BS
231 // Get the address family of the actual address.
232 address_family = ifa->ifa_addr->sa_family;
233
234 // If it is an IPv4 then process further.
235 if ( address_family == AF_INET )
236 {
237 // Translate the address to a protocol independent representation (dottet format). Copy address into ip_addr_buff.
08a5a621 238 ret_val = getnameinfo(ifa->ifa_addr, (socklen_t)sizeof(struct sockaddr_in), ip_addr_buff, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
1d2e2f56
BS
239 if ( ret_val != 0 )
240 {
241 Log->print_error_getting_local_wan_ip("getnameinfo", gai_strerror(ret_val));
242 freeifaddrs(if_addr_struct);
243 return "";
244 }
245
246 // Generate IPv4 string out of char array.
247 string ipv4_addr(ip_addr_buff);
248
249 Log->print_own_ipv4(ipv4_addr, Hostname);
250
251 // Test if it is a local address.
252 if ( !is_local_ipv4(ipv4_addr) )
253 external_ipv4_addresses.push_back(ipv4_addr);
254 else
255 Log->print_ip_is_local(ipv4_addr);
256 }
257 // If it is an IPv6 address and IPv6 is enabled then process further.
ce70569b 258 else if ( (address_family == AF_INET6) && (UseIPv6) )
1d2e2f56
BS
259 {
260 // Translate the address to a protocol independent representation (dottet format). Copy address into ip_addr_buff.
08a5a621 261 ret_val = getnameinfo(ifa->ifa_addr, (socklen_t)sizeof(struct sockaddr_in6), ip_addr_buff, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
1d2e2f56
BS
262 if ( ret_val != 0 )
263 {
264 Log->print_error_getting_local_wan_ip("getnameinfo", gai_strerror(ret_val));
265 freeifaddrs(if_addr_struct);
266 return "";
267 }
268
269 // Generate IPv6 string out of char array.
270 string ipv6_addr(ip_addr_buff);
271
272 Log->print_own_ipv6(ipv6_addr, Hostname);
273
274 // Test if it is a local address.
275 if ( !is_local_ipv6(ipv6_addr) )
276 external_ipv6_addresses.push_back(ipv6_addr);
277 else
278 Log->print_ip_is_local(ipv6_addr);
279 }
280 }
281 freeifaddrs(if_addr_struct);
282
283 // Return the first element in IPv6 list if IPv6 is enabled, otherwise return first element in IPv4 list.
ce70569b 284 if ( (UseIPv6) && (!external_ipv6_addresses.empty()) )
1d2e2f56
BS
285 return external_ipv6_addresses.front();
286 else if ( !external_ipv4_addresses.empty() )
287 return external_ipv4_addresses.front();
288
289 return "";
0665b239
BS
290}
291
0665b239
BS
292
293/**
687d99fb 294 * Get the actual IP of the given host through a DNS query.
c3dea5dc 295 * @param _hostname The hostname for the dns lookup, if empty string, then perform a dns lookup to the local hostname.
0665b239
BS
296 * @return A string representation of the actual IP in dotted format or an empty string if something went wrong.
297 */
ad0e5016 298string IPAddrHelper::dns_query(const string& _hostname) const
0665b239 299{
1d2e2f56
BS
300 list<string> external_ipv4_addresses;
301 list<string> external_ipv6_addresses;
0665b239 302
1d2e2f56 303 // Init the hostname with the given _hostname or with local Hostname if empty.
c3dea5dc
BS
304 string hostname = Hostname;
305 if ( !_hostname.empty() )
306 hostname = _hostname;
307
0665b239
BS
308 try
309 {
310 // BOOST asio isn't the simplest way to perform a DNS lookup, but it works just fine.
311 net::io_service io_service;
312 net::ip::tcp::resolver resolver(io_service);
1d2e2f56
BS
313
314 // Define the DNS query.
315 net::ip::tcp::resolver::query query(hostname, "0", net::ip::resolver_query_base::address_configured | net::ip::resolver_query_base::all_matching);
316
317 // Perform the DNS query.
0665b239
BS
318 net::ip::tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
319 net::ip::tcp::resolver::iterator end;
1d2e2f56
BS
320
321 // Iterate through the returned IP addresses.
0665b239
BS
322 while(endpoint_iterator != end)
323 {
1d2e2f56 324 // Get the IP address out of the endpoint iterator.
687d99fb
BS
325 net::ip::address ip;
326 ip = endpoint_iterator->endpoint().address();
1d2e2f56
BS
327
328 // Test if it is a IPv4 address.
0665b239 329 if ( ip.is_v4() )
1d2e2f56
BS
330 {
331 // Get the string representation.
332 string ipv4_addr = ip.to_string();
333
334 Log->print_own_ipv4(ipv4_addr, hostname);
335
336 // If it is not a local address then push it in the external ipv4 address list.
2f83caa3 337 //if ( !is_local_ipv4(ipv4_addr) )
1d2e2f56 338 external_ipv4_addresses.push_back(ipv4_addr);
2f83caa3
BS
339 //else
340 // Log->print_ip_is_local(ipv4_addr);
1d2e2f56
BS
341 }
342 // Test if it is a IPv6 address and if IPv6 is enabled.
ce70569b 343 else if ( (ip.is_v6()) && (UseIPv6) )
1d2e2f56
BS
344 {
345 // Get the string representation.
346 string ipv6_addr = ip.to_string();
347
348 Log->print_own_ipv6(ipv6_addr, hostname);
349
350 // If it is not a local address then push it in the external ipv6 address list.
2f83caa3 351 //if ( !is_local_ipv6(ipv6_addr) )
1d2e2f56 352 external_ipv6_addresses.push_back(ipv6_addr);
2f83caa3
BS
353 //else
354 // Log->print_ip_is_local(ipv6_addr);
1d2e2f56 355 }
0665b239
BS
356 endpoint_iterator++;
357 }
358 io_service.reset();
359 }
ce70569b 360 catch(const exception& e)
0665b239 361 {
c3dea5dc 362 Log->print_error_hostname_to_ip(e.what(),hostname);
0665b239
BS
363 return "";
364 }
365
1d2e2f56 366 // Return the first element in IPv6 list if IPv6 is enabled, otherwise return first element in IPv4 list.
ce70569b 367 if ( (UseIPv6) && (!external_ipv6_addresses.empty()) )
1d2e2f56
BS
368 return external_ipv6_addresses.front();
369 else if ( !external_ipv4_addresses.empty() )
370 return external_ipv4_addresses.front();
0665b239 371
1d2e2f56
BS
372 // Could not get a external IP address, so return empty string.
373 return "";
0665b239
BS
374}
375
376
377/**
378 * Get the actual IP of this host through a IP webcheck URL.
3c4705d9 379 * @param changed_to_online Indicates if we just went online
0665b239
BS
380 * @return A string representation of the actual IP in dotted format or an empty string if something went wrong.
381 */
3c4705d9 382string IPAddrHelper::webcheck_ip(bool changed_to_online)
0665b239 383{
2b0f7c11 384 // Init IPAddress with a empty string.
1c0908b5
BS
385 string ip_addr = "";
386
2b0f7c11 387 // Get the current time.
ce70569b 388 time_t current_time = time(NULL);
2b0f7c11
BS
389
390 // Test if webcheck is allowed due to webcheck_interval.
3c4705d9
TJ
391 // Ignored if we just went online.
392 if ( !changed_to_online && (LastWebcheck + ((time_t)WebcheckInterval*60)) >= current_time )
2b0f7c11
BS
393 {
394 // Webcheck not allowed, log it and return empty string.
395 Log->print_webcheck_exceed_interval( LastWebcheck, (WebcheckInterval*60), current_time );
1d2e2f56 396 return "";
2b0f7c11
BS
397 }
398
1c0908b5
BS
399 // Init CURL buffers
400 string curl_writedata_buff;
401 char curl_err_buff[CURL_ERROR_SIZE];
402 int curl_err_code=1;
403
404 // Init URL List
405 list<string> url_list;
406 url_list.push_back(WebcheckIpUrl);
407 url_list.push_back(WebcheckIpUrlAlt);
408 string actual_url;
409
410 // Init CURL
411 CURL * curl_easy_handle = init_curl(curl_writedata_buff,curl_err_buff);
ce70569b
BS
412 if ( curl_easy_handle == NULL )
413 {
414 return "";
415 }
1c0908b5 416
d43bb54d
TJ
417 // Set the LastWebcheck time to current time.
418 LastWebcheck = current_time;
419
1c0908b5
BS
420 // If perform_curl_operation returns a connection problem indicating return code, try the next ip webcheck url if there is one.
421 while ( (curl_err_code == 1) && (url_list.size() != 0) && (url_list.front() != "") )
422 {
423 // Set URL
424 actual_url = url_list.front();
425 url_list.pop_front();
c730deea
BS
426 if (set_curl_url(curl_easy_handle,actual_url) == CURLE_OK )
427 {
428 // Perform curl operation, err_code of 1 indicated connection problem, so try next url.
429 curl_err_code = perform_curl_operation(curl_easy_handle, curl_err_buff, actual_url);
430 }
1c0908b5
BS
431 }
432
433 // Cleanup CURL handle
434 curl_easy_cleanup(curl_easy_handle);
435
436 // If curl_err_code is not 0, the ip couldn't be determined through any configured webcheck url.
437 if ( curl_err_code != 0 )
438 {
2b0f7c11 439 // Log it and return the empty string.
1c0908b5 440 Log->print_webcheck_no_ip();
1d2e2f56 441 return "";
1c0908b5
BS
442 }
443
2b0f7c11 444 // Log the received curl data.
1c0908b5
BS
445 Log->print_received_curl_data(curl_writedata_buff);
446
1d2e2f56
BS
447 // Try to parse a IPv4 address out of the received data.
448 ip_addr = parse_ipv4(curl_writedata_buff);
449
5ad93dad
BS
450 // TODO: Parsing of IPv6 address out of received curl data via webcheck IP.
451
1d2e2f56
BS
452 if ( !ip_addr.empty() )
453 {
454 // Got a IPv4 address out of the received data.
455 Log->print_own_ipv4(ip_addr, Hostname);
456 }
457 else
458 {
459 return "";
460 }
0665b239 461
1d2e2f56
BS
462 // If IP is within a private range then return ""
463 if ( is_local_ipv4(ip_addr) )
464 {
465 Log->print_ip_is_local(ip_addr);
466 return "";
467 }
468
2b0f7c11 469 // Return the parsed IPAddress.
0665b239
BS
470 return ip_addr;
471}
1c0908b5
BS
472
473
474/**
1d2e2f56 475 * Tries to find a IPv4 Address in dottet format in a given string and returns the IP-Address found.
1c0908b5
BS
476 * @param data The string data to search in for a valid IPv4-Address.
477 * @return The IP Address found or an empty string.
478 */
1d2e2f56 479string IPAddrHelper::parse_ipv4(const string& data) const
1c0908b5
BS
480{
481 string ip = "";
482
1d2e2f56 483 // Regex for ipv4 address in dottet format
1c0908b5
BS
484 boost::regex expr("([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3})");
485
486 boost::smatch matches;
487
488 if ( boost::regex_search(data,matches,expr) )
489 {
490 ip = matches[1];
1d2e2f56 491 Log->print_regex_match(expr.str(),ip);
1c0908b5
BS
492 }
493 else
494 {
495 Log->print_regex_ip_not_found(data);
496 }
497
498 return ip;
499}
500
501
502/**
503 * Performs the curl operation.
504 * @param curl_easy_handle The initialized and configured curl handle.
505 * @param curl_err_buff The pointer to the curl error buffer to get error messages from.
506 * @param actual_url The actual configured URL.
507 * @return 0 if all is fine, 1 if an connection problem to the configured url occurs, -1 on other errors.
508 */
ce70569b 509int IPAddrHelper::perform_curl_operation(CURL * curl_easy_handle, const char* curl_err_buff, const string& actual_url) const
1c0908b5 510{
ce70569b
BS
511 CURLcode curl_err_code;
512 if ( (curl_err_code = curl_easy_perform(curl_easy_handle) ) != CURLE_OK )
1c0908b5 513 {
de5e00b1 514 // CURL error occurred
1c0908b5
BS
515 if ( (curl_err_code == CURLE_COULDNT_CONNECT) || (curl_err_code == CURLE_OPERATION_TIMEOUTED) || (curl_err_code == CURLE_COULDNT_RESOLVE_HOST) )
516 {
517 // In case of connection problems we should return 1, that the fallback url will be used.
518 Log->print_webcheck_url_connection_problem(curl_err_buff, actual_url);
519 return 1;
520 }
521 else
522 {
523 // other error
524 Log->print_webcheck_error(curl_err_buff, actual_url);
525 return -1;
526 }
527 }
528 // Operation performed without any problems
529 return 0;
530}
531
532
533/**
534 * Sets a url to the easy curl handle
535 * @param curl_easy_handle The easy curl handle to set the url for.
536 * @param url The url to set.
c730deea 537 * @return CURLcode Curl Error code, CURLE_OK if everything is right.
1c0908b5 538 */
c730deea 539CURLcode IPAddrHelper::set_curl_url(CURL * curl_easy_handle, const string& url) const
1c0908b5 540{
c730deea
BS
541 CURLcode curl_error = CURLE_OK;
542
543 if ( curl_easy_handle != NULL )
544 {
545 curl_error = curl_easy_setopt(curl_easy_handle,CURLOPT_URL,url.c_str());
546 if ( curl_error != CURLE_OK )
547 {
548 // Some options could not be set, so destroy the CURL handle.
549 Log->print_curl_error_init("Could not set CURL URL properly.",curl_error);
550 }
551 }
552 return curl_error;
1c0908b5
BS
553}
554
555
556/**
557 * Initialized curl easy handle with a few options.
558 * @param curl_writedata_buff Reference to a string wich will be filled with the curl result
559 * @param curl_err_buff A pointer to an char array which will be filled with error message.
560 * @return A pointer to the easy curl handle.
561 */
ad0e5016 562CURL * IPAddrHelper::init_curl(string& curl_writedata_buff,char* curl_err_buff) const
1c0908b5 563{
0e080ce3 564 ostringstream user_agent_stream;
1dc0bc9b 565 user_agent_stream << "Intra2net AG - Bullet Proof DYNDNS Daemon - " << MAJOR_VERSION << "." << MINOR_VERSION;
0e080ce3 566 string user_agent = user_agent_stream.str();
ce70569b 567
1c0908b5 568 CURL *curl_easy_handle = curl_easy_init();
ce70569b
BS
569 if ( curl_easy_handle == NULL )
570 {
571 // something went wrong.
572 Log->print_curl_error_init("Could not initialize CURL object.",CURLE_FAILED_INIT);
573 return NULL;
574 }
1c0908b5 575
08a5a621 576 CURLcode curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_NOPROGRESS,1);
ce70569b
BS
577 if ( curlError == CURLE_OK)
578 curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_CONNECTTIMEOUT,5);
579 if ( curlError == CURLE_OK)
580 curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_TIMEOUT,10);
581 if ( curlError == CURLE_OK)
582 curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_BUFFERSIZE,1024);
583 if ( curlError == CURLE_OK)
584 curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_ERRORBUFFER,curl_err_buff);
585 if ( curlError == CURLE_OK)
586 curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_WRITEFUNCTION,http_receive);
587 if ( curlError == CURLE_OK)
588 curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_WRITEDATA,&curl_writedata_buff);
589 if ( curlError == CURLE_OK)
0e080ce3 590 curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_USERAGENT,user_agent.c_str());
1c0908b5 591
4eb87664
BS
592 if ( !Proxy.empty() )
593 {
ce70569b
BS
594 if ( curlError == CURLE_OK)
595 curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_PROXY,Proxy.c_str());
596 if ( curlError == CURLE_OK)
597 curlError = curl_easy_setopt(curl_easy_handle,CURLOPT_PROXYPORT,ProxyPort);
598 }
599
600 if ( curlError != CURLE_OK )
601 {
602 // Some options could not be set, so destroy the CURL handle.
603 Log->print_curl_error_init("Could not set CURL options properly.",curlError);
604 curl_easy_cleanup(curl_easy_handle);
605 curl_easy_handle = NULL;
4eb87664
BS
606 }
607
1c0908b5
BS
608 return curl_easy_handle;
609}
610
611
612/**
613 * Callback Function is called every time CURL is receiving data from HTTPS-Server and will copy all received Data to the given stream pointer
614 * @param inBuffer Pointer to input.
615 * @param size How many mem blocks are received
616 * @param nmemb size of each memblock
617 * @param outBuffer Pointer to output stream.
618 * @return The size received.
619 */
0955e6a2 620size_t IPAddrHelper::http_receive( void *inBuffer, size_t size, size_t nmemb, string *outBuffer )
1c0908b5 621{
0955e6a2 622 outBuffer->append(static_cast<char *>(inBuffer), size*nmemb);
1c0908b5 623 return (size*nmemb);
0955e6a2 624} //lint !e818
20399847
BS
625
626
627/**
628 * Get member LastWebcheck
629 * @return LastWebcheck
630 */
08a5a621 631time_t IPAddrHelper::get_last_webcheck() const
20399847
BS
632{
633 return LastWebcheck;
634}