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