blob: eaff89e4289192758f01dd14573791ef59d9ecb0 [file] [log] [blame]
Peter Qiuc0beca52015-09-03 11:25:46 -07001//
2// Copyright (C) 2015 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//
Peter Qiud7881022015-01-21 12:27:41 -080016
17#ifndef SHILL_ACTIVE_LINK_MONITOR_H_
18#define SHILL_ACTIVE_LINK_MONITOR_H_
19
20#include <time.h>
21
22#include <memory>
23#include <string>
24
25#include <base/callback.h>
26#include <base/cancelable_callback.h>
27
28#include "shill/metrics.h"
29#include "shill/net/byte_string.h"
30#include "shill/refptr_types.h"
31
32namespace shill {
33
34class ArpClient;
35class DeviceInfo;
36class EventDispatcher;
37class IOHandler;
38class Time;
39
40// ActiveLinkMonitor probes the status of a connection by sending ARP
41// messages to the default gateway for a connection. The link will be declared
42// as failure if no ARP reply is received for 5 consecutive broadcast ARP
43// requests or unicast ARP requests in the case when gateway unicast ARP
44// support is established. And active when an ARP reply is received.
45// A callback will be invoked when the link is detected as failure or active.
46// The active link monitor will automatically stop when the link status is
47// determined. It also keeps track of response times which can be an indicator
48// of link quality.
49class ActiveLinkMonitor {
50 public:
51 // FailureCallback takes monitor failure code, broadcast failure count, and
52 // unicast failure count as arguments.
53 typedef base::Callback<void(Metrics::LinkMonitorFailure, int, int)>
54 FailureCallback;
55 typedef base::Closure SuccessCallback;
56
57 // The default number of milliseconds between ARP requests. Needed by Metrics.
58 static const int kDefaultTestPeriodMilliseconds;
59
60 // The number of milliseconds between ARP requests when running a quick test.
61 // Used when the device just resume from suspend. Also needed by unit tests.
62 static const int kFastTestPeriodMilliseconds;
63
64 // When the sum of consecutive counted unicast and broadcast failures
65 // equals this value, the failure callback is called, the counters
66 // are reset, and the link monitoring quiesces. Needed by Metrics.
67 static const int kFailureThreshold;
68
Paul Stewarta794cd62015-06-16 13:13:10 -070069 ActiveLinkMonitor(const ConnectionRefPtr& connection,
70 EventDispatcher* dispatcher,
71 Metrics* metrics,
72 DeviceInfo* device_info,
73 const FailureCallback& failure_callback,
74 const SuccessCallback& success_callback);
Peter Qiud7881022015-01-21 12:27:41 -080075 virtual ~ActiveLinkMonitor();
76
77 // Starts an active link-monitoring cycle on the selected connection, with
78 // specified |probe_period_millisecond| milliseconds between each ARP
79 // requests. Returns true if successful, false otherwise.
80 virtual bool Start(int probe_period_millisecond);
81 // Stop active link-monitoring on the selected connection. Clears any
82 // accumulated statistics.
83 virtual void Stop();
84
85 // Return modified cumulative average of the gateway ARP response
86 // time. Returns zero if no samples are available. For each
87 // missed ARP response, the sample is assumed to be the full
88 // test period.
89 int GetResponseTimeMilliseconds() const;
90
91 // Returns true if the ActiveLinkMonitor was ever able to find the default
92 // gateway via broadcast ARP.
93 bool IsGatewayFound() const;
94
Paul Stewarta794cd62015-06-16 13:13:10 -070095 virtual const ByteString& gateway_mac_address() const {
Peter Qiud7881022015-01-21 12:27:41 -080096 return gateway_mac_address_;
97 }
Paul Stewarta794cd62015-06-16 13:13:10 -070098 virtual void set_gateway_mac_address(const ByteString& gateway_mac_address) {
Peter Qiuffa56372015-01-22 14:25:23 -080099 gateway_mac_address_ = gateway_mac_address;
100 }
101
102 virtual bool gateway_supports_unicast_arp() const {
103 return gateway_supports_unicast_arp_;
104 }
105 virtual void set_gateway_supports_unicast_arp(
106 bool gateway_supports_unicast_arp) {
107 gateway_supports_unicast_arp_ = gateway_supports_unicast_arp;
108 }
Peter Qiud7881022015-01-21 12:27:41 -0800109
110 private:
111 friend class ActiveLinkMonitorTest;
112
113 // The number of samples to compute a "strict" average over. When
114 // more samples than this number arrive, this determines how "slow"
115 // our simple low-pass filter works.
116 static const int kMaxResponseSampleFilterDepth;
117
118 // When the sum of consecutive unicast successes equals this value,
119 // we can assume that in general this gateway supports unicast ARP
120 // requests, and we will count future unicast failures.
121 static const int kUnicastReplyReliabilityThreshold;
122
123 // Similar to Start, except that the initial probes use
124 // |probe_period_milliseconds|. After successfully probing with both
125 // broadcast and unicast ARPs (at least one of each), LinkMonitor
126 // switches itself to kDefaultTestPeriodMilliseconds.
127 virtual bool StartInternal(int probe_period_milliseconds);
128 // Stop the current monitoring cycle. It is called when current monitor cycle
129 // results in success.
130 void StopMonitorCycle();
131 // Add a response time sample to the buffer.
132 void AddResponseTimeSample(int response_time_milliseconds);
133 // Start and stop ARP client for sending/receiving ARP requests/replies.
134 bool StartArpClient();
135 void StopArpClient();
136 // Convert a hardware address byte-string to a colon-separated string.
Paul Stewarta794cd62015-06-16 13:13:10 -0700137 static std::string HardwareAddressToString(const ByteString& address);
Peter Qiud7881022015-01-21 12:27:41 -0800138 // Denote a missed response. Returns true if this loss has caused us
139 // to exceed the failure threshold.
140 bool AddMissedResponse();
141 // This I/O callback is triggered whenever the ARP reception socket
142 // has data available to be received.
143 void ReceiveResponse(int fd);
144 // Send the next ARP request.
145 void SendRequest();
146
147 // The connection on which to perform link monitoring.
148 ConnectionRefPtr connection_;
149 // Dispatcher on which to create delayed tasks.
Paul Stewarta794cd62015-06-16 13:13:10 -0700150 EventDispatcher* dispatcher_;
Peter Qiud7881022015-01-21 12:27:41 -0800151 // Metrics instance on which to post performance results.
Paul Stewarta794cd62015-06-16 13:13:10 -0700152 Metrics* metrics_;
Peter Qiud7881022015-01-21 12:27:41 -0800153 // DeviceInfo instance for retrieving the MAC address of a device.
Paul Stewarta794cd62015-06-16 13:13:10 -0700154 DeviceInfo* device_info_;
Peter Qiud7881022015-01-21 12:27:41 -0800155 // Callback methods to call when ActiveLinkMonitor completes a cycle.
156 FailureCallback failure_callback_;
157 SuccessCallback success_callback_;
158 // The MAC address of device associated with this connection.
159 ByteString local_mac_address_;
160 // The MAC address of the default gateway.
161 ByteString gateway_mac_address_;
162 // ArpClient instance used for performing link tests.
163 std::unique_ptr<ArpClient> arp_client_;
164
165 // How frequently we send an ARP request. This is also the timeout
166 // for a pending request.
167 int test_period_milliseconds_;
168 // The number of consecutive times we have failed in receiving
169 // responses to broadcast ARP requests.
170 int broadcast_failure_count_;
171 // The number of consecutive times we have failed in receiving
172 // responses to unicast ARP requests.
173 int unicast_failure_count_;
174 // The number of consecutive times we have succeeded in receiving
175 // responses to broadcast ARP requests.
176 int broadcast_success_count_;
177 // The number of consecutive times we have succeeded in receiving
178 // responses to unicast ARP requests.
179 int unicast_success_count_;
180
181 // Whether this iteration of the test was a unicast request
182 // to the gateway instead of broadcast. The active link monitor
183 // alternates between unicast and broadcast requests so that
184 // both types of network traffic is monitored.
185 bool is_unicast_;
186
187 // Whether we have observed that the gateway reliably responds
188 // to unicast ARP requests.
189 bool gateway_supports_unicast_arp_;
190
191 // Number of response samples received in our rolling averge.
192 int response_sample_count_;
193 // The sum of response samples in our rolling average.
194 int response_sample_bucket_;
195
196 // IOCallback that fires when the socket associated with our ArpClient
197 // has a packet to be received. Calls ReceiveResponse().
198 std::unique_ptr<IOHandler> receive_response_handler_;
199 // Callback method used for periodic transmission of ARP requests.
200 // When the timer expires this will call SendRequest() through the
201 // void callback function SendRequestTask().
202 base::CancelableClosure send_request_callback_;
203
204 // The time at which the last ARP request was sent.
205 struct timeval sent_request_at_;
206 // Time instance for performing GetTimeMonotonic().
Paul Stewarta794cd62015-06-16 13:13:10 -0700207 Time* time_;
Peter Qiud7881022015-01-21 12:27:41 -0800208
209 DISALLOW_COPY_AND_ASSIGN(ActiveLinkMonitor);
210};
211
212} // namespace shill
213
214#endif // SHILL_ACTIVE_LINK_MONITOR_H_