blob: 03adcbae745c9919eaed43c00b8c2472da09027d [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
8#include <base/callback.h>
9#include <base/cancelable_callback.h>
Thieu Le03026662013-04-04 10:45:11 -070010#include <gtest/gtest_prod.h> // for FRIEND_TEST
11
12#include <map>
Alex Vakulenko8a532292014-06-16 17:18:44 -070013#include <string>
14#include <vector>
Ben Chanb061f892013-02-27 17:46:55 -080015
Thieu Lefa7960e2013-04-15 13:14:55 -070016#include "shill/connection_info.h"
17#include "shill/connection_info_reader.h"
Ben Chanb061f892013-02-27 17:46:55 -080018#include "shill/refptr_types.h"
Thieu Le03026662013-04-04 10:45:11 -070019#include "shill/socket_info.h"
Ben Chanb061f892013-02-27 17:46:55 -080020
21namespace shill {
22
23class EventDispatcher;
Thieu Le03026662013-04-04 10:45:11 -070024class SocketInfoReader;
Ben Chanb061f892013-02-27 17:46:55 -080025
26// TrafficMonitor detects certain abnormal scenarios on a network interface
Thieu Le03026662013-04-04 10:45:11 -070027// and notifies an observer of various scenarios via callbacks.
Ben Chanb061f892013-02-27 17:46:55 -080028class TrafficMonitor {
29 public:
Peter Qiudc335f82014-05-15 10:33:17 -070030 // Network problem detected by traffic monitor.
31 enum NetworkProblem {
Alex Vakulenko8a532292014-06-16 17:18:44 -070032 kNetworkProblemCongestedTxQueue = 0,
Peter Qiudc335f82014-05-15 10:33:17 -070033 kNetworkProblemDNSFailure,
34 kNetworkProblemMax
35 };
36
37 typedef base::Callback<void(int)> NetworkProblemDetectedCallback;
Ben Chanb061f892013-02-27 17:46:55 -080038
Thieu Le03026662013-04-04 10:45:11 -070039 TrafficMonitor(const DeviceRefPtr &device, EventDispatcher *dispatcher);
Ben Chanb061f892013-02-27 17:46:55 -080040 virtual ~TrafficMonitor();
41
42 // Starts traffic monitoring on the selected device.
43 virtual void Start();
44
45 // Stops traffic monitoring on the selected device.
46 virtual void Stop();
47
Peter Qiudc335f82014-05-15 10:33:17 -070048 // Sets the callback to invoke, if the traffic monitor detects a network
49 // problem, either too many packets are failing to get transmitted over a
50 // TCP connection or DNS is failing.
51 void set_network_problem_detected_callback(
52 const NetworkProblemDetectedCallback &callback) {
53 network_problem_detected_callback_ = callback;
Ben Chanb061f892013-02-27 17:46:55 -080054 }
55
56 private:
57 friend class TrafficMonitorTest;
Thieu Le03026662013-04-04 10:45:11 -070058 FRIEND_TEST(TrafficMonitorTest,
59 BuildIPPortToTxQueueLengthInvalidConnectionState);
60 FRIEND_TEST(TrafficMonitorTest, BuildIPPortToTxQueueLengthInvalidDevice);
61 FRIEND_TEST(TrafficMonitorTest, BuildIPPortToTxQueueLengthInvalidTimerState);
62 FRIEND_TEST(TrafficMonitorTest, BuildIPPortToTxQueueLengthMultipleEntries);
63 FRIEND_TEST(TrafficMonitorTest, BuildIPPortToTxQueueLengthValid);
64 FRIEND_TEST(TrafficMonitorTest, BuildIPPortToTxQueueLengthZero);
Thieu Lefa7960e2013-04-15 13:14:55 -070065 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsFailureThenSuccess);
66 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsOutstanding);
67 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsStatsReset);
68 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsSuccessful);
69 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsTimedOut);
70 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsTimedOutInvalidProtocol);
71 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsTimedOutInvalidSourceIp);
72 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsTimedOutOutsideTimeWindow);
73 FRIEND_TEST(TrafficMonitorTest, SampleTrafficNonDnsTimedOut);
Thieu Le03026662013-04-04 10:45:11 -070074 FRIEND_TEST(TrafficMonitorTest,
75 SampleTrafficStuckTxQueueIncreasingQueueLength);
76 FRIEND_TEST(TrafficMonitorTest, SampleTrafficStuckTxQueueSameQueueLength);
77 FRIEND_TEST(TrafficMonitorTest,
78 SampleTrafficStuckTxQueueVariousQueueLengths);
79 FRIEND_TEST(TrafficMonitorTest, SampleTrafficUnstuckTxQueueNoConnection);
80 FRIEND_TEST(TrafficMonitorTest, SampleTrafficUnstuckTxQueueStateChanged);
81 FRIEND_TEST(TrafficMonitorTest, SampleTrafficUnstuckTxQueueZeroQueueLength);
Ben Chanb061f892013-02-27 17:46:55 -080082 FRIEND_TEST(TrafficMonitorTest, StartAndStop);
Thieu Le03026662013-04-04 10:45:11 -070083
Ben Chan7fab8972014-08-10 17:14:46 -070084 typedef std::map<std::string, uint64_t> IPPortToTxQueueLengthMap;
Thieu Le03026662013-04-04 10:45:11 -070085
86 // The minimum number of samples that indicate an abnormal scenario
87 // required to trigger the callback.
88 static const int kMinimumFailedSamplesToTrigger;
89 // The frequency at which to sample the TCP connections.
Ben Chan7fab8972014-08-10 17:14:46 -070090 static const int64_t kSamplingIntervalMilliseconds;
Thieu Lefa7960e2013-04-15 13:14:55 -070091 // DNS port.
Ben Chan7fab8972014-08-10 17:14:46 -070092 static const uint16_t kDnsPort;
Thieu Lefa7960e2013-04-15 13:14:55 -070093 // If a DNS "connection" time-to-expire falls below this threshold, then
94 // it's considered a timed out DNS request.
Ben Chan7fab8972014-08-10 17:14:46 -070095 static const int64_t kDnsTimedOutThresholdSeconds;
Thieu Lefa7960e2013-04-15 13:14:55 -070096
97 // Resets congested tx-queues tracking statistics.
98 void ResetCongestedTxQueuesStats();
99 void ResetCongestedTxQueuesStatsWithLogging();
Thieu Le03026662013-04-04 10:45:11 -0700100
101 // Builds map of IP address/port to tx queue lengths from socket info vector.
102 // Skips sockets not on device, tx queue length is 0, connection state is not
103 // established or does not have a pending retransmit timer.
104 void BuildIPPortToTxQueueLength(
105 const std::vector<SocketInfo> &socket_infos,
106 IPPortToTxQueueLengthMap *tx_queue_length);
Ben Chanb061f892013-02-27 17:46:55 -0800107
Thieu Lefa7960e2013-04-15 13:14:55 -0700108 // Checks for congested tx-queue via network statistics.
109 // Returns |true| if tx-queue is congested.
110 bool IsCongestedTxQueues();
111
112 // Resets failing DNS queries tracking statistics.
113 void ResetDnsFailingStats();
114 void ResetDnsFailingStatsWithLogging();
115
116 // Checks to see for failed DNS queries.
117 bool IsDnsFailing();
118
Ben Chanb061f892013-02-27 17:46:55 -0800119 // Samples traffic (e.g. receive and transmit byte counts) on the
120 // selected device and invokes appropriate callbacks when certain
121 // abnormal scenarios are detected.
122 void SampleTraffic();
123
124 // The device on which to perform traffic monitoring.
125 DeviceRefPtr device_;
Thieu Le03026662013-04-04 10:45:11 -0700126
Ben Chanb061f892013-02-27 17:46:55 -0800127 // Dispatcher on which to create delayed tasks.
128 EventDispatcher *dispatcher_;
Thieu Le03026662013-04-04 10:45:11 -0700129
Ben Chanb061f892013-02-27 17:46:55 -0800130 // Callback to invoke when TrafficMonitor needs to sample traffic
131 // of the network interface.
132 base::CancelableClosure sample_traffic_callback_;
133
Peter Qiudc335f82014-05-15 10:33:17 -0700134 // Callback to invoke when we detect a network problem. Possible network
135 // problems that can be detected are congested TCP TX queue and DNS failure.
136 // Refer to enum NetworkProblem for all possible network problems that can be
137 // detected by Traffic Monitor.
138 NetworkProblemDetectedCallback network_problem_detected_callback_;
Thieu Le03026662013-04-04 10:45:11 -0700139
140 // Reads and parses socket information from the system.
141 scoped_ptr<SocketInfoReader> socket_info_reader_;
142
Thieu Lefa7960e2013-04-15 13:14:55 -0700143 // Number of consecutive congested tx-queue cases sampled.
144 int accummulated_congested_tx_queues_samples_;
Thieu Le03026662013-04-04 10:45:11 -0700145
146 // Map of tx queue lengths from previous sampling pass.
147 IPPortToTxQueueLengthMap old_tx_queue_lengths_;
Ben Chanb061f892013-02-27 17:46:55 -0800148
Thieu Lefa7960e2013-04-15 13:14:55 -0700149 // Reads and parses connection information from the system.
150 scoped_ptr<ConnectionInfoReader> connection_info_reader_;
151
152 // Number of consecutive sample intervals that contains failed DNS requests.
153 int accummulated_dns_failures_samples_;
154
Ben Chanb061f892013-02-27 17:46:55 -0800155 DISALLOW_COPY_AND_ASSIGN(TrafficMonitor);
156};
157
158} // namespace shill
159
160#endif // SHILL_TRAFFIC_MONITOR_H_