blob: 2f1987678fcc8692f03aec1408f4d5e043e8aebb [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>
Ben Chanb061f892013-02-27 17:46:55 -080013
Thieu Lefa7960e2013-04-15 13:14:55 -070014#include "shill/connection_info.h"
15#include "shill/connection_info_reader.h"
Ben Chanb061f892013-02-27 17:46:55 -080016#include "shill/refptr_types.h"
Thieu Le03026662013-04-04 10:45:11 -070017#include "shill/socket_info.h"
Ben Chanb061f892013-02-27 17:46:55 -080018
19namespace shill {
20
21class EventDispatcher;
Thieu Le03026662013-04-04 10:45:11 -070022class SocketInfoReader;
Ben Chanb061f892013-02-27 17:46:55 -080023
24// TrafficMonitor detects certain abnormal scenarios on a network interface
Thieu Le03026662013-04-04 10:45:11 -070025// and notifies an observer of various scenarios via callbacks.
Ben Chanb061f892013-02-27 17:46:55 -080026class TrafficMonitor {
27 public:
Thieu Le03026662013-04-04 10:45:11 -070028 typedef base::Closure TcpOutTrafficNotRoutedCallback;
Ben Chanb061f892013-02-27 17:46:55 -080029
Thieu Le03026662013-04-04 10:45:11 -070030 TrafficMonitor(const DeviceRefPtr &device, EventDispatcher *dispatcher);
Ben Chanb061f892013-02-27 17:46:55 -080031 virtual ~TrafficMonitor();
32
33 // Starts traffic monitoring on the selected device.
34 virtual void Start();
35
36 // Stops traffic monitoring on the selected device.
37 virtual void Stop();
38
Thieu Le03026662013-04-04 10:45:11 -070039 // Sets the callback to invoke, if the traffic monitor detects that too many
40 // packets are failing to get transmitted over a TCP connection.
41 void set_tcp_out_traffic_not_routed_callback(
42 const TcpOutTrafficNotRoutedCallback &callback) {
43 outgoing_tcp_packets_not_routed_callback_ = callback;
Ben Chanb061f892013-02-27 17:46:55 -080044 }
45
46 private:
47 friend class TrafficMonitorTest;
Thieu Le03026662013-04-04 10:45:11 -070048 FRIEND_TEST(TrafficMonitorTest,
49 BuildIPPortToTxQueueLengthInvalidConnectionState);
50 FRIEND_TEST(TrafficMonitorTest, BuildIPPortToTxQueueLengthInvalidDevice);
51 FRIEND_TEST(TrafficMonitorTest, BuildIPPortToTxQueueLengthInvalidTimerState);
52 FRIEND_TEST(TrafficMonitorTest, BuildIPPortToTxQueueLengthMultipleEntries);
53 FRIEND_TEST(TrafficMonitorTest, BuildIPPortToTxQueueLengthValid);
54 FRIEND_TEST(TrafficMonitorTest, BuildIPPortToTxQueueLengthZero);
Thieu Lefa7960e2013-04-15 13:14:55 -070055 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsFailureThenSuccess);
56 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsOutstanding);
57 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsStatsReset);
58 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsSuccessful);
59 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsTimedOut);
60 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsTimedOutInvalidProtocol);
61 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsTimedOutInvalidSourceIp);
62 FRIEND_TEST(TrafficMonitorTest, SampleTrafficDnsTimedOutOutsideTimeWindow);
63 FRIEND_TEST(TrafficMonitorTest, SampleTrafficNonDnsTimedOut);
Thieu Le03026662013-04-04 10:45:11 -070064 FRIEND_TEST(TrafficMonitorTest,
65 SampleTrafficStuckTxQueueIncreasingQueueLength);
66 FRIEND_TEST(TrafficMonitorTest, SampleTrafficStuckTxQueueSameQueueLength);
67 FRIEND_TEST(TrafficMonitorTest,
68 SampleTrafficStuckTxQueueVariousQueueLengths);
69 FRIEND_TEST(TrafficMonitorTest, SampleTrafficUnstuckTxQueueNoConnection);
70 FRIEND_TEST(TrafficMonitorTest, SampleTrafficUnstuckTxQueueStateChanged);
71 FRIEND_TEST(TrafficMonitorTest, SampleTrafficUnstuckTxQueueZeroQueueLength);
Ben Chanb061f892013-02-27 17:46:55 -080072 FRIEND_TEST(TrafficMonitorTest, StartAndStop);
Thieu Le03026662013-04-04 10:45:11 -070073
74 typedef std::map<std::string, uint64> IPPortToTxQueueLengthMap;
75
76 // The minimum number of samples that indicate an abnormal scenario
77 // required to trigger the callback.
78 static const int kMinimumFailedSamplesToTrigger;
79 // The frequency at which to sample the TCP connections.
80 static const int64 kSamplingIntervalMilliseconds;
Thieu Lefa7960e2013-04-15 13:14:55 -070081 // DNS port.
82 static const uint16 kDnsPort;
83 // If a DNS "connection" time-to-expire falls below this threshold, then
84 // it's considered a timed out DNS request.
85 static const int64 kDnsTimedOutThresholdSeconds;
86
87 // Resets congested tx-queues tracking statistics.
88 void ResetCongestedTxQueuesStats();
89 void ResetCongestedTxQueuesStatsWithLogging();
Thieu Le03026662013-04-04 10:45:11 -070090
91 // Builds map of IP address/port to tx queue lengths from socket info vector.
92 // Skips sockets not on device, tx queue length is 0, connection state is not
93 // established or does not have a pending retransmit timer.
94 void BuildIPPortToTxQueueLength(
95 const std::vector<SocketInfo> &socket_infos,
96 IPPortToTxQueueLengthMap *tx_queue_length);
Ben Chanb061f892013-02-27 17:46:55 -080097
Thieu Lefa7960e2013-04-15 13:14:55 -070098 // Checks for congested tx-queue via network statistics.
99 // Returns |true| if tx-queue is congested.
100 bool IsCongestedTxQueues();
101
102 // Resets failing DNS queries tracking statistics.
103 void ResetDnsFailingStats();
104 void ResetDnsFailingStatsWithLogging();
105
106 // Checks to see for failed DNS queries.
107 bool IsDnsFailing();
108
Ben Chanb061f892013-02-27 17:46:55 -0800109 // Samples traffic (e.g. receive and transmit byte counts) on the
110 // selected device and invokes appropriate callbacks when certain
111 // abnormal scenarios are detected.
112 void SampleTraffic();
113
114 // The device on which to perform traffic monitoring.
115 DeviceRefPtr device_;
Thieu Le03026662013-04-04 10:45:11 -0700116
Ben Chanb061f892013-02-27 17:46:55 -0800117 // Dispatcher on which to create delayed tasks.
118 EventDispatcher *dispatcher_;
Thieu Le03026662013-04-04 10:45:11 -0700119
Ben Chanb061f892013-02-27 17:46:55 -0800120 // Callback to invoke when TrafficMonitor needs to sample traffic
121 // of the network interface.
122 base::CancelableClosure sample_traffic_callback_;
123
Thieu Le03026662013-04-04 10:45:11 -0700124 // Callback to invoke when we detect that the send queue has been increasing
125 // on an ESTABLISHED TCP connection through the network interface.
126 TcpOutTrafficNotRoutedCallback outgoing_tcp_packets_not_routed_callback_;
127
128 // Reads and parses socket information from the system.
129 scoped_ptr<SocketInfoReader> socket_info_reader_;
130
Thieu Lefa7960e2013-04-15 13:14:55 -0700131 // Number of consecutive congested tx-queue cases sampled.
132 int accummulated_congested_tx_queues_samples_;
Thieu Le03026662013-04-04 10:45:11 -0700133
134 // Map of tx queue lengths from previous sampling pass.
135 IPPortToTxQueueLengthMap old_tx_queue_lengths_;
Ben Chanb061f892013-02-27 17:46:55 -0800136
Thieu Lefa7960e2013-04-15 13:14:55 -0700137 // Reads and parses connection information from the system.
138 scoped_ptr<ConnectionInfoReader> connection_info_reader_;
139
140 // Number of consecutive sample intervals that contains failed DNS requests.
141 int accummulated_dns_failures_samples_;
142
Ben Chanb061f892013-02-27 17:46:55 -0800143 DISALLOW_COPY_AND_ASSIGN(TrafficMonitor);
144};
145
146} // namespace shill
147
148#endif // SHILL_TRAFFIC_MONITOR_H_