Line data Source code
1 : #include "source/common/network/connection_impl_base.h" 2 : 3 : namespace Envoy { 4 : namespace Network { 5 : 6 0 : 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 0 : hash_key.reserve(hash_key.size() + sizeof(connection_id)); 9 0 : for (unsigned i = 0; i < sizeof(connection_id); ++i) { 10 0 : hash_key.push_back(0xFF & (connection_id >> (8 * i))); 11 0 : } 12 0 : } 13 : 14 : ConnectionImplBase::ConnectionImplBase(Event::Dispatcher& dispatcher, uint64_t id) 15 2885 : : dispatcher_(dispatcher), id_(id) {} 16 : 17 3625 : void ConnectionImplBase::addConnectionCallbacks(ConnectionCallbacks& cb) { 18 3625 : callbacks_.push_back(&cb); 19 3625 : } 20 : 21 0 : void ConnectionImplBase::removeConnectionCallbacks(ConnectionCallbacks& callbacks) { 22 : // For performance/safety reasons we just clear the callback and do not resize the list 23 0 : for (auto& callback : callbacks_) { 24 0 : if (callback == &callbacks) { 25 0 : callback = nullptr; 26 0 : return; 27 0 : } 28 0 : } 29 0 : } 30 : 31 0 : void ConnectionImplBase::hashKey(std::vector<uint8_t>& hash) const { addIdToHashKey(hash, id()); } 32 : 33 1055 : void ConnectionImplBase::setConnectionStats(const ConnectionStats& stats) { 34 1055 : connection_stats_ = std::make_unique<ConnectionStats>(stats); 35 1055 : } 36 : 37 882 : void ConnectionImplBase::setDelayedCloseTimeout(std::chrono::milliseconds timeout) { 38 : // Validate that this is only called prior to issuing a close() or closeSocket(). 39 882 : ASSERT(delayed_close_timer_ == nullptr && state() == State::Open); 40 882 : delayed_close_timeout_ = timeout; 41 882 : } 42 : 43 346 : void ConnectionImplBase::initializeDelayedCloseTimer() { 44 346 : const auto timeout = delayed_close_timeout_.count(); 45 346 : ASSERT(delayed_close_timer_ == nullptr && timeout > 0); 46 346 : delayed_close_timer_ = dispatcher_.createTimer([this]() -> void { onDelayedCloseTimeout(); }); 47 346 : ENVOY_CONN_LOG(debug, "setting delayed close timer with timeout {} ms", *this, timeout); 48 346 : delayed_close_timer_->enableTimer(delayed_close_timeout_); 49 346 : } 50 : 51 4838 : void ConnectionImplBase::raiseConnectionEvent(ConnectionEvent event) { 52 6297 : for (ConnectionCallbacks* callback : callbacks_) { 53 : // If a previous connected callback closed the connection, don't raise any further connected 54 : // events. There was already recursion raising closed events. We still raise closed events 55 : // to further callbacks because such events are typically used for cleanup. 56 5782 : if (event != ConnectionEvent::LocalClose && event != ConnectionEvent::RemoteClose && 57 5782 : state() != State::Open) { 58 0 : return; 59 0 : } 60 : 61 5784 : if (callback != nullptr) { 62 5784 : callback->onEvent(event); 63 5784 : } 64 5782 : } 65 4838 : } 66 : 67 28 : void ConnectionImplBase::onDelayedCloseTimeout() { 68 28 : delayed_close_timer_.reset(); 69 28 : ENVOY_CONN_LOG(debug, "triggered delayed close", *this); 70 28 : if (connection_stats_ != nullptr && connection_stats_->delayed_close_timeouts_ != nullptr) { 71 28 : connection_stats_->delayed_close_timeouts_->inc(); 72 28 : } 73 28 : closeConnectionImmediatelyWithDetails( 74 28 : StreamInfo::LocalCloseReasons::get().TriggeredDelayedCloseTimeout); 75 28 : } 76 : 77 : } // namespace Network 78 : } // namespace Envoy