MySQL 8.2.0
Source Code Documentation
resolver.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2020, 2023, Oracle and/or its affiliates.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2.0,
6 as published by the Free Software Foundation.
7
8 This program is also distributed with certain software (including
9 but not limited to OpenSSL) that is licensed under separate terms,
10 as designated in a particular file or component or in included license
11 documentation. The authors of MySQL hereby grant you an additional
12 permission to link the program and your derivative works with the
13 separately licensed software that they have included with MySQL.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
23*/
24#ifndef MYSQL_HARNESS_NET_TS_IMPL_RESOLVER_H_
25#define MYSQL_HARNESS_NET_TS_IMPL_RESOLVER_H_
26
27#include <algorithm>
28#include <memory> // unique_ptr
29#include <string>
30#include <system_error>
31
32#ifdef _WIN32
33#include <WinSock2.h>
34#include <windows.h>
35#include <ws2tcpip.h> // addrinfo
36#else
37#include <arpa/inet.h> // inet_ntop
38#include <netdb.h> // getaddrinfo
39#include <unistd.h> // gethostname
40#endif
41
42#include "mysql/harness/net_ts/impl/socket_error.h" // socket::last_error_code
44
45namespace net {
46namespace ip {
47enum class resolver_errc {
48 try_again = EAI_AGAIN, //!< name could not be resolved at this time
49 bad_flags = EAI_BADFLAGS, //!< flags parameter had an invalid value
50#ifdef EAI_BADHINTS
51 // freebsd, macosx
52 bad_hints = EAI_BADHINTS, //!< invalid value for hints
53#endif
54#ifdef EAI_ADDRFAMILY
55 // glibc, (removed in freebsd), solaris, macosx
56 bad_address_family =
57 EAI_ADDRFAMILY, //!< address family for NAME not supported
58#endif
59 fail = EAI_FAIL, //!< non recoverable failed on name resolution
60 bad_family = EAI_FAMILY, //!< ai_family not supported
61 out_of_memory = EAI_MEMORY, //!< memory allocation failed
62#ifdef EAI_NODATA
63 // glibc, (removed in freebsd), solaris, macosx
64 no_data = EAI_NODATA, //!< no address associated with NAME
65#endif
66 host_not_found = EAI_NONAME, //!< NAME or SERVICE is unknown
67#ifdef EAI_OVERFLOW
68 // glibc, freebsd, solaris, macosx, musl
69 overflow = EAI_OVERFLOW, //!< argument buffer overflow
70#endif
71#ifdef EAI_PROTOCOL
72 // glibc, freebsd, solaris, macosx
73 bad_protocol = EAI_PROTOCOL, //!< resolved protocol unknown
74#endif
75#ifdef EAI_CANCELED
76 // glibc
77 cancelled = EAI_CANCELED, //!< request cancelled
78#endif
79#ifdef EAI_NOTCANCELED
80 // glibc
81 not_cancelled = EAI_NOTCANCELED, //!< request not cancelled
82#endif
83#ifdef EAI_INPROGRESS
84 // glibc
85 in_progress = EAI_INPROGRESS, //!< request in progress
86#endif
87#ifdef EAI_ALLDONE
88 // glibc
89 all_done = EAI_ALLDONE, //!< all done
90#endif
91#ifdef EAI_INTR
92 // glibc
93 interrupted = EAI_INTR, //!< interrupted
94#endif
95#ifdef EAI_IDN_ENCODE
96 // glibc
97 idn_encode_failed = EAI_IDN_ENCODE, //!< IDN encode failed
98#endif
99 service_not_found = EAI_SERVICE, //!< SERVICE not supported for ai_socktype
100 bad_socktype = EAI_SOCKTYPE, //!< ai_socktype not supported
101};
102} // namespace ip
103} // namespace net
104
105namespace std {
106template <>
107struct is_error_code_enum<net::ip::resolver_errc> : true_type {};
108} // namespace std
109
110namespace net {
111namespace ip {
112inline const std::error_category &resolver_category() noexcept {
113 class category_impl : public std::error_category {
114 public:
115 const char *name() const noexcept override { return "resolver"; }
116 std::string message(int ev) const override { return gai_strerror(ev); }
117
118 // MSDN says:
119 //
120 // EAI_AGAIN == WSATRY_AGAIN
121 // EAI_BADFLAGS == WSAEINVAL
122 // EAI_FAIL == WSANO_RECOVERY
123 // EAI_FAMILY == WSAEAFNOSUPPORT
124 // EAI_MEMORY == WSA_NOT_ENOUGH_MEMORY
125 // EAI_NONAME == WSAHOST_NOT_FOUND
126 // EAI_SERVICE == WSATYPE_NOT_FOUND
127 // EAI_SOCKTYPE == WSAESOCKTNOTSUPPORT
128 };
129
130 static category_impl instance;
131 return instance;
132}
133
134inline std::error_code make_error_code(resolver_errc ec) {
135 return {static_cast<int>(ec), resolver_category()};
136}
137} // namespace ip
138
139namespace impl {
140namespace resolver {
141
142/**
143 * get hostname.
144 *
145 * @returns void on success, the native function's error-code on error
146 * @retval std::errc::filename_too_long if the buffer is too small to contain
147 * the hostname + nul-char
148 *
149 */
151 size_t buf_len) {
152 if (0 != ::gethostname(buf, buf_len)) {
154 }
155
156 // POSIX says that it is unspecified if the returned string contains
157 // a \0 char if truncation occurred.
158 //
159 // Looks like only Solaris doesn't add \0 and doesn't return an error.
160 //
161 const auto begin = buf;
162 const auto end = buf + buf_len;
163
164 if (end == std::find(begin, end, '\0')) {
166 std::error_code(make_error_code(std::errc::filename_too_long)));
167 }
168
169 return {};
170}
171
173 const struct sockaddr *saddr, socklen_t addrlen, char *host,
174 socklen_t hostlen, char *serv, socklen_t servlen, int flags) {
175#if defined(__APPLE__)
176 // macosx doesn't check the 'addrlen' parameter and reads garbage.
177
178 if (addrlen < sizeof(*saddr)) {
181 }
182
183 if ((saddr->sa_family == AF_INET && addrlen < sizeof(sockaddr_in)) ||
184 (saddr->sa_family == AF_INET6 && addrlen < sizeof(sockaddr_in6))) {
187 }
188#endif
189
190 int ret = ::getnameinfo(saddr, addrlen, host, hostlen, serv, servlen, flags);
191 if (ret != 0) {
192#ifdef EAI_SYSTEM
193 // linux, freebsd, solaris, macosx
194 if (ret == EAI_SYSTEM) {
196 } else {
198 std::error_code{ret, net::ip::resolver_category()});
199 }
200#else
201#if defined(_WIN32)
202 switch (ret) {
203 case EAI_AGAIN:
204 case EAI_BADFLAGS:
205 case EAI_FAIL:
206 case EAI_FAMILY:
207 case EAI_MEMORY:
208 case EAI_NONAME:
209 case EAI_SERVICE:
210 case EAI_SOCKTYPE:
211 break;
212 default:
214 std::error_code{ret, std::system_category()});
215 }
216#endif
218 std::error_code{ret, net::ip::resolver_category()});
219#endif
220 }
221
222 return {};
223}
224
225inline stdx::expected<
226 std::unique_ptr<struct addrinfo, void (*)(struct addrinfo *)>,
227 std::error_code>
228getaddrinfo(const char *node, const char *service,
229 const struct addrinfo *hints) {
230 struct addrinfo *ainfo{nullptr};
231
232 int ret = ::getaddrinfo(node, service, hints, &ainfo);
233 if (ret != 0) {
234#ifdef EAI_SYSTEM
235 // linux, freebsd, solaris, macosx
236 if (ret == EAI_SYSTEM) {
238 } else {
240 std::error_code{ret, net::ip::resolver_category()});
241 }
242#else
243#if defined(_WIN32)
244 switch (ret) {
245 case EAI_AGAIN:
246 case EAI_BADFLAGS:
247 case EAI_FAIL:
248 case EAI_FAMILY:
249 case EAI_MEMORY:
250 case EAI_NONAME:
251 case EAI_SERVICE:
252 case EAI_SOCKTYPE:
253 break;
254 default:
256 std::error_code{ret, std::system_category()});
257 }
258#endif
260 std::error_code{ret, net::ip::resolver_category()});
261#endif
262 }
263
264 return {std::in_place, ainfo, &::freeaddrinfo};
265}
266
268 const void *src,
269 char *out,
270 size_t out_len) {
271 if (nullptr == ::inet_ntop(af, src, out, out_len)) {
273 }
274 return out;
275}
276
277// # async getaddrinfo
278//
279// windows has GetAddrInfoEx
280// linux has getaddrinfo_a
281// freebsd has getaddrinfo_async
282
283} // namespace resolver
284} // namespace impl
285
286} // namespace net
287
288#endif
Definition: expected.h:943
static char buf[MAX_BUF]
Definition: conf_to_src.cc:72
static int flags[50]
Definition: hp_test1.cc:39
const char * host
Definition: mysqladmin.cc:63
static bool interrupted
Definition: mysqladmin.cc:70
void * begin(THD *thd, const TABLE *table, size_t data_size, size_t memory, size_t num_threads) noexcept
Definition: bulk_data_service.cc:1533
Definition: buf0block_hint.cc:29
const byte * find(const Pages *pages, const page_id_t &page_id) noexcept
Find a doublewrite copy of a page.
Definition: buf0dblwr.cc:3578
bool in_progress()
Check if upgrade is in progress.
Definition: upgrade.cc:113
Definition: authentication.cc:35
stdx::expected< std::unique_ptr< struct addrinfo, void(*)(struct addrinfo *)>, std::error_code > getaddrinfo(const char *node, const char *service, const struct addrinfo *hints)
Definition: resolver.h:228
stdx::expected< const char *, std::error_code > inetntop(int af, const void *src, char *out, size_t out_len)
Definition: resolver.h:267
stdx::expected< void, std::error_code > gethostname(char *buf, size_t buf_len)
get hostname.
Definition: resolver.h:150
stdx::expected< void, std::error_code > getnameinfo(const struct sockaddr *saddr, socklen_t addrlen, char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags)
Definition: resolver.h:172
std::error_code last_error_code()
get last std::error_code for socket-errors.
Definition: socket_error.h:106
resolver_errc
Definition: resolver.h:47
@ bad_socktype
ai_socktype not supported
@ host_not_found
NAME or SERVICE is unknown.
@ bad_flags
flags parameter had an invalid value
@ service_not_found
SERVICE not supported for ai_socktype.
@ out_of_memory
memory allocation failed
@ try_again
name could not be resolved at this time
@ fail
non recoverable failed on name resolution
@ bad_family
ai_family not supported
const std::error_category & resolver_category() noexcept
Definition: resolver.h:112
std::error_code make_error_code(resolver_errc ec)
Definition: resolver.h:134
Definition: buffer.h:44
std::error_code make_error_code(net::stream_errc e) noexcept
Definition: buffer.h:102
Definition: varlen_sort.h:183
constexpr auto make_unexpected(E &&e) -> unexpected< std::decay_t< E > >
Definition: expected.h:124
std::conditional_t< !std::is_array< T >::value, std::unique_ptr< T, detail::Deleter< T > >, std::conditional_t< detail::is_unbounded_array_v< T >, std::unique_ptr< T, detail::Array_deleter< std::remove_extent_t< T > > >, void > > unique_ptr
The following is a common type that is returned by all the ut::make_unique (non-aligned) specializati...
Definition: ut0new.h:2437
struct sockaddr sockaddr
Definition: sock_probe_win32.h:62
case opt name
Definition: sslopt-case.h:32