Home | History | Annotate | Download | only in shill
      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 
     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