1
#include "source/common/http/http3_status_tracker_impl.h"
2

            
3
namespace Envoy {
4
namespace Http {
5

            
6
namespace {
7

            
8
// Initially, HTTP/3 is marked broken for 1 second.
9
const std::chrono::seconds DefaultExpirationTime{1};
10
// Cap the broken period around a day and a half.
11
const int MaxConsecutiveBrokenCount = 17;
12
} // namespace
13

            
14
Http3StatusTrackerImpl::Http3StatusTrackerImpl(Event::Dispatcher& dispatcher)
15
112
    : expiration_timer_(dispatcher.createTimer([this]() -> void { onExpirationTimeout(); })) {}
16

            
17
11
bool Http3StatusTrackerImpl::isHttp3Pending() const { return state_ == State::Pending; }
18

            
19
160
bool Http3StatusTrackerImpl::isHttp3Broken() const { return state_ == State::Broken; }
20

            
21
30
bool Http3StatusTrackerImpl::isHttp3Confirmed() const { return state_ == State::Confirmed; }
22

            
23
151
bool Http3StatusTrackerImpl::hasHttp3FailedRecently() const {
24
151
  return state_ == State::FailedRecently;
25
151
}
26

            
27
1
void Http3StatusTrackerImpl::markHttp3Pending() { state_ = State::Pending; }
28

            
29
61
void Http3StatusTrackerImpl::markHttp3Broken() {
30
61
  state_ = State::Broken;
31
61
  if (!expiration_timer_->enabled()) {
32
60
    std::chrono::seconds expiration_in_sec =
33
60
        DefaultExpirationTime * (1 << consecutive_broken_count_);
34
60
    expiration_timer_->enableTimer(
35
60
        std::chrono::duration_cast<std::chrono::milliseconds>(expiration_in_sec));
36
60
    if (consecutive_broken_count_ < MaxConsecutiveBrokenCount) {
37
58
      ++consecutive_broken_count_;
38
58
    }
39
60
  }
40
61
}
41

            
42
33
void Http3StatusTrackerImpl::markHttp3Confirmed() {
43
33
  state_ = State::Confirmed;
44
33
  consecutive_broken_count_ = 0;
45
33
  if (expiration_timer_->enabled()) {
46
    expiration_timer_->disableTimer();
47
  }
48
33
}
49

            
50
13
void Http3StatusTrackerImpl::markHttp3FailedRecently() { state_ = State::FailedRecently; }
51

            
52
26
void Http3StatusTrackerImpl::onExpirationTimeout() {
53
26
  if (state_ != State::Broken) {
54
    return;
55
  }
56
26
  state_ = State::FailedRecently;
57
26
}
58

            
59
} // namespace Http
60
} // namespace Envoy