blob: 9206ae47fb60557c324a2b6df0dda95679e4d674 [file] [log] [blame]
// Copyright (c) 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/third_party/quiche/src/quic/core/quic_network_blackhole_detector.h"
#include "net/third_party/quiche/src/quic/core/quic_constants.h"
namespace quic {
namespace {
class AlarmDelegate : public QuicAlarm::Delegate {
public:
explicit AlarmDelegate(QuicNetworkBlackholeDetector* detector)
: detector_(detector) {}
AlarmDelegate(const AlarmDelegate&) = delete;
AlarmDelegate& operator=(const AlarmDelegate&) = delete;
void OnAlarm() override { detector_->OnAlarm(); }
private:
QuicNetworkBlackholeDetector* detector_;
};
} // namespace
QuicNetworkBlackholeDetector::QuicNetworkBlackholeDetector(
Delegate* delegate,
QuicConnectionArena* arena,
QuicAlarmFactory* alarm_factory)
: delegate_(delegate),
path_degrading_deadline_(QuicTime::Zero()),
blackhole_deadline_(QuicTime::Zero()),
alarm_(
alarm_factory->CreateAlarm(arena->New<AlarmDelegate>(this), arena)) {}
void QuicNetworkBlackholeDetector::OnAlarm() {
if (path_degrading_deadline_.IsInitialized()) {
path_degrading_deadline_ = QuicTime::Zero();
delegate_->OnPathDegradingDetected();
// Switch to blackhole detection mode.
alarm_->Update(blackhole_deadline_, kAlarmGranularity);
return;
}
if (blackhole_deadline_.IsInitialized()) {
blackhole_deadline_ = QuicTime::Zero();
delegate_->OnBlackholeDetected();
}
}
void QuicNetworkBlackholeDetector::StopDetection() {
alarm_->Cancel();
path_degrading_deadline_ = QuicTime::Zero();
blackhole_deadline_ = QuicTime::Zero();
}
void QuicNetworkBlackholeDetector::RestartDetection(
QuicTime path_degrading_deadline,
QuicTime blackhole_deadline) {
path_degrading_deadline_ = path_degrading_deadline;
blackhole_deadline_ = blackhole_deadline;
QUIC_BUG_IF(path_degrading_deadline_.IsInitialized() &&
blackhole_deadline_.IsInitialized() &&
path_degrading_deadline_ > blackhole_deadline_)
<< "Path degrading timeout is later than blackhole detection timeout";
alarm_->Update(path_degrading_deadline_, kAlarmGranularity);
if (alarm_->IsSet()) {
return;
}
alarm_->Update(blackhole_deadline_, kAlarmGranularity);
}
bool QuicNetworkBlackholeDetector::IsDetectionInProgress() const {
return alarm_->IsSet();
}
} // namespace quic