1c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 2c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Copyright (C) 2013 The Android Open Source Project 3c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 4c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Licensed under the Apache License, Version 2.0 (the "License"); 5c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// you may not use this file except in compliance with the License. 6c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// You may obtain a copy of the License at 7c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 8c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// http://www.apache.org/licenses/LICENSE-2.0 9c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 10c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// Unless required by applicable law or agreed to in writing, software 11c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// distributed under the License is distributed on an "AS IS" BASIS, 12c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// See the License for the specific language governing permissions and 14c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// limitations under the License. 15c0beca55d290fe0b1c96d78cbbcf94b05c23f5a5Peter Qiu// 16b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan 17b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan#include "shill/traffic_monitor.h" 18b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan 19b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan#include <base/bind.h> 20a0ddf46e466bd4ba3d20952f0a6988c680c1af14Ben Chan#include <base/strings/stringprintf.h> 21fa7960effd89d27830ee742c22cf825e3c126097Thieu Le#include <netinet/in.h> 22b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan 23b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan#include "shill/device.h" 24b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan#include "shill/device_info.h" 25b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan#include "shill/event_dispatcher.h" 260302666245cea4a54dac13a9b6b11ddf04048143Thieu Le#include "shill/logging.h" 270302666245cea4a54dac13a9b6b11ddf04048143Thieu Le#include "shill/socket_info_reader.h" 28b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan 290302666245cea4a54dac13a9b6b11ddf04048143Thieu Leusing base::StringPrintf; 300302666245cea4a54dac13a9b6b11ddf04048143Thieu Leusing std::string; 310302666245cea4a54dac13a9b6b11ddf04048143Thieu Leusing std::vector; 32b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan 330302666245cea4a54dac13a9b6b11ddf04048143Thieu Lenamespace shill { 34b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan 35c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silbersteinnamespace Logging { 36c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silbersteinstatic auto kModuleLogScope = ScopeLogger::kLink; 371a212a6b98b22ad1d69652bb26a9e94138635476Paul Stewartstatic string ObjectID(Device* d) { return d->link_name(); } 38c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein} 39c9c31d8497c3f053c2160408cc386010fc125fadRebecca Silberstein 400302666245cea4a54dac13a9b6b11ddf04048143Thieu Le// static 417fab89734d88724a288e96a9996b15548c5294c7Ben Chanconst uint16_t TrafficMonitor::kDnsPort = 53; 427fab89734d88724a288e96a9996b15548c5294c7Ben Chanconst int64_t TrafficMonitor::kDnsTimedOutThresholdSeconds = 15; 430302666245cea4a54dac13a9b6b11ddf04048143Thieu Leconst int TrafficMonitor::kMinimumFailedSamplesToTrigger = 2; 447fab89734d88724a288e96a9996b15548c5294c7Ben Chanconst int64_t TrafficMonitor::kSamplingIntervalMilliseconds = 5000; 45b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan 461a212a6b98b22ad1d69652bb26a9e94138635476Paul StewartTrafficMonitor::TrafficMonitor(const DeviceRefPtr& device, 471a212a6b98b22ad1d69652bb26a9e94138635476Paul Stewart EventDispatcher* dispatcher) 48b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan : device_(device), 49b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan dispatcher_(dispatcher), 500302666245cea4a54dac13a9b6b11ddf04048143Thieu Le socket_info_reader_(new SocketInfoReader), 51fa7960effd89d27830ee742c22cf825e3c126097Thieu Le accummulated_congested_tx_queues_samples_(0), 52fa7960effd89d27830ee742c22cf825e3c126097Thieu Le connection_info_reader_(new ConnectionInfoReader), 53fa7960effd89d27830ee742c22cf825e3c126097Thieu Le accummulated_dns_failures_samples_(0) { 54b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan} 55b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan 56b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen ChanTrafficMonitor::~TrafficMonitor() { 57b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan Stop(); 58b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan} 59b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan 60b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chanvoid TrafficMonitor::Start() { 610951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko SLOG(device_.get(), 2) << __func__; 62b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan Stop(); 63b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan 64b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan sample_traffic_callback_.Reset(base::Bind(&TrafficMonitor::SampleTraffic, 65b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan base::Unretained(this))); 66b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan dispatcher_->PostDelayedTask(sample_traffic_callback_.callback(), 67b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan kSamplingIntervalMilliseconds); 68b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan} 69b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan 70b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chanvoid TrafficMonitor::Stop() { 710951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko SLOG(device_.get(), 2) << __func__; 72b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan sample_traffic_callback_.Cancel(); 73fa7960effd89d27830ee742c22cf825e3c126097Thieu Le ResetCongestedTxQueuesStats(); 74fa7960effd89d27830ee742c22cf825e3c126097Thieu Le ResetDnsFailingStats(); 75fa7960effd89d27830ee742c22cf825e3c126097Thieu Le} 76fa7960effd89d27830ee742c22cf825e3c126097Thieu Le 77fa7960effd89d27830ee742c22cf825e3c126097Thieu Levoid TrafficMonitor::ResetCongestedTxQueuesStats() { 78fa7960effd89d27830ee742c22cf825e3c126097Thieu Le accummulated_congested_tx_queues_samples_ = 0; 79fa7960effd89d27830ee742c22cf825e3c126097Thieu Le} 80fa7960effd89d27830ee742c22cf825e3c126097Thieu Le 81fa7960effd89d27830ee742c22cf825e3c126097Thieu Levoid TrafficMonitor::ResetCongestedTxQueuesStatsWithLogging() { 820951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko SLOG(device_.get(), 2) << __func__ << ": Tx-queues decongested"; 83fa7960effd89d27830ee742c22cf825e3c126097Thieu Le ResetCongestedTxQueuesStats(); 84b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan} 85b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan 860302666245cea4a54dac13a9b6b11ddf04048143Thieu Levoid TrafficMonitor::BuildIPPortToTxQueueLength( 871a212a6b98b22ad1d69652bb26a9e94138635476Paul Stewart const vector<SocketInfo>& socket_infos, 881a212a6b98b22ad1d69652bb26a9e94138635476Paul Stewart IPPortToTxQueueLengthMap* tx_queue_lengths) { 890951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko SLOG(device_.get(), 3) << __func__; 900302666245cea4a54dac13a9b6b11ddf04048143Thieu Le string device_ip_address = device_->ipconfig()->properties().address; 911a212a6b98b22ad1d69652bb26a9e94138635476Paul Stewart for (const auto& info : socket_infos) { 920951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko SLOG(device_.get(), 4) << "SocketInfo(IP=" 930951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko << info.local_ip_address().ToString() 940951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko << ", TX=" << info.transmit_queue_value() 950951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko << ", State=" << info.connection_state() 960951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko << ", TimerState=" << info.timer_state(); 976db7b24348e69639e19cd6c408388b10d6ee54fePaul Stewart if (info.local_ip_address().ToString() != device_ip_address || 986db7b24348e69639e19cd6c408388b10d6ee54fePaul Stewart info.transmit_queue_value() == 0 || 996db7b24348e69639e19cd6c408388b10d6ee54fePaul Stewart info.connection_state() != SocketInfo::kConnectionStateEstablished || 1006db7b24348e69639e19cd6c408388b10d6ee54fePaul Stewart (info.timer_state() != SocketInfo::kTimerStateRetransmitTimerPending && 1016db7b24348e69639e19cd6c408388b10d6ee54fePaul Stewart info.timer_state() != 102d42d8ec85a9a1bdc406870b75d1b9e266fbaaa02Arman Uguray SocketInfo::kTimerStateZeroWindowProbeTimerPending)) { 1030951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko SLOG(device_.get(), 4) << "Connection Filtered."; 1040302666245cea4a54dac13a9b6b11ddf04048143Thieu Le continue; 105d42d8ec85a9a1bdc406870b75d1b9e266fbaaa02Arman Uguray } 1060951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko SLOG(device_.get(), 3) << "Monitoring connection: TX=" 1070951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko << info.transmit_queue_value() 1080951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko << " TimerState=" << info.timer_state(); 1090302666245cea4a54dac13a9b6b11ddf04048143Thieu Le 1100302666245cea4a54dac13a9b6b11ddf04048143Thieu Le string local_ip_port = 1110302666245cea4a54dac13a9b6b11ddf04048143Thieu Le StringPrintf("%s:%d", 1126db7b24348e69639e19cd6c408388b10d6ee54fePaul Stewart info.local_ip_address().ToString().c_str(), 1136db7b24348e69639e19cd6c408388b10d6ee54fePaul Stewart info.local_port()); 1146db7b24348e69639e19cd6c408388b10d6ee54fePaul Stewart (*tx_queue_lengths)[local_ip_port] = info.transmit_queue_value(); 115b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan } 1160302666245cea4a54dac13a9b6b11ddf04048143Thieu Le} 117b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan 118fa7960effd89d27830ee742c22cf825e3c126097Thieu Lebool TrafficMonitor::IsCongestedTxQueues() { 1190951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko SLOG(device_.get(), 4) << __func__; 1200302666245cea4a54dac13a9b6b11ddf04048143Thieu Le vector<SocketInfo> socket_infos; 1210302666245cea4a54dac13a9b6b11ddf04048143Thieu Le if (!socket_info_reader_->LoadTcpSocketInfo(&socket_infos) || 1220302666245cea4a54dac13a9b6b11ddf04048143Thieu Le socket_infos.empty()) { 1230951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko SLOG(device_.get(), 3) << __func__ << ": Empty socket info"; 124fa7960effd89d27830ee742c22cf825e3c126097Thieu Le ResetCongestedTxQueuesStatsWithLogging(); 125fa7960effd89d27830ee742c22cf825e3c126097Thieu Le return false; 1260302666245cea4a54dac13a9b6b11ddf04048143Thieu Le } 127fa7960effd89d27830ee742c22cf825e3c126097Thieu Le bool congested_tx_queues = true; 1280302666245cea4a54dac13a9b6b11ddf04048143Thieu Le IPPortToTxQueueLengthMap curr_tx_queue_lengths; 1290302666245cea4a54dac13a9b6b11ddf04048143Thieu Le BuildIPPortToTxQueueLength(socket_infos, &curr_tx_queue_lengths); 1300302666245cea4a54dac13a9b6b11ddf04048143Thieu Le if (curr_tx_queue_lengths.empty()) { 1310951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko SLOG(device_.get(), 3) << __func__ << ": No interesting socket info"; 132fa7960effd89d27830ee742c22cf825e3c126097Thieu Le ResetCongestedTxQueuesStatsWithLogging(); 1330302666245cea4a54dac13a9b6b11ddf04048143Thieu Le } else { 1341a212a6b98b22ad1d69652bb26a9e94138635476Paul Stewart for (const auto& length_entry : old_tx_queue_lengths_) { 1350302666245cea4a54dac13a9b6b11ddf04048143Thieu Le IPPortToTxQueueLengthMap::iterator curr_tx_queue_it = 1366db7b24348e69639e19cd6c408388b10d6ee54fePaul Stewart curr_tx_queue_lengths.find(length_entry.first); 1370302666245cea4a54dac13a9b6b11ddf04048143Thieu Le if (curr_tx_queue_it == curr_tx_queue_lengths.end() || 1386db7b24348e69639e19cd6c408388b10d6ee54fePaul Stewart curr_tx_queue_it->second < length_entry.second) { 1390302666245cea4a54dac13a9b6b11ddf04048143Thieu Le congested_tx_queues = false; 140f84a4242b4218dc375449ab2d68085226f43ce5bArman Uguray // TODO(armansito): If we had a false positive earlier, we may 141f84a4242b4218dc375449ab2d68085226f43ce5bArman Uguray // want to correct it here by invoking a "connection back to normal 142f84a4242b4218dc375449ab2d68085226f43ce5bArman Uguray // callback", so that the OutOfCredits property can be set to 143f84a4242b4218dc375449ab2d68085226f43ce5bArman Uguray // false. 1440302666245cea4a54dac13a9b6b11ddf04048143Thieu Le break; 1450302666245cea4a54dac13a9b6b11ddf04048143Thieu Le } 1460302666245cea4a54dac13a9b6b11ddf04048143Thieu Le } 147fa7960effd89d27830ee742c22cf825e3c126097Thieu Le if (congested_tx_queues) { 148fa7960effd89d27830ee742c22cf825e3c126097Thieu Le ++accummulated_congested_tx_queues_samples_; 1490951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko SLOG(device_.get(), 2) << __func__ 1500951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko << ": Congested tx-queues detected (" 1510951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko << accummulated_congested_tx_queues_samples_ 1520951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko << ")"; 153b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan } 154b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan } 1550302666245cea4a54dac13a9b6b11ddf04048143Thieu Le old_tx_queue_lengths_ = curr_tx_queue_lengths; 156b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan 157fa7960effd89d27830ee742c22cf825e3c126097Thieu Le return congested_tx_queues; 158fa7960effd89d27830ee742c22cf825e3c126097Thieu Le} 159fa7960effd89d27830ee742c22cf825e3c126097Thieu Le 160fa7960effd89d27830ee742c22cf825e3c126097Thieu Levoid TrafficMonitor::ResetDnsFailingStats() { 161fa7960effd89d27830ee742c22cf825e3c126097Thieu Le accummulated_dns_failures_samples_ = 0; 162fa7960effd89d27830ee742c22cf825e3c126097Thieu Le} 163fa7960effd89d27830ee742c22cf825e3c126097Thieu Le 164fa7960effd89d27830ee742c22cf825e3c126097Thieu Levoid TrafficMonitor::ResetDnsFailingStatsWithLogging() { 1650951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko SLOG(device_.get(), 2) << __func__ << ": DNS queries restored"; 166fa7960effd89d27830ee742c22cf825e3c126097Thieu Le ResetDnsFailingStats(); 167fa7960effd89d27830ee742c22cf825e3c126097Thieu Le} 168fa7960effd89d27830ee742c22cf825e3c126097Thieu Le 169fa7960effd89d27830ee742c22cf825e3c126097Thieu Lebool TrafficMonitor::IsDnsFailing() { 1700951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko SLOG(device_.get(), 4) << __func__; 171fa7960effd89d27830ee742c22cf825e3c126097Thieu Le vector<ConnectionInfo> connection_infos; 172fa7960effd89d27830ee742c22cf825e3c126097Thieu Le if (!connection_info_reader_->LoadConnectionInfo(&connection_infos) || 173fa7960effd89d27830ee742c22cf825e3c126097Thieu Le connection_infos.empty()) { 1740951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko SLOG(device_.get(), 3) << __func__ << ": Empty connection info"; 175fa7960effd89d27830ee742c22cf825e3c126097Thieu Le } else { 176fa7960effd89d27830ee742c22cf825e3c126097Thieu Le // The time-to-expire counter is used to determine when a DNS request 177fa7960effd89d27830ee742c22cf825e3c126097Thieu Le // has timed out. This counter is the number of seconds remaining until 178fa7960effd89d27830ee742c22cf825e3c126097Thieu Le // the entry is removed from the system IP connection tracker. The 179fa7960effd89d27830ee742c22cf825e3c126097Thieu Le // default time is 30 seconds. This is too long of a wait. Instead, we 180fa7960effd89d27830ee742c22cf825e3c126097Thieu Le // want to time out at |kDnsTimedOutThresholdSeconds|. Unfortunately, 181fa7960effd89d27830ee742c22cf825e3c126097Thieu Le // we cannot simply look for entries less than 182fa7960effd89d27830ee742c22cf825e3c126097Thieu Le // |kDnsTimedOutThresholdSeconds| because we will count the entry 183fa7960effd89d27830ee742c22cf825e3c126097Thieu Le // multiple times once its time-to-expire is less than 184fa7960effd89d27830ee742c22cf825e3c126097Thieu Le // |kDnsTimedOutThresholdSeconds|. To ensure that we only count an 185fa7960effd89d27830ee742c22cf825e3c126097Thieu Le // entry once, we look for entries in this time window between 186fa7960effd89d27830ee742c22cf825e3c126097Thieu Le // |kDnsTimedOutThresholdSeconds| and |kDnsTimedOutLowerThresholdSeconds|. 1877fab89734d88724a288e96a9996b15548c5294c7Ben Chan const int64_t kDnsTimedOutLowerThresholdSeconds = 188fa7960effd89d27830ee742c22cf825e3c126097Thieu Le kDnsTimedOutThresholdSeconds - kSamplingIntervalMilliseconds / 1000; 189fa7960effd89d27830ee742c22cf825e3c126097Thieu Le string device_ip_address = device_->ipconfig()->properties().address; 1901a212a6b98b22ad1d69652bb26a9e94138635476Paul Stewart for (const auto& info : connection_infos) { 1916db7b24348e69639e19cd6c408388b10d6ee54fePaul Stewart if (info.protocol() != IPPROTO_UDP || 1926db7b24348e69639e19cd6c408388b10d6ee54fePaul Stewart info.time_to_expire_seconds() > kDnsTimedOutThresholdSeconds || 1936db7b24348e69639e19cd6c408388b10d6ee54fePaul Stewart info.time_to_expire_seconds() <= kDnsTimedOutLowerThresholdSeconds || 1946db7b24348e69639e19cd6c408388b10d6ee54fePaul Stewart !info.is_unreplied() || 1956db7b24348e69639e19cd6c408388b10d6ee54fePaul Stewart info.original_source_ip_address().ToString() != device_ip_address || 1966db7b24348e69639e19cd6c408388b10d6ee54fePaul Stewart info.original_destination_port() != kDnsPort) 197fa7960effd89d27830ee742c22cf825e3c126097Thieu Le continue; 198fa7960effd89d27830ee742c22cf825e3c126097Thieu Le 199fa7960effd89d27830ee742c22cf825e3c126097Thieu Le ++accummulated_dns_failures_samples_; 2000951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko SLOG(device_.get(), 2) << __func__ 2010951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko << ": DNS failures detected (" 2020951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko << accummulated_dns_failures_samples_ << ")"; 203fa7960effd89d27830ee742c22cf825e3c126097Thieu Le return true; 204fa7960effd89d27830ee742c22cf825e3c126097Thieu Le } 205fa7960effd89d27830ee742c22cf825e3c126097Thieu Le } 206fa7960effd89d27830ee742c22cf825e3c126097Thieu Le ResetDnsFailingStatsWithLogging(); 207fa7960effd89d27830ee742c22cf825e3c126097Thieu Le return false; 208fa7960effd89d27830ee742c22cf825e3c126097Thieu Le} 209fa7960effd89d27830ee742c22cf825e3c126097Thieu Le 210fa7960effd89d27830ee742c22cf825e3c126097Thieu Levoid TrafficMonitor::SampleTraffic() { 2110951ccbfca977a9cf218b2e4308aa26fb4d06ef9Alex Vakulenko SLOG(device_.get(), 3) << __func__; 212fa7960effd89d27830ee742c22cf825e3c126097Thieu Le 213dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu // Schedule the sample callback first, so it is possible for the network 214dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu // problem callback to stop the traffic monitor. 215dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu dispatcher_->PostDelayedTask(sample_traffic_callback_.callback(), 216dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu kSamplingIntervalMilliseconds); 217dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu 218fa7960effd89d27830ee742c22cf825e3c126097Thieu Le if (IsCongestedTxQueues() && 219fa7960effd89d27830ee742c22cf825e3c126097Thieu Le accummulated_congested_tx_queues_samples_ == 220fa7960effd89d27830ee742c22cf825e3c126097Thieu Le kMinimumFailedSamplesToTrigger) { 221fa7960effd89d27830ee742c22cf825e3c126097Thieu Le LOG(WARNING) << "Congested tx queues detected, out-of-credits?"; 222dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu network_problem_detected_callback_.Run(kNetworkProblemCongestedTxQueue); 223fa7960effd89d27830ee742c22cf825e3c126097Thieu Le } else if (IsDnsFailing() && 224fa7960effd89d27830ee742c22cf825e3c126097Thieu Le accummulated_dns_failures_samples_ == 225fa7960effd89d27830ee742c22cf825e3c126097Thieu Le kMinimumFailedSamplesToTrigger) { 226fa7960effd89d27830ee742c22cf825e3c126097Thieu Le LOG(WARNING) << "DNS queries failing, out-of-credits?"; 227dc335f81a9d0ffe8efd02a96d3cd17399a06e61ePeter Qiu network_problem_detected_callback_.Run(kNetworkProblemDNSFailure); 228fa7960effd89d27830ee742c22cf825e3c126097Thieu Le } 229b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan} 230b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan 231b061f89e7088c7fba50b49ee5ac876619c9e8a7eBen Chan} // namespace shill 232