1 //
2 // ip/basic_resolver.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
6 //
7 // Distributed under the Boost Software License, Version 1.0. (See accompanying
8 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 //
10 
11 #ifndef BOOST_ASIO_IP_BASIC_RESOLVER_HPP
12 #define BOOST_ASIO_IP_BASIC_RESOLVER_HPP
13 
14 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
15 # pragma once
16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
17 
18 #include <boost/asio/detail/config.hpp>
19 #include <string>
20 #include <boost/asio/any_io_executor.hpp>
21 #include <boost/asio/async_result.hpp>
22 #include <boost/asio/detail/handler_type_requirements.hpp>
23 #include <boost/asio/detail/io_object_impl.hpp>
24 #include <boost/asio/detail/non_const_lvalue.hpp>
25 #include <boost/asio/detail/string_view.hpp>
26 #include <boost/asio/detail/throw_error.hpp>
27 #include <boost/asio/error.hpp>
28 #include <boost/asio/execution_context.hpp>
29 #include <boost/asio/ip/basic_resolver_iterator.hpp>
30 #include <boost/asio/ip/basic_resolver_query.hpp>
31 #include <boost/asio/ip/basic_resolver_results.hpp>
32 #include <boost/asio/ip/resolver_base.hpp>
33 #if defined(BOOST_ASIO_WINDOWS_RUNTIME)
34 # include <boost/asio/detail/winrt_resolver_service.hpp>
35 #else
36 # include <boost/asio/detail/resolver_service.hpp>
37 #endif
38 
39 #if defined(BOOST_ASIO_HAS_MOVE)
40 # include <utility>
41 #endif // defined(BOOST_ASIO_HAS_MOVE)
42 
43 #include <boost/asio/detail/push_options.hpp>
44 
45 namespace boost {
46 namespace asio {
47 namespace ip {
48 
49 #if !defined(BOOST_ASIO_IP_BASIC_RESOLVER_FWD_DECL)
50 #define BOOST_ASIO_IP_BASIC_RESOLVER_FWD_DECL
51 
52 // Forward declaration with defaulted arguments.
53 template <typename InternetProtocol, typename Executor = any_io_executor>
54 class basic_resolver;
55 
56 #endif // !defined(BOOST_ASIO_IP_BASIC_RESOLVER_FWD_DECL)
57 
58 /// Provides endpoint resolution functionality.
59 /**
60  * The basic_resolver class template provides the ability to resolve a query
61  * to a list of endpoints.
62  *
63  * @par Thread Safety
64  * @e Distinct @e objects: Safe.@n
65  * @e Shared @e objects: Unsafe.
66  */
67 template <typename InternetProtocol, typename Executor>
68 class basic_resolver
69   : public resolver_base
70 {
71 public:
72   /// The type of the executor associated with the object.
73   typedef Executor executor_type;
74 
75   /// Rebinds the resolver type to another executor.
76   template <typename Executor1>
77   struct rebind_executor
78   {
79     /// The resolver type when rebound to the specified executor.
80     typedef basic_resolver<InternetProtocol, Executor1> other;
81   };
82 
83   /// The protocol type.
84   typedef InternetProtocol protocol_type;
85 
86   /// The endpoint type.
87   typedef typename InternetProtocol::endpoint endpoint_type;
88 
89 #if !defined(BOOST_ASIO_NO_DEPRECATED)
90   /// (Deprecated.) The query type.
91   typedef basic_resolver_query<InternetProtocol> query;
92 
93   /// (Deprecated.) The iterator type.
94   typedef basic_resolver_iterator<InternetProtocol> iterator;
95 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
96 
97   /// The results type.
98   typedef basic_resolver_results<InternetProtocol> results_type;
99 
100   /// Construct with executor.
101   /**
102    * This constructor creates a basic_resolver.
103    *
104    * @param ex The I/O executor that the resolver will use, by default, to
105    * dispatch handlers for any asynchronous operations performed on the
106    * resolver.
107    */
basic_resolver(const executor_type & ex)108   explicit basic_resolver(const executor_type& ex)
109     : impl_(0, ex)
110   {
111   }
112 
113   /// Construct with execution context.
114   /**
115    * This constructor creates a basic_resolver.
116    *
117    * @param context An execution context which provides the I/O executor that
118    * the resolver will use, by default, to dispatch handlers for any
119    * asynchronous operations performed on the resolver.
120    */
121   template <typename ExecutionContext>
basic_resolver(ExecutionContext & context,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)122   explicit basic_resolver(ExecutionContext& context,
123       typename constraint<
124         is_convertible<ExecutionContext&, execution_context&>::value
125       >::type = 0)
126     : impl_(0, 0, context)
127   {
128   }
129 
130 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
131   /// Move-construct a basic_resolver from another.
132   /**
133    * This constructor moves a resolver from one object to another.
134    *
135    * @param other The other basic_resolver object from which the move will
136    * occur.
137    *
138    * @note Following the move, the moved-from object is in the same state as if
139    * constructed using the @c basic_resolver(const executor_type&) constructor.
140    */
basic_resolver(basic_resolver && other)141   basic_resolver(basic_resolver&& other)
142     : impl_(std::move(other.impl_))
143   {
144   }
145 
146   // All resolvers have access to each other's implementations.
147   template <typename InternetProtocol1, typename Executor1>
148   friend class basic_resolver;
149 
150   /// Move-construct a basic_resolver from another.
151   /**
152    * This constructor moves a resolver from one object to another.
153    *
154    * @param other The other basic_resolver object from which the move will
155    * occur.
156    *
157    * @note Following the move, the moved-from object is in the same state as if
158    * constructed using the @c basic_resolver(const executor_type&) constructor.
159    */
160   template <typename Executor1>
basic_resolver(basic_resolver<InternetProtocol,Executor1> && other,typename constraint<is_convertible<Executor1,Executor>::value>::type=0)161   basic_resolver(basic_resolver<InternetProtocol, Executor1>&& other,
162       typename constraint<
163           is_convertible<Executor1, Executor>::value
164       >::type = 0)
165     : impl_(std::move(other.impl_))
166   {
167   }
168 
169   /// Move-assign a basic_resolver from another.
170   /**
171    * This assignment operator moves a resolver from one object to another.
172    * Cancels any outstanding asynchronous operations associated with the target
173    * object.
174    *
175    * @param other The other basic_resolver object from which the move will
176    * occur.
177    *
178    * @note Following the move, the moved-from object is in the same state as if
179    * constructed using the @c basic_resolver(const executor_type&) constructor.
180    */
operator =(basic_resolver && other)181   basic_resolver& operator=(basic_resolver&& other)
182   {
183     impl_ = std::move(other.impl_);
184     return *this;
185   }
186 
187   /// Move-assign a basic_resolver from another.
188   /**
189    * This assignment operator moves a resolver from one object to another.
190    * Cancels any outstanding asynchronous operations associated with the target
191    * object.
192    *
193    * @param other The other basic_resolver object from which the move will
194    * occur.
195    *
196    * @note Following the move, the moved-from object is in the same state as if
197    * constructed using the @c basic_resolver(const executor_type&) constructor.
198    */
199   template <typename Executor1>
200   typename constraint<
201     is_convertible<Executor1, Executor>::value,
202     basic_resolver&
operator =(basic_resolver<InternetProtocol,Executor1> && other)203   >::type operator=(basic_resolver<InternetProtocol, Executor1>&& other)
204   {
205     basic_resolver tmp(std::move(other));
206     impl_ = std::move(tmp.impl_);
207     return *this;
208   }
209 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION)
210 
211   /// Destroys the resolver.
212   /**
213    * This function destroys the resolver, cancelling any outstanding
214    * asynchronous wait operations associated with the resolver as if by calling
215    * @c cancel.
216    */
~basic_resolver()217   ~basic_resolver()
218   {
219   }
220 
221   /// Get the executor associated with the object.
get_executor()222   executor_type get_executor() BOOST_ASIO_NOEXCEPT
223   {
224     return impl_.get_executor();
225   }
226 
227   /// Cancel any asynchronous operations that are waiting on the resolver.
228   /**
229    * This function forces the completion of any pending asynchronous
230    * operations on the host resolver. The handler for each cancelled operation
231    * will be invoked with the boost::asio::error::operation_aborted error code.
232    */
cancel()233   void cancel()
234   {
235     return impl_.get_service().cancel(impl_.get_implementation());
236   }
237 
238 #if !defined(BOOST_ASIO_NO_DEPRECATED)
239   /// (Deprecated: Use overload with separate host and service parameters.)
240   /// Perform forward resolution of a query to a list of entries.
241   /**
242    * This function is used to resolve a query into a list of endpoint entries.
243    *
244    * @param q A query object that determines what endpoints will be returned.
245    *
246    * @returns A range object representing the list of endpoint entries. A
247    * successful call to this function is guaranteed to return a non-empty
248    * range.
249    *
250    * @throws boost::system::system_error Thrown on failure.
251    */
resolve(const query & q)252   results_type resolve(const query& q)
253   {
254     boost::system::error_code ec;
255     results_type r = impl_.get_service().resolve(
256         impl_.get_implementation(), q, ec);
257     boost::asio::detail::throw_error(ec, "resolve");
258     return r;
259   }
260 
261   /// (Deprecated: Use overload with separate host and service parameters.)
262   /// Perform forward resolution of a query to a list of entries.
263   /**
264    * This function is used to resolve a query into a list of endpoint entries.
265    *
266    * @param q A query object that determines what endpoints will be returned.
267    *
268    * @param ec Set to indicate what error occurred, if any.
269    *
270    * @returns A range object representing the list of endpoint entries. An
271    * empty range is returned if an error occurs. A successful call to this
272    * function is guaranteed to return a non-empty range.
273    */
resolve(const query & q,boost::system::error_code & ec)274   results_type resolve(const query& q, boost::system::error_code& ec)
275   {
276     return impl_.get_service().resolve(impl_.get_implementation(), q, ec);
277   }
278 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
279 
280   /// Perform forward resolution of a query to a list of entries.
281   /**
282    * This function is used to resolve host and service names into a list of
283    * endpoint entries.
284    *
285    * @param host A string identifying a location. May be a descriptive name or
286    * a numeric address string. If an empty string and the passive flag has been
287    * specified, the resolved endpoints are suitable for local service binding.
288    * If an empty string and passive is not specified, the resolved endpoints
289    * will use the loopback address.
290    *
291    * @param service A string identifying the requested service. This may be a
292    * descriptive name or a numeric string corresponding to a port number. May
293    * be an empty string, in which case all resolved endpoints will have a port
294    * number of 0.
295    *
296    * @returns A range object representing the list of endpoint entries. A
297    * successful call to this function is guaranteed to return a non-empty
298    * range.
299    *
300    * @throws boost::system::system_error Thrown on failure.
301    *
302    * @note On POSIX systems, host names may be locally defined in the file
303    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
304    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
305    * resolution is performed using DNS. Operating systems may use additional
306    * locations when resolving host names (such as NETBIOS names on Windows).
307    *
308    * On POSIX systems, service names are typically defined in the file
309    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
310    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
311    * may use additional locations when resolving service names.
312    */
resolve(BOOST_ASIO_STRING_VIEW_PARAM host,BOOST_ASIO_STRING_VIEW_PARAM service)313   results_type resolve(BOOST_ASIO_STRING_VIEW_PARAM host,
314       BOOST_ASIO_STRING_VIEW_PARAM service)
315   {
316     return resolve(host, service, resolver_base::flags());
317   }
318 
319   /// Perform forward resolution of a query to a list of entries.
320   /**
321    * This function is used to resolve host and service names into a list of
322    * endpoint entries.
323    *
324    * @param host A string identifying a location. May be a descriptive name or
325    * a numeric address string. If an empty string and the passive flag has been
326    * specified, the resolved endpoints are suitable for local service binding.
327    * If an empty string and passive is not specified, the resolved endpoints
328    * will use the loopback address.
329    *
330    * @param service A string identifying the requested service. This may be a
331    * descriptive name or a numeric string corresponding to a port number. May
332    * be an empty string, in which case all resolved endpoints will have a port
333    * number of 0.
334    *
335    * @param ec Set to indicate what error occurred, if any.
336    *
337    * @returns A range object representing the list of endpoint entries. An
338    * empty range is returned if an error occurs. A successful call to this
339    * function is guaranteed to return a non-empty range.
340    *
341    * @note On POSIX systems, host names may be locally defined in the file
342    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
343    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
344    * resolution is performed using DNS. Operating systems may use additional
345    * locations when resolving host names (such as NETBIOS names on Windows).
346    *
347    * On POSIX systems, service names are typically defined in the file
348    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
349    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
350    * may use additional locations when resolving service names.
351    */
resolve(BOOST_ASIO_STRING_VIEW_PARAM host,BOOST_ASIO_STRING_VIEW_PARAM service,boost::system::error_code & ec)352   results_type resolve(BOOST_ASIO_STRING_VIEW_PARAM host,
353       BOOST_ASIO_STRING_VIEW_PARAM service, boost::system::error_code& ec)
354   {
355     return resolve(host, service, resolver_base::flags(), ec);
356   }
357 
358   /// Perform forward resolution of a query to a list of entries.
359   /**
360    * This function is used to resolve host and service names into a list of
361    * endpoint entries.
362    *
363    * @param host A string identifying a location. May be a descriptive name or
364    * a numeric address string. If an empty string and the passive flag has been
365    * specified, the resolved endpoints are suitable for local service binding.
366    * If an empty string and passive is not specified, the resolved endpoints
367    * will use the loopback address.
368    *
369    * @param service A string identifying the requested service. This may be a
370    * descriptive name or a numeric string corresponding to a port number. May
371    * be an empty string, in which case all resolved endpoints will have a port
372    * number of 0.
373    *
374    * @param resolve_flags A set of flags that determine how name resolution
375    * should be performed. The default flags are suitable for communication with
376    * remote hosts. See the @ref resolver_base documentation for the set of
377    * available flags.
378    *
379    * @returns A range object representing the list of endpoint entries. A
380    * successful call to this function is guaranteed to return a non-empty
381    * range.
382    *
383    * @throws boost::system::system_error Thrown on failure.
384    *
385    * @note On POSIX systems, host names may be locally defined in the file
386    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
387    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
388    * resolution is performed using DNS. Operating systems may use additional
389    * locations when resolving host names (such as NETBIOS names on Windows).
390    *
391    * On POSIX systems, service names are typically defined in the file
392    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
393    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
394    * may use additional locations when resolving service names.
395    */
resolve(BOOST_ASIO_STRING_VIEW_PARAM host,BOOST_ASIO_STRING_VIEW_PARAM service,resolver_base::flags resolve_flags)396   results_type resolve(BOOST_ASIO_STRING_VIEW_PARAM host,
397       BOOST_ASIO_STRING_VIEW_PARAM service, resolver_base::flags resolve_flags)
398   {
399     boost::system::error_code ec;
400     basic_resolver_query<protocol_type> q(static_cast<std::string>(host),
401         static_cast<std::string>(service), resolve_flags);
402     results_type r = impl_.get_service().resolve(
403         impl_.get_implementation(), q, ec);
404     boost::asio::detail::throw_error(ec, "resolve");
405     return r;
406   }
407 
408   /// Perform forward resolution of a query to a list of entries.
409   /**
410    * This function is used to resolve host and service names into a list of
411    * endpoint entries.
412    *
413    * @param host A string identifying a location. May be a descriptive name or
414    * a numeric address string. If an empty string and the passive flag has been
415    * specified, the resolved endpoints are suitable for local service binding.
416    * If an empty string and passive is not specified, the resolved endpoints
417    * will use the loopback address.
418    *
419    * @param service A string identifying the requested service. This may be a
420    * descriptive name or a numeric string corresponding to a port number. May
421    * be an empty string, in which case all resolved endpoints will have a port
422    * number of 0.
423    *
424    * @param resolve_flags A set of flags that determine how name resolution
425    * should be performed. The default flags are suitable for communication with
426    * remote hosts. See the @ref resolver_base documentation for the set of
427    * available flags.
428    *
429    * @param ec Set to indicate what error occurred, if any.
430    *
431    * @returns A range object representing the list of endpoint entries. An
432    * empty range is returned if an error occurs. A successful call to this
433    * function is guaranteed to return a non-empty range.
434    *
435    * @note On POSIX systems, host names may be locally defined in the file
436    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
437    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
438    * resolution is performed using DNS. Operating systems may use additional
439    * locations when resolving host names (such as NETBIOS names on Windows).
440    *
441    * On POSIX systems, service names are typically defined in the file
442    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
443    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
444    * may use additional locations when resolving service names.
445    */
resolve(BOOST_ASIO_STRING_VIEW_PARAM host,BOOST_ASIO_STRING_VIEW_PARAM service,resolver_base::flags resolve_flags,boost::system::error_code & ec)446   results_type resolve(BOOST_ASIO_STRING_VIEW_PARAM host,
447       BOOST_ASIO_STRING_VIEW_PARAM service, resolver_base::flags resolve_flags,
448       boost::system::error_code& ec)
449   {
450     basic_resolver_query<protocol_type> q(static_cast<std::string>(host),
451         static_cast<std::string>(service), resolve_flags);
452     return impl_.get_service().resolve(impl_.get_implementation(), q, ec);
453   }
454 
455   /// Perform forward resolution of a query to a list of entries.
456   /**
457    * This function is used to resolve host and service names into a list of
458    * endpoint entries.
459    *
460    * @param protocol A protocol object, normally representing either the IPv4 or
461    * IPv6 version of an internet protocol.
462    *
463    * @param host A string identifying a location. May be a descriptive name or
464    * a numeric address string. If an empty string and the passive flag has been
465    * specified, the resolved endpoints are suitable for local service binding.
466    * If an empty string and passive is not specified, the resolved endpoints
467    * will use the loopback address.
468    *
469    * @param service A string identifying the requested service. This may be a
470    * descriptive name or a numeric string corresponding to a port number. May
471    * be an empty string, in which case all resolved endpoints will have a port
472    * number of 0.
473    *
474    * @returns A range object representing the list of endpoint entries. A
475    * successful call to this function is guaranteed to return a non-empty
476    * range.
477    *
478    * @throws boost::system::system_error Thrown on failure.
479    *
480    * @note On POSIX systems, host names may be locally defined in the file
481    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
482    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
483    * resolution is performed using DNS. Operating systems may use additional
484    * locations when resolving host names (such as NETBIOS names on Windows).
485    *
486    * On POSIX systems, service names are typically defined in the file
487    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
488    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
489    * may use additional locations when resolving service names.
490    */
resolve(const protocol_type & protocol,BOOST_ASIO_STRING_VIEW_PARAM host,BOOST_ASIO_STRING_VIEW_PARAM service)491   results_type resolve(const protocol_type& protocol,
492       BOOST_ASIO_STRING_VIEW_PARAM host, BOOST_ASIO_STRING_VIEW_PARAM service)
493   {
494     return resolve(protocol, host, service, resolver_base::flags());
495   }
496 
497   /// Perform forward resolution of a query to a list of entries.
498   /**
499    * This function is used to resolve host and service names into a list of
500    * endpoint entries.
501    *
502    * @param protocol A protocol object, normally representing either the IPv4 or
503    * IPv6 version of an internet protocol.
504    *
505    * @param host A string identifying a location. May be a descriptive name or
506    * a numeric address string. If an empty string and the passive flag has been
507    * specified, the resolved endpoints are suitable for local service binding.
508    * If an empty string and passive is not specified, the resolved endpoints
509    * will use the loopback address.
510    *
511    * @param service A string identifying the requested service. This may be a
512    * descriptive name or a numeric string corresponding to a port number. May
513    * be an empty string, in which case all resolved endpoints will have a port
514    * number of 0.
515    *
516    * @param ec Set to indicate what error occurred, if any.
517    *
518    * @returns A range object representing the list of endpoint entries. An
519    * empty range is returned if an error occurs. A successful call to this
520    * function is guaranteed to return a non-empty range.
521    *
522    * @note On POSIX systems, host names may be locally defined in the file
523    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
524    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
525    * resolution is performed using DNS. Operating systems may use additional
526    * locations when resolving host names (such as NETBIOS names on Windows).
527    *
528    * On POSIX systems, service names are typically defined in the file
529    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
530    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
531    * may use additional locations when resolving service names.
532    */
resolve(const protocol_type & protocol,BOOST_ASIO_STRING_VIEW_PARAM host,BOOST_ASIO_STRING_VIEW_PARAM service,boost::system::error_code & ec)533   results_type resolve(const protocol_type& protocol,
534       BOOST_ASIO_STRING_VIEW_PARAM host, BOOST_ASIO_STRING_VIEW_PARAM service,
535       boost::system::error_code& ec)
536   {
537     return resolve(protocol, host, service, resolver_base::flags(), ec);
538   }
539 
540   /// Perform forward resolution of a query to a list of entries.
541   /**
542    * This function is used to resolve host and service names into a list of
543    * endpoint entries.
544    *
545    * @param protocol A protocol object, normally representing either the IPv4 or
546    * IPv6 version of an internet protocol.
547    *
548    * @param host A string identifying a location. May be a descriptive name or
549    * a numeric address string. If an empty string and the passive flag has been
550    * specified, the resolved endpoints are suitable for local service binding.
551    * If an empty string and passive is not specified, the resolved endpoints
552    * will use the loopback address.
553    *
554    * @param service A string identifying the requested service. This may be a
555    * descriptive name or a numeric string corresponding to a port number. May
556    * be an empty string, in which case all resolved endpoints will have a port
557    * number of 0.
558    *
559    * @param resolve_flags A set of flags that determine how name resolution
560    * should be performed. The default flags are suitable for communication with
561    * remote hosts. See the @ref resolver_base documentation for the set of
562    * available flags.
563    *
564    * @returns A range object representing the list of endpoint entries. A
565    * successful call to this function is guaranteed to return a non-empty
566    * range.
567    *
568    * @throws boost::system::system_error Thrown on failure.
569    *
570    * @note On POSIX systems, host names may be locally defined in the file
571    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
572    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
573    * resolution is performed using DNS. Operating systems may use additional
574    * locations when resolving host names (such as NETBIOS names on Windows).
575    *
576    * On POSIX systems, service names are typically defined in the file
577    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
578    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
579    * may use additional locations when resolving service names.
580    */
resolve(const protocol_type & protocol,BOOST_ASIO_STRING_VIEW_PARAM host,BOOST_ASIO_STRING_VIEW_PARAM service,resolver_base::flags resolve_flags)581   results_type resolve(const protocol_type& protocol,
582       BOOST_ASIO_STRING_VIEW_PARAM host, BOOST_ASIO_STRING_VIEW_PARAM service,
583       resolver_base::flags resolve_flags)
584   {
585     boost::system::error_code ec;
586     basic_resolver_query<protocol_type> q(
587         protocol, static_cast<std::string>(host),
588         static_cast<std::string>(service), resolve_flags);
589     results_type r = impl_.get_service().resolve(
590         impl_.get_implementation(), q, ec);
591     boost::asio::detail::throw_error(ec, "resolve");
592     return r;
593   }
594 
595   /// Perform forward resolution of a query to a list of entries.
596   /**
597    * This function is used to resolve host and service names into a list of
598    * endpoint entries.
599    *
600    * @param protocol A protocol object, normally representing either the IPv4 or
601    * IPv6 version of an internet protocol.
602    *
603    * @param host A string identifying a location. May be a descriptive name or
604    * a numeric address string. If an empty string and the passive flag has been
605    * specified, the resolved endpoints are suitable for local service binding.
606    * If an empty string and passive is not specified, the resolved endpoints
607    * will use the loopback address.
608    *
609    * @param service A string identifying the requested service. This may be a
610    * descriptive name or a numeric string corresponding to a port number. May
611    * be an empty string, in which case all resolved endpoints will have a port
612    * number of 0.
613    *
614    * @param resolve_flags A set of flags that determine how name resolution
615    * should be performed. The default flags are suitable for communication with
616    * remote hosts. See the @ref resolver_base documentation for the set of
617    * available flags.
618    *
619    * @param ec Set to indicate what error occurred, if any.
620    *
621    * @returns A range object representing the list of endpoint entries. An
622    * empty range is returned if an error occurs. A successful call to this
623    * function is guaranteed to return a non-empty range.
624    *
625    * @note On POSIX systems, host names may be locally defined in the file
626    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
627    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
628    * resolution is performed using DNS. Operating systems may use additional
629    * locations when resolving host names (such as NETBIOS names on Windows).
630    *
631    * On POSIX systems, service names are typically defined in the file
632    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
633    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
634    * may use additional locations when resolving service names.
635    */
resolve(const protocol_type & protocol,BOOST_ASIO_STRING_VIEW_PARAM host,BOOST_ASIO_STRING_VIEW_PARAM service,resolver_base::flags resolve_flags,boost::system::error_code & ec)636   results_type resolve(const protocol_type& protocol,
637       BOOST_ASIO_STRING_VIEW_PARAM host, BOOST_ASIO_STRING_VIEW_PARAM service,
638       resolver_base::flags resolve_flags, boost::system::error_code& ec)
639   {
640     basic_resolver_query<protocol_type> q(
641         protocol, static_cast<std::string>(host),
642         static_cast<std::string>(service), resolve_flags);
643     return impl_.get_service().resolve(impl_.get_implementation(), q, ec);
644   }
645 
646 #if !defined(BOOST_ASIO_NO_DEPRECATED)
647   /// (Deprecated: Use overload with separate host and service parameters.)
648   /// Asynchronously perform forward resolution of a query to a list of entries.
649   /**
650    * This function is used to asynchronously resolve a query into a list of
651    * endpoint entries.
652    *
653    * @param q A query object that determines what endpoints will be returned.
654    *
655    * @param handler The handler to be called when the resolve operation
656    * completes. Copies will be made of the handler as required. The function
657    * signature of the handler must be:
658    * @code void handler(
659    *   const boost::system::error_code& error, // Result of operation.
660    *   resolver::results_type results // Resolved endpoints as a range.
661    * ); @endcode
662    * Regardless of whether the asynchronous operation completes immediately or
663    * not, the handler will not be invoked from within this function. On
664    * immediate completion, invocation of the handler will be performed in a
665    * manner equivalent to using boost::asio::post().
666    *
667    * A successful resolve operation is guaranteed to pass a non-empty range to
668    * the handler.
669    */
670   template <
671       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
672         results_type)) ResolveHandler
673           BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,void (boost::system::error_code,results_type))674   BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,
675       void (boost::system::error_code, results_type))
676   async_resolve(const query& q,
677       BOOST_ASIO_MOVE_ARG(ResolveHandler) handler
678         BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
679   {
680     return boost::asio::async_initiate<ResolveHandler,
681       void (boost::system::error_code, results_type)>(
682         initiate_async_resolve(this), handler, q);
683   }
684 #endif // !defined(BOOST_ASIO_NO_DEPRECATED)
685 
686   /// Asynchronously perform forward resolution of a query to a list of entries.
687   /**
688    * This function is used to resolve host and service names into a list of
689    * endpoint entries.
690    *
691    * @param host A string identifying a location. May be a descriptive name or
692    * a numeric address string. If an empty string and the passive flag has been
693    * specified, the resolved endpoints are suitable for local service binding.
694    * If an empty string and passive is not specified, the resolved endpoints
695    * will use the loopback address.
696    *
697    * @param service A string identifying the requested service. This may be a
698    * descriptive name or a numeric string corresponding to a port number. May
699    * be an empty string, in which case all resolved endpoints will have a port
700    * number of 0.
701    *
702    * @param handler The handler to be called when the resolve operation
703    * completes. Copies will be made of the handler as required. The function
704    * signature of the handler must be:
705    * @code void handler(
706    *   const boost::system::error_code& error, // Result of operation.
707    *   resolver::results_type results // Resolved endpoints as a range.
708    * ); @endcode
709    * Regardless of whether the asynchronous operation completes immediately or
710    * not, the handler will not be invoked from within this function. On
711    * immediate completion, invocation of the handler will be performed in a
712    * manner equivalent to using boost::asio::post().
713    *
714    * A successful resolve operation is guaranteed to pass a non-empty range to
715    * the handler.
716    *
717    * @note On POSIX systems, host names may be locally defined in the file
718    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
719    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
720    * resolution is performed using DNS. Operating systems may use additional
721    * locations when resolving host names (such as NETBIOS names on Windows).
722    *
723    * On POSIX systems, service names are typically defined in the file
724    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
725    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
726    * may use additional locations when resolving service names.
727    */
728   template <
729       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
730         results_type)) ResolveHandler
731           BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,void (boost::system::error_code,results_type))732   BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,
733       void (boost::system::error_code, results_type))
734   async_resolve(BOOST_ASIO_STRING_VIEW_PARAM host,
735       BOOST_ASIO_STRING_VIEW_PARAM service,
736       BOOST_ASIO_MOVE_ARG(ResolveHandler) handler
737         BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
738   {
739     return async_resolve(host, service, resolver_base::flags(),
740         BOOST_ASIO_MOVE_CAST(ResolveHandler)(handler));
741   }
742 
743   /// Asynchronously perform forward resolution of a query to a list of entries.
744   /**
745    * This function is used to resolve host and service names into a list of
746    * endpoint entries.
747    *
748    * @param host A string identifying a location. May be a descriptive name or
749    * a numeric address string. If an empty string and the passive flag has been
750    * specified, the resolved endpoints are suitable for local service binding.
751    * If an empty string and passive is not specified, the resolved endpoints
752    * will use the loopback address.
753    *
754    * @param service A string identifying the requested service. This may be a
755    * descriptive name or a numeric string corresponding to a port number. May
756    * be an empty string, in which case all resolved endpoints will have a port
757    * number of 0.
758    *
759    * @param resolve_flags A set of flags that determine how name resolution
760    * should be performed. The default flags are suitable for communication with
761    * remote hosts. See the @ref resolver_base documentation for the set of
762    * available flags.
763    *
764    * @param handler The handler to be called when the resolve operation
765    * completes. Copies will be made of the handler as required. The function
766    * signature of the handler must be:
767    * @code void handler(
768    *   const boost::system::error_code& error, // Result of operation.
769    *   resolver::results_type results // Resolved endpoints as a range.
770    * ); @endcode
771    * Regardless of whether the asynchronous operation completes immediately or
772    * not, the handler will not be invoked from within this function. On
773    * immediate completion, invocation of the handler will be performed in a
774    * manner equivalent to using boost::asio::post().
775    *
776    * A successful resolve operation is guaranteed to pass a non-empty range to
777    * the handler.
778    *
779    * @note On POSIX systems, host names may be locally defined in the file
780    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
781    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
782    * resolution is performed using DNS. Operating systems may use additional
783    * locations when resolving host names (such as NETBIOS names on Windows).
784    *
785    * On POSIX systems, service names are typically defined in the file
786    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
787    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
788    * may use additional locations when resolving service names.
789    */
790   template <
791       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
792         results_type)) ResolveHandler
793           BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,void (boost::system::error_code,results_type))794   BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,
795       void (boost::system::error_code, results_type))
796   async_resolve(BOOST_ASIO_STRING_VIEW_PARAM host,
797       BOOST_ASIO_STRING_VIEW_PARAM service,
798       resolver_base::flags resolve_flags,
799       BOOST_ASIO_MOVE_ARG(ResolveHandler) handler
800         BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
801   {
802     basic_resolver_query<protocol_type> q(static_cast<std::string>(host),
803         static_cast<std::string>(service), resolve_flags);
804 
805     return boost::asio::async_initiate<ResolveHandler,
806       void (boost::system::error_code, results_type)>(
807         initiate_async_resolve(this), handler, q);
808   }
809 
810   /// Asynchronously perform forward resolution of a query to a list of entries.
811   /**
812    * This function is used to resolve host and service names into a list of
813    * endpoint entries.
814    *
815    * @param protocol A protocol object, normally representing either the IPv4 or
816    * IPv6 version of an internet protocol.
817    *
818    * @param host A string identifying a location. May be a descriptive name or
819    * a numeric address string. If an empty string and the passive flag has been
820    * specified, the resolved endpoints are suitable for local service binding.
821    * If an empty string and passive is not specified, the resolved endpoints
822    * will use the loopback address.
823    *
824    * @param service A string identifying the requested service. This may be a
825    * descriptive name or a numeric string corresponding to a port number. May
826    * be an empty string, in which case all resolved endpoints will have a port
827    * number of 0.
828    *
829    * @param handler The handler to be called when the resolve operation
830    * completes. Copies will be made of the handler as required. The function
831    * signature of the handler must be:
832    * @code void handler(
833    *   const boost::system::error_code& error, // Result of operation.
834    *   resolver::results_type results // Resolved endpoints as a range.
835    * ); @endcode
836    * Regardless of whether the asynchronous operation completes immediately or
837    * not, the handler will not be invoked from within this function. On
838    * immediate completion, invocation of the handler will be performed in a
839    * manner equivalent to using boost::asio::post().
840    *
841    * A successful resolve operation is guaranteed to pass a non-empty range to
842    * the handler.
843    *
844    * @note On POSIX systems, host names may be locally defined in the file
845    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
846    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
847    * resolution is performed using DNS. Operating systems may use additional
848    * locations when resolving host names (such as NETBIOS names on Windows).
849    *
850    * On POSIX systems, service names are typically defined in the file
851    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
852    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
853    * may use additional locations when resolving service names.
854    */
855   template <
856       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
857         results_type)) ResolveHandler
858           BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,void (boost::system::error_code,results_type))859   BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,
860       void (boost::system::error_code, results_type))
861   async_resolve(const protocol_type& protocol,
862       BOOST_ASIO_STRING_VIEW_PARAM host, BOOST_ASIO_STRING_VIEW_PARAM service,
863       BOOST_ASIO_MOVE_ARG(ResolveHandler) handler
864         BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
865   {
866     return async_resolve(protocol, host, service, resolver_base::flags(),
867         BOOST_ASIO_MOVE_CAST(ResolveHandler)(handler));
868   }
869 
870   /// Asynchronously perform forward resolution of a query to a list of entries.
871   /**
872    * This function is used to resolve host and service names into a list of
873    * endpoint entries.
874    *
875    * @param protocol A protocol object, normally representing either the IPv4 or
876    * IPv6 version of an internet protocol.
877    *
878    * @param host A string identifying a location. May be a descriptive name or
879    * a numeric address string. If an empty string and the passive flag has been
880    * specified, the resolved endpoints are suitable for local service binding.
881    * If an empty string and passive is not specified, the resolved endpoints
882    * will use the loopback address.
883    *
884    * @param service A string identifying the requested service. This may be a
885    * descriptive name or a numeric string corresponding to a port number. May
886    * be an empty string, in which case all resolved endpoints will have a port
887    * number of 0.
888    *
889    * @param resolve_flags A set of flags that determine how name resolution
890    * should be performed. The default flags are suitable for communication with
891    * remote hosts. See the @ref resolver_base documentation for the set of
892    * available flags.
893    *
894    * @param handler The handler to be called when the resolve operation
895    * completes. Copies will be made of the handler as required. The function
896    * signature of the handler must be:
897    * @code void handler(
898    *   const boost::system::error_code& error, // Result of operation.
899    *   resolver::results_type results // Resolved endpoints as a range.
900    * ); @endcode
901    * Regardless of whether the asynchronous operation completes immediately or
902    * not, the handler will not be invoked from within this function. On
903    * immediate completion, invocation of the handler will be performed in a
904    * manner equivalent to using boost::asio::post().
905    *
906    * A successful resolve operation is guaranteed to pass a non-empty range to
907    * the handler.
908    *
909    * @note On POSIX systems, host names may be locally defined in the file
910    * <tt>/etc/hosts</tt>. On Windows, host names may be defined in the file
911    * <tt>c:\\windows\\system32\\drivers\\etc\\hosts</tt>. Remote host name
912    * resolution is performed using DNS. Operating systems may use additional
913    * locations when resolving host names (such as NETBIOS names on Windows).
914    *
915    * On POSIX systems, service names are typically defined in the file
916    * <tt>/etc/services</tt>. On Windows, service names may be found in the file
917    * <tt>c:\\windows\\system32\\drivers\\etc\\services</tt>. Operating systems
918    * may use additional locations when resolving service names.
919    */
920   template <
921       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
922         results_type)) ResolveHandler
923           BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,void (boost::system::error_code,results_type))924   BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,
925       void (boost::system::error_code, results_type))
926   async_resolve(const protocol_type& protocol,
927       BOOST_ASIO_STRING_VIEW_PARAM host, BOOST_ASIO_STRING_VIEW_PARAM service,
928       resolver_base::flags resolve_flags,
929       BOOST_ASIO_MOVE_ARG(ResolveHandler) handler
930         BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
931   {
932     basic_resolver_query<protocol_type> q(
933         protocol, static_cast<std::string>(host),
934         static_cast<std::string>(service), resolve_flags);
935 
936     return boost::asio::async_initiate<ResolveHandler,
937       void (boost::system::error_code, results_type)>(
938         initiate_async_resolve(this), handler, q);
939   }
940 
941   /// Perform reverse resolution of an endpoint to a list of entries.
942   /**
943    * This function is used to resolve an endpoint into a list of endpoint
944    * entries.
945    *
946    * @param e An endpoint object that determines what endpoints will be
947    * returned.
948    *
949    * @returns A range object representing the list of endpoint entries. A
950    * successful call to this function is guaranteed to return a non-empty
951    * range.
952    *
953    * @throws boost::system::system_error Thrown on failure.
954    */
resolve(const endpoint_type & e)955   results_type resolve(const endpoint_type& e)
956   {
957     boost::system::error_code ec;
958     results_type i = impl_.get_service().resolve(
959         impl_.get_implementation(), e, ec);
960     boost::asio::detail::throw_error(ec, "resolve");
961     return i;
962   }
963 
964   /// Perform reverse resolution of an endpoint to a list of entries.
965   /**
966    * This function is used to resolve an endpoint into a list of endpoint
967    * entries.
968    *
969    * @param e An endpoint object that determines what endpoints will be
970    * returned.
971    *
972    * @param ec Set to indicate what error occurred, if any.
973    *
974    * @returns A range object representing the list of endpoint entries. An
975    * empty range is returned if an error occurs. A successful call to this
976    * function is guaranteed to return a non-empty range.
977    */
resolve(const endpoint_type & e,boost::system::error_code & ec)978   results_type resolve(const endpoint_type& e, boost::system::error_code& ec)
979   {
980     return impl_.get_service().resolve(impl_.get_implementation(), e, ec);
981   }
982 
983   /// Asynchronously perform reverse resolution of an endpoint to a list of
984   /// entries.
985   /**
986    * This function is used to asynchronously resolve an endpoint into a list of
987    * endpoint entries.
988    *
989    * @param e An endpoint object that determines what endpoints will be
990    * returned.
991    *
992    * @param handler The handler to be called when the resolve operation
993    * completes. Copies will be made of the handler as required. The function
994    * signature of the handler must be:
995    * @code void handler(
996    *   const boost::system::error_code& error, // Result of operation.
997    *   resolver::results_type results // Resolved endpoints as a range.
998    * ); @endcode
999    * Regardless of whether the asynchronous operation completes immediately or
1000    * not, the handler will not be invoked from within this function. On
1001    * immediate completion, invocation of the handler will be performed in a
1002    * manner equivalent to using boost::asio::post().
1003    *
1004    * A successful resolve operation is guaranteed to pass a non-empty range to
1005    * the handler.
1006    */
1007   template <
1008       BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code,
1009         results_type)) ResolveHandler
1010           BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)>
BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,void (boost::system::error_code,results_type))1011   BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(ResolveHandler,
1012       void (boost::system::error_code, results_type))
1013   async_resolve(const endpoint_type& e,
1014       BOOST_ASIO_MOVE_ARG(ResolveHandler) handler
1015         BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type))
1016   {
1017     return boost::asio::async_initiate<ResolveHandler,
1018       void (boost::system::error_code, results_type)>(
1019         initiate_async_resolve(this), handler, e);
1020   }
1021 
1022 private:
1023   // Disallow copying and assignment.
1024   basic_resolver(const basic_resolver&) BOOST_ASIO_DELETED;
1025   basic_resolver& operator=(const basic_resolver&) BOOST_ASIO_DELETED;
1026 
1027   class initiate_async_resolve
1028   {
1029   public:
1030     typedef Executor executor_type;
1031 
initiate_async_resolve(basic_resolver * self)1032     explicit initiate_async_resolve(basic_resolver* self)
1033       : self_(self)
1034     {
1035     }
1036 
get_executor() const1037     executor_type get_executor() const BOOST_ASIO_NOEXCEPT
1038     {
1039       return self_->get_executor();
1040     }
1041 
1042     template <typename ResolveHandler, typename Query>
operator ()(BOOST_ASIO_MOVE_ARG (ResolveHandler)handler,const Query & q) const1043     void operator()(BOOST_ASIO_MOVE_ARG(ResolveHandler) handler,
1044         const Query& q) const
1045     {
1046       // If you get an error on the following line it means that your handler
1047       // does not meet the documented type requirements for a ResolveHandler.
1048       BOOST_ASIO_RESOLVE_HANDLER_CHECK(
1049           ResolveHandler, handler, results_type) type_check;
1050 
1051       boost::asio::detail::non_const_lvalue<ResolveHandler> handler2(handler);
1052       self_->impl_.get_service().async_resolve(
1053           self_->impl_.get_implementation(), q,
1054           handler2.value, self_->impl_.get_executor());
1055     }
1056 
1057   private:
1058     basic_resolver* self_;
1059   };
1060 
1061 # if defined(BOOST_ASIO_WINDOWS_RUNTIME)
1062   boost::asio::detail::io_object_impl<
1063     boost::asio::detail::winrt_resolver_service<InternetProtocol>,
1064     Executor> impl_;
1065 # else
1066   boost::asio::detail::io_object_impl<
1067     boost::asio::detail::resolver_service<InternetProtocol>,
1068     Executor> impl_;
1069 # endif
1070 };
1071 
1072 } // namespace ip
1073 } // namespace asio
1074 } // namespace boost
1075 
1076 #include <boost/asio/detail/pop_options.hpp>
1077 
1078 #endif // BOOST_ASIO_IP_BASIC_RESOLVER_HPP
1079