1//
2// Copyright (C) 2014 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_SERVER_TESTER_H_
18#define SHILL_DNS_SERVER_TESTER_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/ref_counted.h>
27#include <base/memory/weak_ptr.h>
28#include <gtest/gtest_prod.h>  // for FRIEND_TEST
29
30#include "shill/net/ip_address.h"
31#include "shill/refptr_types.h"
32
33namespace shill {
34
35class DNSClient;
36class Error;
37class EventDispatcher;
38
39// The DNSServerTester class implements the DNS health check
40// facility in shill, which is responsible for checking to see
41// if the given DNS servers are working or not.
42//
43// The tester support two modes of operation, continuous and
44// non-continuous mode. With continuous mode (retry_until_success_ flag is set),
45// the tester will continue to perform DNS test until the DNS test succeed or
46// the DNS client failed to start. The callback is only invoke when the test
47// succeed or we failed to start the DNS client. With non-continuous mode,
48// only one DNS test is performed. And the callback is invoked regardless of
49// the result of the test.
50class DNSServerTester {
51 public:
52  enum Status {
53    kStatusFailure,
54    kStatusSuccess,
55  };
56
57  DNSServerTester(ConnectionRefPtr connection,
58                  EventDispatcher* dispatcher,
59                  const std::vector<std::string>& dns_servers,
60                  const bool retry_until_success,
61                  const base::Callback<void(const Status)>& callback);
62  virtual ~DNSServerTester();
63
64  // Start the test.
65  virtual void Start();
66
67  // End the current DNS test process if one exist, and do not call
68  // the callback.
69  virtual void Stop();
70
71 private:
72  friend class DNSServerTesterTest;
73  FRIEND_TEST(DNSServerTesterTest, StartAttempt);
74  FRIEND_TEST(DNSServerTesterTest, StartAttemptTask);
75  FRIEND_TEST(DNSServerTesterTest, AttemptCompleted);
76  FRIEND_TEST(DNSServerTesterTest, StopAttempt);
77
78  static const char kDNSTestHostname[];
79  static const int kDNSTestRetryIntervalMilliseconds;
80  static const int kDNSTimeoutMilliseconds;
81
82  void StartAttempt(int delay_ms);
83  void StartAttemptTask();
84  void StopAttempt();
85  void CompleteAttempt(Status status);
86  void DNSClientCallback(const Error& error, const IPAddress& ip);
87
88  ConnectionRefPtr connection_;
89  EventDispatcher* dispatcher_;
90  // Flag indicating to continuously probing the DNS servers until it succeed.
91  // The callback is only invoke when the test succeed or test failed to start.
92  bool retry_until_success_;
93  base::WeakPtrFactory<DNSServerTester> weak_ptr_factory_;
94  base::CancelableClosure start_attempt_;
95  base::Callback<void(const Status)> dns_result_callback_;
96  base::Callback<void(const Error&, const IPAddress&)>
97      dns_client_callback_;
98  std::unique_ptr<DNSClient> dns_test_client_;
99
100  DISALLOW_COPY_AND_ASSIGN(DNSServerTester);
101};
102
103}  // namespace shill
104
105#endif  // SHILL_DNS_SERVER_TESTER_H_
106