blob: c15596b95007678015c9b95a23dbcc352a78282c [file] [log] [blame]
Paul Stewart3f43f432012-07-16 12:12:45 -07001// Copyright (c) 2012 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
Paul Stewart6c72c972012-07-27 11:29:20 -07005#ifndef SHILL_LINK_MONITOR_H_
6#define SHILL_LINK_MONITOR_H_
7
8#include <time.h>
Paul Stewart3f43f432012-07-16 12:12:45 -07009
Alex Vakulenko8a532292014-06-16 17:18:44 -070010#include <string>
11
Paul Stewart3f43f432012-07-16 12:12:45 -070012#include <base/callback.h>
Paul Stewart6c72c972012-07-27 11:29:20 -070013#include <base/cancelable_callback.h>
Paul Stewart3f43f432012-07-16 12:12:45 -070014#include <base/memory/scoped_ptr.h>
15
Paul Stewart6c72c972012-07-27 11:29:20 -070016#include "shill/byte_string.h"
Paul Stewart3f43f432012-07-16 12:12:45 -070017#include "shill/refptr_types.h"
18
19namespace shill {
20
Paul Stewart6c72c972012-07-27 11:29:20 -070021class ArpClient;
22class DeviceInfo;
Paul Stewart3f43f432012-07-16 12:12:45 -070023class EventDispatcher;
Paul Stewart6c72c972012-07-27 11:29:20 -070024class IOHandler;
Paul Stewartff845fc2012-08-07 07:28:44 -070025class Metrics;
Paul Stewart6c72c972012-07-27 11:29:20 -070026class Time;
Paul Stewart3f43f432012-07-16 12:12:45 -070027
28// LinkMonitor tracks the status of a connection by sending ARP
29// messages to the default gateway for a connection. It keeps
Paul Stewart6c72c972012-07-27 11:29:20 -070030// track of response times which can be an indicator of link
31// quality. It signals to caller that the link has failed if
Peter Qiub5d124f2014-04-14 12:05:02 -070032// too many requests go unanswered. It also signals to caller
33// when the gateway's mac address is found or changed.
Paul Stewart3f43f432012-07-16 12:12:45 -070034class LinkMonitor {
35 public:
Paul Stewart6c72c972012-07-27 11:29:20 -070036 typedef base::Closure FailureCallback;
Peter Qiub5d124f2014-04-14 12:05:02 -070037 typedef base::Closure GatewayChangeCallback;
Paul Stewart3f43f432012-07-16 12:12:45 -070038
mukesh agrawalbb2231c2013-07-17 16:32:24 -070039 // The default number of milliseconds between ARP requests. Needed by Metrics.
40 static const int kDefaultTestPeriodMilliseconds;
Paul Stewartff845fc2012-08-07 07:28:44 -070041
Paul Stewart036dba02012-08-07 12:34:41 -070042 // The default list of technologies for which link monitoring is enabled.
mukesh agrawalbb2231c2013-07-17 16:32:24 -070043 // Needed by DefaultProfile.
Paul Stewart036dba02012-08-07 12:34:41 -070044 static const char kDefaultLinkMonitorTechnologies[];
45
Paul Stewartb434ce52013-09-23 13:53:49 -070046 // When the sum of consecutive counted unicast and broadcast failures
47 // equals this value, the failure callback is called, the counters
48 // are reset, and the link monitoring quiesces. Needed by Metrics.
49 static const int kFailureThreshold;
50
Paul Stewart3f43f432012-07-16 12:12:45 -070051 LinkMonitor(const ConnectionRefPtr &connection,
Paul Stewartf1961f82012-09-11 20:45:39 -070052 EventDispatcher *dispatcher, // Owned by caller; can't be NULL.
53 Metrics *metrics, // Owned by caller; must not be NULL.
Paul Stewart6c72c972012-07-27 11:29:20 -070054 DeviceInfo *device_info,
Peter Qiub5d124f2014-04-14 12:05:02 -070055 const FailureCallback &failure_callback,
56 const GatewayChangeCallback &gateway_change_callback);
Paul Stewart3f43f432012-07-16 12:12:45 -070057 virtual ~LinkMonitor();
58
Paul Stewart6c72c972012-07-27 11:29:20 -070059 // Starts link-monitoring on the selected connection. Returns
60 // true if successful, false otherwise.
61 virtual bool Start();
mukesh agrawalbb2231c2013-07-17 16:32:24 -070062 // Stop link-monitoring on the selected connection. Clears any
63 // accumulated statistics.
Paul Stewart6c72c972012-07-27 11:29:20 -070064 virtual void Stop();
65
mukesh agrawalbb2231c2013-07-17 16:32:24 -070066 // Inform LinkMonitor that the system is resuming from sleep.
67 // LinkMonitor will immediately probe the gateway, using a lower
68 // timeout than normal.
69 virtual void OnAfterResume();
70
Paul Stewart6c72c972012-07-27 11:29:20 -070071 // Return modified cumulative average of the gateway ARP response
72 // time. Returns zero if no samples are available. For each
73 // missed ARP response, the sample is assumed to be the full
74 // test period.
Paul Stewartf1961f82012-09-11 20:45:39 -070075 virtual int GetResponseTimeMilliseconds() const;
Paul Stewart9f7823e2012-08-09 10:58:26 -070076
77 // Returns true if the LinkMonitor was ever able to find the default
78 // gateway via broadcast ARP.
79 virtual bool IsGatewayFound() const;
Paul Stewart3f43f432012-07-16 12:12:45 -070080
Peter Qiub5d124f2014-04-14 12:05:02 -070081 const ByteString &gateway_mac_address() const {
82 return gateway_mac_address_;
83 }
84
Paul Stewart3f43f432012-07-16 12:12:45 -070085 private:
Paul Stewart6c72c972012-07-27 11:29:20 -070086 friend class LinkMonitorForTest;
87 friend class LinkMonitorTest;
88
mukesh agrawalbb2231c2013-07-17 16:32:24 -070089 // The number of milliseconds between ARP requests when running a quick test.
90 // Needed by unit tests.
91 static const int kFastTestPeriodMilliseconds;
92
Paul Stewart6c72c972012-07-27 11:29:20 -070093 // The number of samples to compute a "strict" average over. When
94 // more samples than this number arrive, this determines how "slow"
95 // our simple low-pass filter works.
Paul Stewartf1961f82012-09-11 20:45:39 -070096 static const int kMaxResponseSampleFilterDepth;
Paul Stewart6c72c972012-07-27 11:29:20 -070097
Paul Stewartb434ce52013-09-23 13:53:49 -070098 // When the sum of consecutive unicast successes equals this value,
99 // we can assume that in general this gateway supports unicast ARP
100 // requests, and we will count future unicast failures.
101 static const int kUnicastReplyReliabilityThreshold;
102
mukesh agrawalbb2231c2013-07-17 16:32:24 -0700103 // Similar to Start, except that the initial probes use
104 // |probe_period_milliseconds|. After successfully probing with both
105 // broadcast and unicast ARPs (at least one of each), LinkMonitor
106 // switches itself to kDefaultTestPeriodMilliseconds.
107 virtual bool StartInternal(int probe_period_milliseconds);
Paul Stewart6c72c972012-07-27 11:29:20 -0700108 // Add a response time sample to the buffer.
Paul Stewartf1961f82012-09-11 20:45:39 -0700109 void AddResponseTimeSample(int response_time_milliseconds);
Paul Stewart6c72c972012-07-27 11:29:20 -0700110 // Create an ArpClient instance so we can receive and transmit ARP
111 // packets. This method is virtual so it can be overridden in
112 // unit tests.
113 virtual bool CreateClient();
114 // Convert a hardware address byte-string to a colon-separated string.
115 static std::string HardwareAddressToString(const ByteString &address);
116 // Denote a missed response. Returns true if this loss has caused us
117 // to exceed the failure threshold.
118 bool AddMissedResponse();
119 // This I/O callback is triggered whenever the ARP reception socket
120 // has data available to be received.
121 void ReceiveResponse(int fd);
122 // Send the next ARP request. Returns true if successful, false
123 // otherwise.
124 bool SendRequest();
Paul Stewart6c72c972012-07-27 11:29:20 -0700125
Paul Stewartf1961f82012-09-11 20:45:39 -0700126 // The connection on which to perform link monitoring.
Paul Stewart3f43f432012-07-16 12:12:45 -0700127 ConnectionRefPtr connection_;
Paul Stewartf1961f82012-09-11 20:45:39 -0700128 // Dispatcher on which to create delayed tasks.
Paul Stewart3f43f432012-07-16 12:12:45 -0700129 EventDispatcher *dispatcher_;
Paul Stewartf1961f82012-09-11 20:45:39 -0700130 // Metrics instance on which to post performance results.
Paul Stewartff845fc2012-08-07 07:28:44 -0700131 Metrics *metrics_;
Paul Stewartf1961f82012-09-11 20:45:39 -0700132 // DeviceInfo instance for retrieving the MAC address of a device.
Paul Stewart6c72c972012-07-27 11:29:20 -0700133 DeviceInfo *device_info_;
Paul Stewartf1961f82012-09-11 20:45:39 -0700134 // Failure callback method to call if LinkMonitor fails.
Paul Stewart3f43f432012-07-16 12:12:45 -0700135 FailureCallback failure_callback_;
Peter Qiub5d124f2014-04-14 12:05:02 -0700136 // Callback method to call if gateway mac address changes.
137 GatewayChangeCallback gateway_change_callback_;
Paul Stewartf1961f82012-09-11 20:45:39 -0700138 // The MAC address of device associated with this connection.
Paul Stewart6c72c972012-07-27 11:29:20 -0700139 ByteString local_mac_address_;
Paul Stewartf1961f82012-09-11 20:45:39 -0700140 // The MAC address of the default gateway.
Paul Stewart6c72c972012-07-27 11:29:20 -0700141 ByteString gateway_mac_address_;
Paul Stewartf1961f82012-09-11 20:45:39 -0700142 // ArpClient instance used for performing link tests.
Paul Stewart6c72c972012-07-27 11:29:20 -0700143 scoped_ptr<ArpClient> arp_client_;
144
mukesh agrawalbb2231c2013-07-17 16:32:24 -0700145 // How frequently we send an ARP request. This is also the timeout
146 // for a pending request.
147 int test_period_milliseconds_;
Paul Stewart6c72c972012-07-27 11:29:20 -0700148 // The number of consecutive times we have failed in receiving
149 // responses to broadcast ARP requests.
Paul Stewartf1961f82012-09-11 20:45:39 -0700150 int broadcast_failure_count_;
Paul Stewart6c72c972012-07-27 11:29:20 -0700151 // The number of consecutive times we have failed in receiving
152 // responses to unicast ARP requests.
Paul Stewartf1961f82012-09-11 20:45:39 -0700153 int unicast_failure_count_;
mukesh agrawalbb2231c2013-07-17 16:32:24 -0700154 // The number of consecutive times we have succeeded in receiving
155 // responses to broadcast ARP requests.
156 int broadcast_success_count_;
157 // The number of consecutive times we have succeeded in receiving
158 // responses to unicast ARP requests.
159 int unicast_success_count_;
Paul Stewart6c72c972012-07-27 11:29:20 -0700160
161 // Whether this iteration of the test was a unicast request
162 // to the gateway instead of broadcast. The link monitor
163 // alternates between unicast and broadcast requests so that
164 // both types of network traffic is monitored.
165 bool is_unicast_;
166
Paul Stewartb434ce52013-09-23 13:53:49 -0700167 // Whether we have observed that the gateway reliably responds
168 // to unicast ARP requests.
169 bool gateway_supports_unicast_arp_;
170
Paul Stewartf1961f82012-09-11 20:45:39 -0700171 // Number of response samples received in our rolling averge.
172 int response_sample_count_;
173 // The sum of response samples in our rolling average.
174 int response_sample_bucket_;
Paul Stewart6c72c972012-07-27 11:29:20 -0700175
Paul Stewartf1961f82012-09-11 20:45:39 -0700176 // IOCallback that fires when the socket associated with our ArpClient
177 // has a packet to be received. Calls ReceiveResponse().
Paul Stewart6c72c972012-07-27 11:29:20 -0700178 scoped_ptr<IOHandler> receive_response_handler_;
179 // Callback method used for periodic transmission of ARP requests.
180 // When the timer expires this will call SendRequest() through the
181 // void callback function SendRequestTask().
182 base::CancelableClosure send_request_callback_;
183
Paul Stewart0443aa52012-08-09 10:43:50 -0700184 // The time at which the link monitor started.
185 struct timeval started_monitoring_at_;
186
Paul Stewart6c72c972012-07-27 11:29:20 -0700187 // The time at which the last ARP request was sent.
188 struct timeval sent_request_at_;
Paul Stewartf1961f82012-09-11 20:45:39 -0700189 // Time instance for performing GetTimeMonotonic().
Paul Stewart6c72c972012-07-27 11:29:20 -0700190 Time *time_;
Paul Stewart3f43f432012-07-16 12:12:45 -0700191
192 DISALLOW_COPY_AND_ASSIGN(LinkMonitor);
193};
194
195} // namespace shill
196
Paul Stewart6c72c972012-07-27 11:29:20 -0700197#endif // SHILL_LINK_MONITOR_H_