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 
33 namespace shill {
34 
35 class DNSClient;
36 class Error;
37 class 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.
50 class 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