blob: a5e93b24ca5a495f19c1b0d3bce3c03e7e9c7aec [file] [log] [blame]
Ben Chanb061f892013-02-27 17:46:55 -08001// Copyright (c) 2013 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
5#ifndef SHILL_TRAFFIC_MONITOR_H_
6#define SHILL_TRAFFIC_MONITOR_H_
7
Ben Chan22f1fbc2014-10-17 14:18:07 -07008#include <map>
9#include <memory>
10#include <string>
11#include <vector>
12
Ben Chanb061f892013-02-27 17:46:55 -080013#include <base/callback.h>
14#include <base/cancelable_callback.h>
Thieu Le03026662013-04-04 10:45:11 -070015#include <gtest/gtest_prod.h> // for FRIEND_TEST
16
Thieu Lefa7960e2013-04-15 13:14:55 -070017#include "shill/connection_info.h"
18#include "shill/connection_info_reader.h"
Ben Chanb061f892013-02-27 17:46:55 -080019#include "shill/refptr_types.h"
Thieu Le03026662013-04-04 10:45:11 -070020#include "shill/socket_info.h"
Ben Chanb061f892013-02-27 17:46:55 -080021
22namespace shill {
23
24class EventDispatcher;
Thieu Le03026662013-04-04 10:45:11 -070025class SocketInfoReader;
Ben Chanb061f892013-02-27 17:46:55 -080026
27// TrafficMonitor detects certain abnormal scenarios on a network interface
Thieu Le03026662013-04-04 10:45:11 -070028// and notifies an observer of various scenarios via callbacks.
Ben Chanb061f892013-02-27 17:46:55 -080029class TrafficMonitor {
30 public:
Peter Qiudc335f82014-05-15 10:33:17 -070031 // Network problem detected by traffic monitor.
32 enum NetworkProblem {
Alex Vakulenko8a532292014-06-16 17:18:44 -070033 kNetworkProblemCongestedTxQueue = 0,
Peter Qiudc335f82014-05-15 10:33:17 -070034 kNetworkProblemDNSFailure,
35 kNetworkProblemMax
36 };
37
38 typedef base::Callback<void(int)> NetworkProblemDetectedCallback;
Ben Chanb061f892013-02-27 17:46:55 -080039
Paul Stewart1a212a62015-06-16 13:13:10 -070040 TrafficMonitor(const DeviceRefPtr& device, EventDispatcher* dispatcher);
Ben Chanb061f892013-02-27 17:46:55 -080041 virtual ~TrafficMonitor();
42
43 // Starts traffic monitoring on the selected device.
44 virtual void Start();
45
46 // Stops traffic monitoring on the selected device.
47 virtual void Stop();
48
Peter Qiudc335f82014-05-15 10:33:17 -070049 // Sets the callback to invoke, if the traffic monitor detects a network
50 // problem, either too many packets are failing to get transmitted over a
51 // TCP connection or DNS is failing.
52 void set_network_problem_detected_callback(
Paul Stewart1a212a62015-06-16 13:13:10 -070053 const NetworkProblemDetectedCallback& callback) {
Peter Qiudc335f82014-05-15 10:33:17 -070054 network_problem_detected_callback_ = callback;
Ben Chanb061f892013-02-27 17:46:55 -080055 }
56
57 private:
58 friend class TrafficMonitorTest;
Thieu Le03026662013-04-04 10:45:11 -070059 FRIEND_TEST(TrafficMonitorTest,
60 BuildIPPortToTxQueueLengthInvalidConnectionState);
61 FRIEND_TEST(TrafficMonitorTest, BuildIPPortToTxQueueLengthInvalidDevice);
62 FRIEND_TEST(TrafficMonitorTest, BuildIPPortToTxQueueLengthInvalidTimerState);
63 FRIEND_TEST(TrafficMonitorTest, BuildIPPortToTxQueueLengthMultipleEntries);
64 FRIEND_TEST(TrafficMonitorTest, BuildIPPortToTxQueueLengthValid);
65 FRIEND_TEST(TrafficMonitorTest, BuildIPPortToTxQueueLengthZero);
Thieu Lefa7960e2013-04-15 13:14:55 -070066 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsFailureThenSuccess);
67 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsOutstanding);
68 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsStatsReset);
69 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsSuccessful);
70 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsTimedOut);
71 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsTimedOutInvalidProtocol);
72 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsTimedOutInvalidSourceIp);
73 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsTimedOutOutsideTimeWindow);
74 FRIEND_TEST(TrafficMonitorTest, SampleTrafficNonDnsTimedOut);
Thieu Le03026662013-04-04 10:45:11 -070075 FRIEND_TEST(TrafficMonitorTest,
76 SampleTrafficStuckTxQueueIncreasingQueueLength);
77 FRIEND_TEST(TrafficMonitorTest, SampleTrafficStuckTxQueueSameQueueLength);
78 FRIEND_TEST(TrafficMonitorTest,
79 SampleTrafficStuckTxQueueVariousQueueLengths);
80 FRIEND_TEST(TrafficMonitorTest, SampleTrafficUnstuckTxQueueNoConnection);
81 FRIEND_TEST(TrafficMonitorTest, SampleTrafficUnstuckTxQueueStateChanged);
82 FRIEND_TEST(TrafficMonitorTest, SampleTrafficUnstuckTxQueueZeroQueueLength);
Ben Chanb061f892013-02-27 17:46:55 -080083 FRIEND_TEST(TrafficMonitorTest, StartAndStop);
Thieu Le03026662013-04-04 10:45:11 -070084
Ben Chan7fab8972014-08-10 17:14:46 -070085 typedef std::map<std::string, uint64_t> IPPortToTxQueueLengthMap;
Thieu Le03026662013-04-04 10:45:11 -070086
87 // The minimum number of samples that indicate an abnormal scenario
88 // required to trigger the callback.
89 static const int kMinimumFailedSamplesToTrigger;
90 // The frequency at which to sample the TCP connections.
Ben Chan7fab8972014-08-10 17:14:46 -070091 static const int64_t kSamplingIntervalMilliseconds;
Thieu Lefa7960e2013-04-15 13:14:55 -070092 // DNS port.
Ben Chan7fab8972014-08-10 17:14:46 -070093 static const uint16_t kDnsPort;
Thieu Lefa7960e2013-04-15 13:14:55 -070094 // If a DNS "connection" time-to-expire falls below this threshold, then
95 // it's considered a timed out DNS request.
Ben Chan7fab8972014-08-10 17:14:46 -070096 static const int64_t kDnsTimedOutThresholdSeconds;
Thieu Lefa7960e2013-04-15 13:14:55 -070097
98 // Resets congested tx-queues tracking statistics.
99 void ResetCongestedTxQueuesStats();
100 void ResetCongestedTxQueuesStatsWithLogging();
Thieu Le03026662013-04-04 10:45:11 -0700101
102 // Builds map of IP address/port to tx queue lengths from socket info vector.
103 // Skips sockets not on device, tx queue length is 0, connection state is not
104 // established or does not have a pending retransmit timer.
105 void BuildIPPortToTxQueueLength(
Paul Stewart1a212a62015-06-16 13:13:10 -0700106 const std::vector<SocketInfo>& socket_infos,
107 IPPortToTxQueueLengthMap* tx_queue_length);
Ben Chanb061f892013-02-27 17:46:55 -0800108
Thieu Lefa7960e2013-04-15 13:14:55 -0700109 // Checks for congested tx-queue via network statistics.
110 // Returns |true| if tx-queue is congested.
111 bool IsCongestedTxQueues();
112
113 // Resets failing DNS queries tracking statistics.
114 void ResetDnsFailingStats();
115 void ResetDnsFailingStatsWithLogging();
116
117 // Checks to see for failed DNS queries.
118 bool IsDnsFailing();
119
Ben Chanb061f892013-02-27 17:46:55 -0800120 // Samples traffic (e.g. receive and transmit byte counts) on the
121 // selected device and invokes appropriate callbacks when certain
122 // abnormal scenarios are detected.
123 void SampleTraffic();
124
125 // The device on which to perform traffic monitoring.
126 DeviceRefPtr device_;
Thieu Le03026662013-04-04 10:45:11 -0700127
Ben Chanb061f892013-02-27 17:46:55 -0800128 // Dispatcher on which to create delayed tasks.
Paul Stewart1a212a62015-06-16 13:13:10 -0700129 EventDispatcher* dispatcher_;
Thieu Le03026662013-04-04 10:45:11 -0700130
Ben Chanb061f892013-02-27 17:46:55 -0800131 // Callback to invoke when TrafficMonitor needs to sample traffic
132 // of the network interface.
133 base::CancelableClosure sample_traffic_callback_;
134
Peter Qiudc335f82014-05-15 10:33:17 -0700135 // Callback to invoke when we detect a network problem. Possible network
136 // problems that can be detected are congested TCP TX queue and DNS failure.
137 // Refer to enum NetworkProblem for all possible network problems that can be
138 // detected by Traffic Monitor.
139 NetworkProblemDetectedCallback network_problem_detected_callback_;
Thieu Le03026662013-04-04 10:45:11 -0700140
141 // Reads and parses socket information from the system.
Ben Chan22f1fbc2014-10-17 14:18:07 -0700142 std::unique_ptr<SocketInfoReader> socket_info_reader_;
Thieu Le03026662013-04-04 10:45:11 -0700143
Thieu Lefa7960e2013-04-15 13:14:55 -0700144 // Number of consecutive congested tx-queue cases sampled.
145 int accummulated_congested_tx_queues_samples_;
Thieu Le03026662013-04-04 10:45:11 -0700146
147 // Map of tx queue lengths from previous sampling pass.
148 IPPortToTxQueueLengthMap old_tx_queue_lengths_;
Ben Chanb061f892013-02-27 17:46:55 -0800149
Thieu Lefa7960e2013-04-15 13:14:55 -0700150 // Reads and parses connection information from the system.
Ben Chan22f1fbc2014-10-17 14:18:07 -0700151 std::unique_ptr<ConnectionInfoReader> connection_info_reader_;
Thieu Lefa7960e2013-04-15 13:14:55 -0700152
153 // Number of consecutive sample intervals that contains failed DNS requests.
154 int accummulated_dns_failures_samples_;
155
Ben Chanb061f892013-02-27 17:46:55 -0800156 DISALLOW_COPY_AND_ASSIGN(TrafficMonitor);
157};
158
159} // namespace shill
160
161#endif // SHILL_TRAFFIC_MONITOR_H_