1
#include "source/common/network/connection_impl_base.h"
2

            
3
namespace Envoy {
4
namespace Network {
5

            
6
13
void ConnectionImplBase::addIdToHashKey(std::vector<uint8_t>& hash_key, uint64_t connection_id) {
7
  // Pack the connection_id into sizeof(connection_id) uint8_t entries in the hash_key vector.
8
13
  hash_key.reserve(hash_key.size() + sizeof(connection_id));
9
117
  for (unsigned i = 0; i < sizeof(connection_id); ++i) {
10
104
    hash_key.push_back(0xFF & (connection_id >> (8 * i)));
11
104
  }
12
13
}
13

            
14
ConnectionImplBase::ConnectionImplBase(Event::Dispatcher& dispatcher, uint64_t id)
15
114516
    : dispatcher_(dispatcher), id_(id) {}
16

            
17
215431
void ConnectionImplBase::addConnectionCallbacks(ConnectionCallbacks& cb) {
18
215431
  callbacks_.push_back(&cb);
19
215431
}
20

            
21
95
void ConnectionImplBase::removeConnectionCallbacks(ConnectionCallbacks& callbacks) {
22
  // For performance/safety reasons we just clear the callback and do not resize the list
23
106
  for (auto& callback : callbacks_) {
24
106
    if (callback == &callbacks) {
25
95
      callback = nullptr;
26
95
      return;
27
95
    }
28
106
  }
29
95
}
30

            
31
OptRef<const StreamInfo::StreamInfo> ConnectionImplBase::trackedStream() const {
32
  return streamInfo();
33
}
34

            
35
11
void ConnectionImplBase::hashKey(std::vector<uint8_t>& hash) const { addIdToHashKey(hash, id()); }
36

            
37
55762
void ConnectionImplBase::setConnectionStats(const ConnectionStats& stats) {
38
55762
  connection_stats_ = std::make_unique<ConnectionStats>(stats);
39
55762
}
40

            
41
22242
void ConnectionImplBase::setDelayedCloseTimeout(std::chrono::milliseconds timeout) {
42
  // Validate that this is only called prior to issuing a close() or closeSocket().
43
22242
  ASSERT(delayed_close_timer_ == nullptr && state() == State::Open);
44
22242
  delayed_close_timeout_ = timeout;
45
22242
}
46

            
47
2378
void ConnectionImplBase::initializeDelayedCloseTimer() {
48
2378
  const auto timeout = delayed_close_timeout_.count();
49
2378
  ASSERT(delayed_close_timer_ == nullptr && timeout > 0);
50
2378
  delayed_close_timer_ = dispatcher_.createTimer([this]() -> void { onDelayedCloseTimeout(); });
51
2378
  ENVOY_CONN_LOG(debug, "setting delayed close timer with timeout {} ms", *this, timeout);
52
2378
  delayed_close_timer_->enableTimer(delayed_close_timeout_);
53
2378
}
54

            
55
197945
void ConnectionImplBase::raiseConnectionEvent(ConnectionEvent event) {
56
346874
  for (ConnectionCallbacks* callback : callbacks_) {
57
    // If a previous connected callback closed the connection, don't raise any further connected
58
    // events. There was already recursion raising closed events. We still raise closed events
59
    // to further callbacks because such events are typically used for cleanup.
60
346549
    if (event != ConnectionEvent::LocalClose && event != ConnectionEvent::RemoteClose &&
61
346549
        state() != State::Open) {
62
10
      return;
63
10
    }
64

            
65
346547
    if (callback != nullptr) {
66
346454
      callback->onEvent(event);
67
346454
    }
68
346539
  }
69
197945
}
70

            
71
1955
void ConnectionImplBase::onDelayedCloseTimeout() {
72
1955
  delayed_close_timer_.reset();
73
1955
  ENVOY_CONN_LOG(debug, "triggered delayed close", *this);
74
1955
  if (connection_stats_ != nullptr && connection_stats_->delayed_close_timeouts_ != nullptr) {
75
1947
    connection_stats_->delayed_close_timeouts_->inc();
76
1947
  }
77
1955
  closeConnectionImmediatelyWithDetails(
78
1955
      StreamInfo::LocalCloseReasons::get().TriggeredDelayedCloseTimeout);
79
1955
}
80

            
81
} // namespace Network
82
} // namespace Envoy