1 #pragma once 2 3 #include "biboumi.h" 4 5 #include <functional> 6 #include <vector> 7 #include <memory> 8 #include <string> 9 10 #include <sys/types.h> 11 #include <sys/socket.h> 12 #include <netdb.h> 13 #ifdef UDNS_FOUND 14 # include <udns.h> 15 #endif 16 17 class AddrinfoDeleter 18 { 19 public: operator ()(struct addrinfo * addr)20 void operator()(struct addrinfo* addr) 21 { 22 freeaddrinfo(addr); 23 } 24 }; 25 26 27 class Resolver 28 { 29 public: 30 31 using ErrorCallbackType = std::function<void(const char*)>; 32 using SuccessCallbackType = std::function<void(const struct addrinfo*)>; 33 34 Resolver(); 35 ~Resolver() = default; 36 Resolver(const Resolver&) = delete; 37 Resolver(Resolver&&) = delete; 38 Resolver& operator=(const Resolver&) = delete; 39 Resolver& operator=(Resolver&&) = delete; 40 is_resolving() const41 bool is_resolving() const 42 { 43 #ifdef UDNS_FOUND 44 return this->resolving; 45 #else 46 return false; 47 #endif 48 } 49 is_resolved() const50 bool is_resolved() const 51 { 52 return this->resolved; 53 } 54 get_result() const55 const auto& get_result() const 56 { 57 return this->addr; 58 } get_error_message() const59 std::string get_error_message() const 60 { 61 return this->error_msg; 62 } 63 clear()64 void clear() 65 { 66 #ifdef UDNS_FOUND 67 this->resolved6 = false; 68 this->resolved4 = false; 69 this->resolving = false; 70 this->port.clear(); 71 #endif 72 this->resolved = false; 73 this->addr.reset(); 74 this->error_msg.clear(); 75 } 76 77 void resolve(const std::string& hostname, const std::string& port, 78 SuccessCallbackType success_cb, ErrorCallbackType error_cb); 79 80 private: 81 void start_resolving(const std::string& hostname, const std::string& port); 82 std::vector<std::string> look_in_etc_hosts(const std::string& hostname); 83 /** 84 * Call getaddrinfo() on the given hostname or IP, and append the result 85 * to our internal addrinfo list. Return getaddrinfo()’s return value. 86 */ 87 int call_getaddrinfo(const char* name, const char* port, int flags); 88 89 #ifdef UDNS_FOUND 90 void on_hostname4_resolved(dns_rr_a4 *result); 91 void on_hostname6_resolved(dns_rr_a6 *result); 92 /** 93 * Called after one record (4 or 6) has been resolved. 94 */ 95 void after_resolved(); 96 97 void start_timer(); 98 99 void on_resolved(); 100 101 bool resolved4; 102 bool resolved6; 103 104 bool resolving; 105 106 std::string port; 107 108 #endif 109 /** 110 * Tells if we finished the resolution process. It doesn't indicate if it 111 * was successful (it is true even if the result is an error). 112 */ 113 bool resolved; 114 std::string error_msg; 115 116 std::unique_ptr<struct addrinfo, AddrinfoDeleter> addr; 117 118 ErrorCallbackType error_cb; 119 SuccessCallbackType success_cb; 120 }; 121 122 std::string addr_to_string(const struct addrinfo* rp); 123