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