77 if (ai->ai_family == AF_INET) return inet_ntop(ai->ai_family, &((sockaddr_in const *) ai->ai_addr)->sin_addr, buffer, sizeof (buffer)); // TODO: check 0 result |
77 if (ai->ai_family == AF_INET) return inet_ntop(ai->ai_family, &((sockaddr_in const *) ai->ai_addr)->sin_addr, buffer, sizeof (buffer)); // TODO: check 0 result |
78 else if (ai->ai_family == AF_INET6) return inet_ntop(ai->ai_family, &((sockaddr_in6 const *) ai->ai_addr)->sin6_addr, buffer, sizeof (buffer)); // TODO: check 0 result |
78 else if (ai->ai_family == AF_INET6) return inet_ntop(ai->ai_family, &((sockaddr_in6 const *) ai->ai_addr)->sin6_addr, buffer, sizeof (buffer)); // TODO: check 0 result |
79 else throw std::logic_error("Invalid address family: " + std::to_string(ai->ai_family)); |
79 else throw std::logic_error("Invalid address family: " + std::to_string(ai->ai_family)); |
80 } |
80 } |
81 |
81 |
|
82 class AddressInfos { |
|
83 private: |
|
84 struct addrinfo* addrInfo; |
|
85 |
|
86 AddressInfos(addrinfo* addrInfo) : addrInfo(addrInfo) { |
|
87 std::cerr << " AddressInfo()" << std::endl; |
|
88 } |
|
89 |
|
90 public: |
|
91 |
|
92 virtual ~AddressInfos() { |
|
93 std::cerr << " ~AddressInfo()" << std::endl; |
|
94 freeaddrinfo(addrInfo); |
|
95 } |
|
96 |
|
97 class AddressInfo { |
|
98 public: |
|
99 const addrinfo* const ai; |
|
100 |
|
101 AddressInfo(const addrinfo* const ai) : ai(ai) {} |
|
102 }; |
|
103 |
|
104 static AddressInfos getAddressInfo(const std::string& host, const std::string& port) { |
|
105 struct addrinfo query; |
|
106 memset(&query, sizeof (query), 0); |
|
107 query.ai_family = AF_UNSPEC; |
|
108 query.ai_socktype = SOCK_STREAM; |
|
109 query.ai_protocol = IPPROTO_TCP; |
|
110 query.ai_flags = AI_ALL; |
|
111 |
|
112 struct addrinfo* addrInfo; |
|
113 check(getaddrinfo(host.c_str(), port.c_str(), &query, &addrInfo), "getaddrinfo"); |
|
114 |
|
115 return AddressInfos(addrInfo); |
|
116 } |
|
117 |
|
118 const sockaddr* getSocketAddress() { |
|
119 return addrInfo->ai_addr; |
|
120 } |
|
121 |
|
122 const std::size_t size() const { |
|
123 std::size_t size = 0; |
|
124 for (addrinfo* ai = addrInfo; ai; ai = ai->ai_next) size++; |
|
125 return size; |
|
126 } |
|
127 |
|
128 const addrinfo& operator[](std::size_t index) const { |
|
129 for (addrinfo* ai = addrInfo; ai; index--) { |
|
130 if (index == 0) return *ai; |
|
131 else ai = ai->ai_next; |
|
132 } |
|
133 |
|
134 throw std::out_of_range("invalid index for AddressInfo: " + std::to_string(index)); |
|
135 } |
|
136 |
|
137 }; |
|
138 |
82 static in_addr_t getAddress(const std::string& host) { |
139 static in_addr_t getAddress(const std::string& host) { |
|
140 |
|
141 { |
|
142 AddressInfos ai = AddressInfos::getAddressInfo("::0ff2", "smtp"); |
|
143 std::cerr << "AddressInfo size = " << ai.size() << std::endl; |
|
144 for (size_t i = 0, limit = ai.size(); i < limit; i++) { |
|
145 std::cerr << "AddressInfo: " << ip2string(&ai[i]) << std::endl; |
|
146 } |
|
147 } |
|
148 |
|
149 |
|
150 |
83 |
151 |
84 struct addrinfo query; |
152 struct addrinfo query; |
85 memset(&query, sizeof (query), 0); |
153 memset(&query, sizeof (query), 0); |
86 query.ai_family = AF_INET; |
154 query.ai_family = AF_UNSPEC; |
87 query.ai_socktype = SOCK_STREAM; |
155 query.ai_socktype = SOCK_STREAM; |
88 query.ai_protocol = IPPROTO_TCP; |
156 query.ai_protocol = IPPROTO_TCP; |
89 query.ai_flags = AI_ALL; |
157 query.ai_flags = AI_ALL; |
90 |
158 |
91 struct addrinfo* addrInfo; |
159 struct addrinfo* addrInfo; |