1 //
2 // detail/resolver_service.hpp
3 // ~~~~~~~~~~~~~~~~~~~~~~~~~~~
4 //
5 // Copyright (c) 2003-2015 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 ASIO_DETAIL_RESOLVER_SERVICE_HPP
12 #define ASIO_DETAIL_RESOLVER_SERVICE_HPP
13 
14 
15 #include "asio/detail/config.hpp"
16 
17 
18 #include "asio/ip/basic_resolver_iterator.hpp"
19 #include "asio/ip/basic_resolver_query.hpp"
20 #include "asio/detail/addressof.hpp"
21 #include "asio/detail/resolve_endpoint_op.hpp"
22 #include "asio/detail/resolve_op.hpp"
23 #include "asio/detail/resolver_service_base.hpp"
24 
25 #include "asio/detail/push_options.hpp"
26 
27 namespace asio {
28 namespace detail {
29 
30 template <typename Protocol>
31 class resolver_service : public resolver_service_base
32 {
33 public:
34   // The implementation type of the resolver. A cancellation token is used to
35   // indicate to the background thread that the operation has been cancelled.
36   typedef socket_ops::shared_cancel_token_type implementation_type;
37 
38   // The endpoint type.
39   typedef typename Protocol::endpoint endpoint_type;
40 
41   // The query type.
42   typedef asio::ip::basic_resolver_query<Protocol> query_type;
43 
44   // The iterator type.
45   typedef asio::ip::basic_resolver_iterator<Protocol> iterator_type;
46 
47   // Constructor.
resolver_service(asio::io_service & io_service)48   resolver_service(asio::io_service& io_service)
49     : resolver_service_base(io_service)
50   {
51   }
52 
53   // Resolve a query to a list of entries.
resolve(implementation_type &,const query_type & query,asio::error_code & ec)54   iterator_type resolve(implementation_type&, const query_type& query,
55       asio::error_code& ec)
56   {
57     asio::detail::addrinfo_type* address_info = 0;
58 
59     socket_ops::getaddrinfo(query.host_name().c_str(),
60         query.service_name().c_str(), query.hints(), &address_info, ec);
61     auto_addrinfo auto_address_info(address_info);
62 
63     return ec ? iterator_type() : iterator_type::create(
64         address_info, query.host_name(), query.service_name());
65   }
66 
67   // Asynchronously resolve a query to a list of entries.
68   template <typename Handler>
async_resolve(implementation_type & impl,const query_type & query,Handler & handler)69   void async_resolve(implementation_type& impl,
70       const query_type& query, Handler& handler)
71   {
72     // Allocate and construct an operation to wrap the handler.
73     typedef resolve_op<Protocol, Handler> op;
74     typename op::ptr p = { asio::detail::addressof(handler),
75       asio_handler_alloc_helpers::allocate(
76         sizeof(op), handler), 0 };
77     p.p = new (p.v) op(impl, query, io_service_impl_, handler);
78 
79     ASIO_HANDLER_CREATION((p.p, "resolver", &impl, "async_resolve"));
80 
81     start_resolve_op(p.p);
82     p.v = p.p = 0;
83   }
84 
85   // Resolve an endpoint to a list of entries.
resolve(implementation_type &,const endpoint_type & endpoint,asio::error_code & ec)86   iterator_type resolve(implementation_type&,
87       const endpoint_type& endpoint, asio::error_code& ec)
88   {
89     char host_name[NI_MAXHOST];
90     char service_name[NI_MAXSERV];
91     socket_ops::sync_getnameinfo(endpoint.data(), endpoint.size(),
92         host_name, NI_MAXHOST, service_name, NI_MAXSERV,
93         endpoint.protocol().type(), ec);
94 
95     return ec ? iterator_type() : iterator_type::create(
96         endpoint, host_name, service_name);
97   }
98 
99   // Asynchronously resolve an endpoint to a list of entries.
100   template <typename Handler>
async_resolve(implementation_type & impl,const endpoint_type & endpoint,Handler & handler)101   void async_resolve(implementation_type& impl,
102       const endpoint_type& endpoint, Handler& handler)
103   {
104     // Allocate and construct an operation to wrap the handler.
105     typedef resolve_endpoint_op<Protocol, Handler> op;
106     typename op::ptr p = { asio::detail::addressof(handler),
107       asio_handler_alloc_helpers::allocate(
108         sizeof(op), handler), 0 };
109     p.p = new (p.v) op(impl, endpoint, io_service_impl_, handler);
110 
111     ASIO_HANDLER_CREATION((p.p, "resolver", &impl, "async_resolve"));
112 
113     start_resolve_op(p.p);
114     p.v = p.p = 0;
115   }
116 };
117 
118 } // namespace detail
119 } // namespace asio
120 
121 #include "asio/detail/pop_options.hpp"
122 
123 
124 #endif // ASIO_DETAIL_RESOLVER_SERVICE_HPP
125