1// 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// 16 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 69 ActiveLinkMonitor(const ConnectionRefPtr& connection, 70 EventDispatcher* dispatcher, 71 Metrics* metrics, 72 DeviceInfo* device_info, 73 const FailureCallback& failure_callback, 74 const SuccessCallback& success_callback); 75 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 95 virtual const ByteString& gateway_mac_address() const { 96 return gateway_mac_address_; 97 } 98 virtual void set_gateway_mac_address(const ByteString& gateway_mac_address) { 99 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 } 109 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. 137 static std::string HardwareAddressToString(const ByteString& address); 138 // 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. 150 EventDispatcher* dispatcher_; 151 // Metrics instance on which to post performance results. 152 Metrics* metrics_; 153 // DeviceInfo instance for retrieving the MAC address of a device. 154 DeviceInfo* device_info_; 155 // 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(). 207 Time* time_; 208 209 DISALLOW_COPY_AND_ASSIGN(ActiveLinkMonitor); 210}; 211 212} // namespace shill 213 214#endif // SHILL_ACTIVE_LINK_MONITOR_H_ 215