1 // 2 // Copyright (C) 2013 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_TRAFFIC_MONITOR_H_ 18 #define SHILL_TRAFFIC_MONITOR_H_ 19 20 #include <map> 21 #include <memory> 22 #include <string> 23 #include <vector> 24 25 #include <base/callback.h> 26 #include <base/cancelable_callback.h> 27 #include <gtest/gtest_prod.h> // for FRIEND_TEST 28 29 #include "shill/connection_info.h" 30 #include "shill/connection_info_reader.h" 31 #include "shill/refptr_types.h" 32 #include "shill/socket_info.h" 33 34 namespace shill { 35 36 class EventDispatcher; 37 class SocketInfoReader; 38 39 // TrafficMonitor detects certain abnormal scenarios on a network interface 40 // and notifies an observer of various scenarios via callbacks. 41 class TrafficMonitor { 42 public: 43 // Network problem detected by traffic monitor. 44 enum NetworkProblem { 45 kNetworkProblemCongestedTxQueue = 0, 46 kNetworkProblemDNSFailure, 47 kNetworkProblemMax 48 }; 49 50 typedef base::Callback<void(int)> NetworkProblemDetectedCallback; 51 52 TrafficMonitor(const DeviceRefPtr& device, EventDispatcher* dispatcher); 53 virtual ~TrafficMonitor(); 54 55 // Starts traffic monitoring on the selected device. 56 virtual void Start(); 57 58 // Stops traffic monitoring on the selected device. 59 virtual void Stop(); 60 61 // Sets the callback to invoke, if the traffic monitor detects a network 62 // problem, either too many packets are failing to get transmitted over a 63 // TCP connection or DNS is failing. 64 void set_network_problem_detected_callback( 65 const NetworkProblemDetectedCallback& callback) { 66 network_problem_detected_callback_ = callback; 67 } 68 69 private: 70 friend class TrafficMonitorTest; 71 FRIEND_TEST(TrafficMonitorTest, 72 BuildIPPortToTxQueueLengthInvalidConnectionState); 73 FRIEND_TEST(TrafficMonitorTest, BuildIPPortToTxQueueLengthInvalidDevice); 74 FRIEND_TEST(TrafficMonitorTest, BuildIPPortToTxQueueLengthInvalidTimerState); 75 FRIEND_TEST(TrafficMonitorTest, BuildIPPortToTxQueueLengthMultipleEntries); 76 FRIEND_TEST(TrafficMonitorTest, BuildIPPortToTxQueueLengthValid); 77 FRIEND_TEST(TrafficMonitorTest, BuildIPPortToTxQueueLengthZero); 78 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsFailureThenSuccess); 79 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsOutstanding); 80 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsStatsReset); 81 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsSuccessful); 82 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsTimedOut); 83 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsTimedOutInvalidProtocol); 84 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsTimedOutInvalidSourceIp); 85 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsTimedOutOutsideTimeWindow); 86 FRIEND_TEST(TrafficMonitorTest, SampleTrafficNonDnsTimedOut); 87 FRIEND_TEST(TrafficMonitorTest, 88 SampleTrafficStuckTxQueueIncreasingQueueLength); 89 FRIEND_TEST(TrafficMonitorTest, SampleTrafficStuckTxQueueSameQueueLength); 90 FRIEND_TEST(TrafficMonitorTest, 91 SampleTrafficStuckTxQueueVariousQueueLengths); 92 FRIEND_TEST(TrafficMonitorTest, SampleTrafficUnstuckTxQueueNoConnection); 93 FRIEND_TEST(TrafficMonitorTest, SampleTrafficUnstuckTxQueueStateChanged); 94 FRIEND_TEST(TrafficMonitorTest, SampleTrafficUnstuckTxQueueZeroQueueLength); 95 FRIEND_TEST(TrafficMonitorTest, StartAndStop); 96 97 typedef std::map<std::string, uint64_t> IPPortToTxQueueLengthMap; 98 99 // The minimum number of samples that indicate an abnormal scenario 100 // required to trigger the callback. 101 static const int kMinimumFailedSamplesToTrigger; 102 // The frequency at which to sample the TCP connections. 103 static const int64_t kSamplingIntervalMilliseconds; 104 // DNS port. 105 static const uint16_t kDnsPort; 106 // If a DNS "connection" time-to-expire falls below this threshold, then 107 // it's considered a timed out DNS request. 108 static const int64_t kDnsTimedOutThresholdSeconds; 109 110 // Resets congested tx-queues tracking statistics. 111 void ResetCongestedTxQueuesStats(); 112 void ResetCongestedTxQueuesStatsWithLogging(); 113 114 // Builds map of IP address/port to tx queue lengths from socket info vector. 115 // Skips sockets not on device, tx queue length is 0, connection state is not 116 // established or does not have a pending retransmit timer. 117 void BuildIPPortToTxQueueLength( 118 const std::vector<SocketInfo>& socket_infos, 119 IPPortToTxQueueLengthMap* tx_queue_length); 120 121 // Checks for congested tx-queue via network statistics. 122 // Returns |true| if tx-queue is congested. 123 bool IsCongestedTxQueues(); 124 125 // Resets failing DNS queries tracking statistics. 126 void ResetDnsFailingStats(); 127 void ResetDnsFailingStatsWithLogging(); 128 129 // Checks to see for failed DNS queries. 130 bool IsDnsFailing(); 131 132 // Samples traffic (e.g. receive and transmit byte counts) on the 133 // selected device and invokes appropriate callbacks when certain 134 // abnormal scenarios are detected. 135 void SampleTraffic(); 136 137 // The device on which to perform traffic monitoring. 138 DeviceRefPtr device_; 139 140 // Dispatcher on which to create delayed tasks. 141 EventDispatcher* dispatcher_; 142 143 // Callback to invoke when TrafficMonitor needs to sample traffic 144 // of the network interface. 145 base::CancelableClosure sample_traffic_callback_; 146 147 // Callback to invoke when we detect a network problem. Possible network 148 // problems that can be detected are congested TCP TX queue and DNS failure. 149 // Refer to enum NetworkProblem for all possible network problems that can be 150 // detected by Traffic Monitor. 151 NetworkProblemDetectedCallback network_problem_detected_callback_; 152 153 // Reads and parses socket information from the system. 154 std::unique_ptr<SocketInfoReader> socket_info_reader_; 155 156 // Number of consecutive congested tx-queue cases sampled. 157 int accummulated_congested_tx_queues_samples_; 158 159 // Map of tx queue lengths from previous sampling pass. 160 IPPortToTxQueueLengthMap old_tx_queue_lengths_; 161 162 // Reads and parses connection information from the system. 163 std::unique_ptr<ConnectionInfoReader> connection_info_reader_; 164 165 // Number of consecutive sample intervals that contains failed DNS requests. 166 int accummulated_dns_failures_samples_; 167 168 DISALLOW_COPY_AND_ASSIGN(TrafficMonitor); 169 }; 170 171 } // namespace shill 172 173 #endif // SHILL_TRAFFIC_MONITOR_H_ 174