1//
2// Copyright (C) 2011 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//      http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17#ifndef SHILL_DNS_CLIENT_H_
18#define SHILL_DNS_CLIENT_H_
19
20#include <memory>
21#include <string>
22#include <vector>
23
24#include <base/callback.h>
25#include <base/cancelable_callback.h>
26#include <base/memory/weak_ptr.h>
27#include <gtest/gtest_prod.h>  // for FRIEND_TEST
28
29#include "shill/error.h"
30#include "shill/event_dispatcher.h"
31#include "shill/net/ip_address.h"
32#include "shill/refptr_types.h"
33
34struct hostent;
35
36namespace shill {
37
38class Ares;
39class Time;
40struct DNSClientState;
41
42// Implements a DNS resolution client that can run asynchronously.
43class DNSClient {
44 public:
45  typedef base::Callback<void(const Error&, const IPAddress&)> ClientCallback;
46
47  static const char kErrorNoData[];
48  static const char kErrorFormErr[];
49  static const char kErrorServerFail[];
50  static const char kErrorNotFound[];
51  static const char kErrorNotImp[];
52  static const char kErrorRefused[];
53  static const char kErrorBadQuery[];
54  static const char kErrorNetRefused[];
55  static const char kErrorTimedOut[];
56  static const char kErrorUnknown[];
57
58  DNSClient(IPAddress::Family family,
59            const std::string& interface_name,
60            const std::vector<std::string>& dns_servers,
61            int timeout_ms,
62            EventDispatcher* dispatcher,
63            const ClientCallback& callback);
64  virtual ~DNSClient();
65
66  // Returns true if the DNS client started successfully, false otherwise.
67  // If successful, the callback will be called with the result of the
68  // request.  If Start() fails and returns false, the callback will not
69  // be called, but the error that caused the failure will be returned in
70  // |error|.
71  virtual bool Start(const std::string& hostname, Error* error);
72
73  // Aborts any running DNS client transaction.  This will cancel any callback
74  // invocation.
75  virtual void Stop();
76
77  virtual bool IsActive() const;
78
79  std::string interface_name() { return interface_name_; }
80
81 private:
82  friend class DNSClientTest;
83
84  void HandleCompletion();
85  void HandleDNSRead(int fd);
86  void HandleDNSWrite(int fd);
87  void HandleTimeout();
88  void ReceiveDNSReply(int status, struct hostent* hostent);
89  static void ReceiveDNSReplyCB(void* arg, int status, int timeouts,
90                                struct hostent* hostent);
91  bool RefreshHandles();
92
93  static const int kDefaultDNSPort;
94
95  Error error_;
96  IPAddress address_;
97  std::string interface_name_;
98  std::vector<std::string> dns_servers_;
99  EventDispatcher* dispatcher_;
100  ClientCallback callback_;
101  int timeout_ms_;
102  bool running_;
103  std::unique_ptr<DNSClientState> resolver_state_;
104  base::CancelableClosure timeout_closure_;
105  base::WeakPtrFactory<DNSClient> weak_ptr_factory_;
106  Ares* ares_;
107  Time* time_;
108
109  DISALLOW_COPY_AND_ASSIGN(DNSClient);
110};
111
112}  // namespace shill
113
114#endif  // SHILL_DNS_CLIENT_H_
115