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 32 namespace shill { 33 34 class ArpClient; 35 class DeviceInfo; 36 class EventDispatcher; 37 class IOHandler; 38 class 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. 49 class 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 gateway_mac_address()95 virtual const ByteString& gateway_mac_address() const { 96 return gateway_mac_address_; 97 } set_gateway_mac_address(const ByteString & gateway_mac_address)98 virtual void set_gateway_mac_address(const ByteString& gateway_mac_address) { 99 gateway_mac_address_ = gateway_mac_address; 100 } 101 gateway_supports_unicast_arp()102 virtual bool gateway_supports_unicast_arp() const { 103 return gateway_supports_unicast_arp_; 104 } set_gateway_supports_unicast_arp(bool gateway_supports_unicast_arp)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