This is an automated email from the ASF dual-hosted git repository. acanary pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push: new d4f202c PoolableSession (#6828) d4f202c is described below commit d4f202c808dd1b76255ce8991960ff83c07a9c46 Author: a-a-ron <acan...@verizonmedia.com> AuthorDate: Wed Jan 20 11:27:21 2021 -0600 PoolableSession (#6828) Http1ServerSessions now inherit from an abstract PoolableSession which adds following for outbound pooling: + linkage for intrusive dlist + KA status + OutboundConnTrack::Group Its is expected that H2 and H3 session will also need to inherit from this, or something similar. --- proxy/Makefile.am | 1 + proxy/PoolableSession.h | 192 ++++++++++++++++++++++ proxy/ProxySession.cc | 18 +- proxy/ProxySession.h | 15 +- proxy/ProxyTransaction.cc | 34 +++- proxy/ProxyTransaction.h | 57 ++++++- proxy/http/Http1ClientSession.cc | 37 ++--- proxy/http/Http1ClientSession.h | 19 ++- proxy/http/Http1ServerSession.cc | 110 +++++-------- proxy/http/Http1ServerSession.h | 159 ++---------------- proxy/http/Http1Transaction.cc | 52 ------ proxy/http/Http1Transaction.h | 11 -- proxy/http/HttpSM.cc | 146 ++++++++-------- proxy/http/HttpSM.h | 14 +- proxy/http/HttpSessionManager.cc | 75 +++++---- proxy/http/HttpSessionManager.h | 14 +- proxy/http/HttpTransactHeaders.cc | 1 + proxy/http2/Http2ClientSession.cc | 10 +- proxy/http2/Http2ClientSession.h | 6 +- proxy/http2/Http2ConnectionState.cc | 2 +- proxy/http2/Http2Stream.h | 2 +- proxy/http3/Http3Session.cc | 8 +- proxy/http3/Http3Session.h | 8 +- src/traffic_server/InkAPI.cc | 54 +++--- tests/gold_tests/continuations/session_id.test.py | 15 +- 25 files changed, 563 insertions(+), 497 deletions(-) diff --git a/proxy/Makefile.am b/proxy/Makefile.am index 33a2ad1..4eec154 100644 --- a/proxy/Makefile.am +++ b/proxy/Makefile.am @@ -70,6 +70,7 @@ libproxy_a_SOURCES = \ ProtocolProbeSessionAccept.h \ ProxySession.cc \ ProxySession.h \ + PoolableSession.h \ ProxyTransaction.cc \ ProxyTransaction.h \ ReverseProxy.cc \ diff --git a/proxy/PoolableSession.h b/proxy/PoolableSession.h new file mode 100644 index 0000000..76946ef --- /dev/null +++ b/proxy/PoolableSession.h @@ -0,0 +1,192 @@ +/** @file + + PoolableSession - class that extends ProxySession so that they can be cataloged for reuse. + + @section license License + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#pragma once + +#include "ProxySession.h" + +class PoolableSession : public ProxySession +{ + using self_type = PoolableSession; + using super_type = ProxySession; + +public: + enum PooledState { + INIT, + SSN_IN_USE, // actively in use + KA_RESERVED, // stuck to client + KA_POOLED, // free for reuse + }; + + /// Hash map descriptor class for IP map. + struct IPLinkage { + self_type *_next = nullptr; + self_type *_prev = nullptr; + + static self_type *&next_ptr(self_type *); + static self_type *&prev_ptr(self_type *); + static uint32_t hash_of(sockaddr const *key); + static sockaddr const *key_of(self_type const *ssn); + static bool equal(sockaddr const *lhs, sockaddr const *rhs); + // Add a couple overloads for internal convenience. + static bool equal(sockaddr const *lhs, PoolableSession const *rhs); + static bool equal(PoolableSession const *lhs, sockaddr const *rhs); + } _ip_link; + + /// Hash map descriptor class for FQDN map. + struct FQDNLinkage { + self_type *_next = nullptr; + self_type *_prev = nullptr; + + static self_type *&next_ptr(self_type *); + static self_type *&prev_ptr(self_type *); + static uint64_t hash_of(CryptoHash const &key); + static CryptoHash const &key_of(self_type *ssn); + static bool equal(CryptoHash const &lhs, CryptoHash const &rhs); + } _fqdn_link; + + CryptoHash hostname_hash; + PooledState state = INIT; + + // Copy of the owning SM's server session sharing settings + TSServerSessionSharingMatchMask sharing_match = TS_SERVER_SESSION_SHARING_MATCH_MASK_NONE; + TSServerSessionSharingPoolType sharing_pool = TS_SERVER_SESSION_SHARING_POOL_GLOBAL; + + // Keep track of connection limiting and a pointer to the + // singleton that keeps track of the connection counts. + OutboundConnTrack::Group *conn_track_group = nullptr; + + void set_active(); + bool is_active(); + void set_private(bool new_private = true); + bool is_private() const; + + void set_netvc(NetVConnection *newvc); + +private: + // Sessions become if authentication headers + // are sent over them + bool private_session = false; +}; + +inline void +PoolableSession::set_active() +{ + state = SSN_IN_USE; +} +inline bool +PoolableSession::is_active() +{ + return state == SSN_IN_USE; +} +inline void +PoolableSession::set_private(bool new_private) +{ + private_session = new_private; +} +inline bool +PoolableSession::is_private() const +{ + return private_session; +} + +inline void +PoolableSession::set_netvc(NetVConnection *newvc) +{ + ProxySession::_vc = newvc; +} + +// +// LINKAGE + +inline PoolableSession *& +PoolableSession::IPLinkage::next_ptr(self_type *ssn) +{ + return ssn->_ip_link._next; +} + +inline PoolableSession *& +PoolableSession::IPLinkage::prev_ptr(self_type *ssn) +{ + return ssn->_ip_link._prev; +} + +inline uint32_t +PoolableSession::IPLinkage::hash_of(sockaddr const *key) +{ + return ats_ip_hash(key); +} + +inline sockaddr const * +PoolableSession::IPLinkage::key_of(self_type const *ssn) +{ + return ssn->get_remote_addr(); +} + +inline bool +PoolableSession::IPLinkage::equal(sockaddr const *lhs, sockaddr const *rhs) +{ + return ats_ip_addr_port_eq(lhs, rhs); +} + +inline bool +PoolableSession::IPLinkage::equal(sockaddr const *lhs, PoolableSession const *rhs) +{ + return ats_ip_addr_port_eq(lhs, key_of(rhs)); +} + +inline bool +PoolableSession::IPLinkage::equal(PoolableSession const *lhs, sockaddr const *rhs) +{ + return ats_ip_addr_port_eq(key_of(lhs), rhs); +} + +inline PoolableSession *& +PoolableSession::FQDNLinkage::next_ptr(self_type *ssn) +{ + return ssn->_fqdn_link._next; +} + +inline PoolableSession *& +PoolableSession::FQDNLinkage::prev_ptr(self_type *ssn) +{ + return ssn->_fqdn_link._prev; +} + +inline uint64_t +PoolableSession::FQDNLinkage::hash_of(CryptoHash const &key) +{ + return key.fold(); +} + +inline CryptoHash const & +PoolableSession::FQDNLinkage::key_of(self_type *ssn) +{ + return ssn->hostname_hash; +} + +inline bool +PoolableSession::FQDNLinkage::equal(CryptoHash const &lhs, CryptoHash const &rhs) +{ + return lhs == rhs; +} diff --git a/proxy/ProxySession.cc b/proxy/ProxySession.cc index 07af66a..a866507 100644 --- a/proxy/ProxySession.cc +++ b/proxy/ProxySession.cc @@ -35,7 +35,7 @@ ProxySession::set_session_active() { if (!m_active) { m_active = true; - this->increment_current_active_client_connections_stat(); + this->increment_current_active_connections_stat(); } } @@ -44,7 +44,7 @@ ProxySession::clear_session_active() { if (m_active) { m_active = false; - this->decrement_current_active_client_connections_stat(); + this->decrement_current_active_connections_stat(); } } @@ -201,12 +201,12 @@ ProxySession::connection_id() const } bool -ProxySession::attach_server_session(Http1ServerSession *ssession, bool transaction_done) +ProxySession::attach_server_session(PoolableSession *ssession, bool transaction_done) { return false; } -Http1ServerSession * +PoolableSession * ProxySession::get_server_session() const { return nullptr; @@ -236,6 +236,14 @@ ProxySession::cancel_inactivity_timeout() } } +void +ProxySession::cancel_active_timeout() +{ + if (_vc) { + _vc->cancel_active_timeout(); + } +} + int ProxySession::populate_protocol(std::string_view *result, int size) const { @@ -249,7 +257,7 @@ ProxySession::protocol_contains(std::string_view tag_prefix) const } sockaddr const * -ProxySession::get_client_addr() +ProxySession::get_remote_addr() const { return _vc ? _vc->get_remote_addr() : nullptr; } diff --git a/proxy/ProxySession.h b/proxy/ProxySession.h index 8c6a071..d31888f 100644 --- a/proxy/ProxySession.h +++ b/proxy/ProxySession.h @@ -30,7 +30,6 @@ #include <memory> #include "P_Net.h" #include "InkAPIInternal.h" -#include "http/Http1ServerSession.h" #include "http/HttpSessionAccept.h" #include "IPAllow.h" #include "private/SSLProxySession.h" @@ -41,6 +40,7 @@ #define SsnDebug(ssn, tag, ...) SpecificDebug((ssn)->debug(), tag, __VA_ARGS__) class ProxyTransaction; +class PoolableSession; enum class ProxyErrorClass { NONE, @@ -89,18 +89,17 @@ public: // Virtual Methods virtual void new_connection(NetVConnection *new_vc, MIOBuffer *iobuf, IOBufferReader *reader) = 0; virtual void start() = 0; - virtual bool attach_server_session(Http1ServerSession *ssession, bool transaction_done = true); + virtual bool attach_server_session(PoolableSession *ssession, bool transaction_done = true); virtual void release(ProxyTransaction *trans) = 0; virtual void destroy() = 0; virtual void free(); - virtual void increment_current_active_client_connections_stat() = 0; - virtual void decrement_current_active_client_connections_stat() = 0; + virtual void increment_current_active_connections_stat() = 0; + virtual void decrement_current_active_connections_stat() = 0; // Virtual Accessors - NetVConnection *get_netvc() const; virtual int get_transact_count() const = 0; virtual const char *get_protocol_string() const = 0; @@ -111,20 +110,22 @@ public: virtual void set_half_close_flag(bool flag); virtual bool get_half_close_flag() const; - virtual Http1ServerSession *get_server_session() const; + virtual PoolableSession *get_server_session() const; // Replicate NetVConnection API - virtual sockaddr const *get_client_addr(); + virtual sockaddr const *get_remote_addr() const; virtual sockaddr const *get_local_addr(); virtual void set_active_timeout(ink_hrtime timeout_in); virtual void set_inactivity_timeout(ink_hrtime timeout_in); virtual void cancel_inactivity_timeout(); + virtual void cancel_active_timeout(); virtual int populate_protocol(std::string_view *result, int size) const; virtual const char *protocol_contains(std::string_view tag_prefix) const; // Non-Virtual Methods + NetVConnection *get_netvc() const; int do_api_callout(TSHttpHookID id); void set_debug(bool flag); diff --git a/proxy/ProxyTransaction.cc b/proxy/ProxyTransaction.cc index 2ef8ad1..3f80e77 100644 --- a/proxy/ProxyTransaction.cc +++ b/proxy/ProxyTransaction.cc @@ -22,7 +22,6 @@ */ #include "http/HttpSM.h" -#include "http/Http1ServerSession.h" #include "Plugin.h" #define HttpTxnDebug(fmt, ...) SsnDebug(this, "http_txn", fmt, __VA_ARGS__) @@ -57,7 +56,7 @@ ProxyTransaction::new_transaction(bool from_early_data) } bool -ProxyTransaction::attach_server_session(Http1ServerSession *ssession, bool transaction_done) +ProxyTransaction::attach_server_session(PoolableSession *ssession, bool transaction_done) { return _proxy_ssn->attach_server_session(ssession, transaction_done); } @@ -185,3 +184,34 @@ ProxyTransaction::transaction_done() SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread()); this->decrement_client_transactions_stat(); } + +// Implement VConnection interface. +VIO * +ProxyTransaction::do_io_read(Continuation *c, int64_t nbytes, MIOBuffer *buf) +{ + return _proxy_ssn->do_io_read(c, nbytes, buf); +} +VIO * +ProxyTransaction::do_io_write(Continuation *c, int64_t nbytes, IOBufferReader *buf, bool owner) +{ + return _proxy_ssn->do_io_write(c, nbytes, buf, owner); +} + +void +ProxyTransaction::do_io_close(int lerrno) +{ + _proxy_ssn->do_io_close(lerrno); + // this->destroy(); Parent owns this data structure. No need for separate destroy. +} + +void +ProxyTransaction::do_io_shutdown(ShutdownHowTo_t howto) +{ + _proxy_ssn->do_io_shutdown(howto); +} + +void +ProxyTransaction::reenable(VIO *vio) +{ + _proxy_ssn->reenable(vio); +} diff --git a/proxy/ProxyTransaction.h b/proxy/ProxyTransaction.h index 6ceb3c0..7c1e3de 100644 --- a/proxy/ProxyTransaction.h +++ b/proxy/ProxyTransaction.h @@ -27,7 +27,6 @@ #include <string_view> class HttpSM; -class Http1ServerSession; // Abstract Class for any transaction with-in the HttpSM class ProxyTransaction : public VConnection @@ -38,18 +37,28 @@ public: /// Virtual Methods // virtual void new_transaction(bool from_early_data = false); - virtual bool attach_server_session(Http1ServerSession *ssession, bool transaction_done = true); + virtual bool attach_server_session(PoolableSession *ssession, bool transaction_done = true); Action *adjust_thread(Continuation *cont, int event, void *data); virtual void release(IOBufferReader *r) = 0; virtual void transaction_done(); virtual void destroy(); + virtual void set_active_timeout(ink_hrtime timeout_in); + virtual void set_inactivity_timeout(ink_hrtime timeout_in); + virtual void cancel_inactivity_timeout(); + virtual void cancel_active_timeout(); + + // Implement VConnection interface. + VIO *do_io_read(Continuation *c, int64_t nbytes = INT64_MAX, MIOBuffer *buf = nullptr) override; + VIO *do_io_write(Continuation *c = nullptr, int64_t nbytes = INT64_MAX, IOBufferReader *buf = nullptr, + bool owner = false) override; + void do_io_close(int lerrno = -1) override; + void do_io_shutdown(ShutdownHowTo_t howto) override; + void reenable(VIO *vio) override; + /// Virtual Accessors // - virtual void set_active_timeout(ink_hrtime timeout_in) = 0; - virtual void set_inactivity_timeout(ink_hrtime timeout_in) = 0; - virtual void cancel_inactivity_timeout() = 0; - virtual int get_transaction_id() const = 0; + virtual int get_transaction_id() const = 0; virtual int get_transaction_priority_weight() const; virtual int get_transaction_priority_dependence() const; virtual bool allow_half_open() const = 0; @@ -97,7 +106,7 @@ public: const IpAllow::ACL &get_acl() const; ProxySession *get_proxy_ssn(); - Http1ServerSession *get_server_session() const; + PoolableSession *get_server_session() const; HttpSM *get_sm() const; // This function must return a non-negative number that is different for two in-progress transactions with the same proxy_ssn @@ -185,7 +194,7 @@ ProxyTransaction::set_proxy_ssn(ProxySession *new_proxy_ssn) _proxy_ssn = new_proxy_ssn; } -inline Http1ServerSession * +inline PoolableSession * ProxyTransaction::get_server_session() const { return _proxy_ssn ? _proxy_ssn->get_server_session() : nullptr; @@ -221,6 +230,38 @@ ProxyTransaction::support_sni() const return _proxy_ssn ? _proxy_ssn->support_sni() : false; } +inline void +ProxyTransaction::set_active_timeout(ink_hrtime timeout_in) +{ + if (_proxy_ssn) { + _proxy_ssn->set_active_timeout(timeout_in); + } +} + +inline void +ProxyTransaction::set_inactivity_timeout(ink_hrtime timeout_in) +{ + if (_proxy_ssn) { + _proxy_ssn->set_inactivity_timeout(timeout_in); + } +} + +inline void +ProxyTransaction::cancel_inactivity_timeout() +{ + if (_proxy_ssn) { + _proxy_ssn->cancel_inactivity_timeout(); + } +} + +inline void +ProxyTransaction::cancel_active_timeout() +{ + if (_proxy_ssn) { + _proxy_ssn->cancel_active_timeout(); + } +} + // See if we need to schedule on the primary thread for the transaction or change the thread that is associated with the VC. // If we reschedule, the scheduled action is returned. Otherwise, NULL is returned inline Action * diff --git a/proxy/http/Http1ClientSession.cc b/proxy/http/Http1ClientSession.cc index 4ffc6b1..14291cb 100644 --- a/proxy/http/Http1ClientSession.cc +++ b/proxy/http/Http1ClientSession.cc @@ -35,8 +35,8 @@ #include "Http1Transaction.h" #include "HttpSM.h" #include "HttpDebugNames.h" -#include "Http1ServerSession.h" #include "Plugin.h" +#include "PoolableSession.h" #define HttpSsnDebug(fmt, ...) SsnDebug(this, "http_cs", fmt, __VA_ARGS__) @@ -46,11 +46,6 @@ HttpSsnDebug("[%" PRId64 "] [%s, %s]", con_id, #state_name, HttpDebugNames::get_event_name(event)); \ } while (0) -enum { - HTTP_CS_MAGIC_ALIVE = 0x0123F00D, - HTTP_CS_MAGIC_DEAD = 0xDEADF00D, -}; - #ifdef USE_HTTP_DEBUG_LISTS // We have debugging list that we can use to find stuck @@ -227,7 +222,7 @@ Http1ClientSession::do_io_close(int alerrno) // If we have an attached server session, release // it back to our shared pool if (bound_ss) { - bound_ss->release(); + bound_ss->release(nullptr); bound_ss = nullptr; slave_ka_vio = nullptr; } @@ -339,7 +334,7 @@ Http1ClientSession::state_slave_keep_alive(int event, void *data) case VC_EVENT_ACTIVE_TIMEOUT: case VC_EVENT_INACTIVITY_TIMEOUT: // Timeout - place the session on the shared pool - bound_ss->release(); + bound_ss->release(nullptr); bound_ss = nullptr; slave_ka_vio = nullptr; break; @@ -461,14 +456,13 @@ Http1ClientSession::new_transaction() } bool -Http1ClientSession::attach_server_session(Http1ServerSession *ssession, bool transaction_done) +Http1ClientSession::attach_server_session(PoolableSession *ssession, bool transaction_done) { if (ssession) { ink_assert(bound_ss == nullptr); - ssession->state = HSS_KA_CLIENT_SLAVE; + ssession->state = PoolableSession::KA_RESERVED; bound_ss = ssession; - HttpSsnDebug("[%" PRId64 "] attaching server session [%" PRId64 "] as slave", con_id, ssession->con_id); - ink_assert(ssession->get_reader()->read_avail() == 0); + HttpSsnDebug("[%" PRId64 "] attaching server session [%" PRId64 "] as slave", con_id, ssession->connection_id()); ink_assert(ssession->get_netvc() != this->get_netvc()); // handling potential keep-alive here @@ -478,21 +472,19 @@ Http1ClientSession::attach_server_session(Http1ServerSession *ssession, bool tra // have it call the client session back. This IO also prevent // the server net conneciton from calling back a dead sm SET_HANDLER(&Http1ClientSession::state_keep_alive); - slave_ka_vio = ssession->do_io_read(this, INT64_MAX, ssession->read_buffer); - this->do_io_write(this, 0, nullptr); // Capture the inactivity timeouts + slave_ka_vio = ssession->do_io_read(this, 0, nullptr); ink_assert(slave_ka_vio != ka_vio); // Transfer control of the write side as well ssession->do_io_write(this, 0, nullptr); if (transaction_done) { - ssession->get_netvc()->set_inactivity_timeout( - HRTIME_SECONDS(trans.get_sm()->t_state.txn_conf->keep_alive_no_activity_timeout_out)); - ssession->get_netvc()->cancel_active_timeout(); + ssession->set_inactivity_timeout(HRTIME_SECONDS(trans.get_sm()->t_state.txn_conf->keep_alive_no_activity_timeout_out)); + ssession->cancel_active_timeout(); } else { // we are serving from the cache - this could take a while. - ssession->get_netvc()->cancel_inactivity_timeout(); - ssession->get_netvc()->cancel_active_timeout(); + ssession->cancel_inactivity_timeout(); + ssession->cancel_active_timeout(); } } else { ink_assert(bound_ss != nullptr); @@ -503,13 +495,12 @@ Http1ClientSession::attach_server_session(Http1ServerSession *ssession, bool tra } void -Http1ClientSession::increment_current_active_client_connections_stat() +Http1ClientSession::increment_current_active_connections_stat() { HTTP_INCREMENT_DYN_STAT(http_current_active_client_connections_stat); } - void -Http1ClientSession::decrement_current_active_client_connections_stat() +Http1ClientSession::decrement_current_active_connections_stat() { HTTP_DECREMENT_DYN_STAT(http_current_active_client_connections_stat); } @@ -558,7 +549,7 @@ Http1ClientSession::is_outbound_transparent() const return f_outbound_transparent; } -Http1ServerSession * +PoolableSession * Http1ClientSession::get_server_session() const { return bound_ss; diff --git a/proxy/http/Http1ClientSession.h b/proxy/http/Http1ClientSession.h index 686f5f4..0c6e2f5 100644 --- a/proxy/http/Http1ClientSession.h +++ b/proxy/http/Http1ClientSession.h @@ -43,9 +43,12 @@ extern ink_mutex debug_cs_list_mutex; #endif -class HttpSM; -class Http1ServerSession; +enum { + HTTP_CS_MAGIC_ALIVE = 0x0123FEED, + HTTP_CS_MAGIC_DEAD = 0xDEADFEED, +}; +class HttpSM; class Http1ClientSession : public ProxySession { public: @@ -60,7 +63,7 @@ public: void destroy() override; void free() override; - bool attach_server_session(Http1ServerSession *ssession, bool transaction_done = true) override; + bool attach_server_session(PoolableSession *ssession, bool transaction_done = true) override; // Implement VConnection interface. void do_io_close(int lerrno = -1) override; @@ -73,11 +76,11 @@ public: int get_transact_count() const override; virtual bool is_outbound_transparent() const; - Http1ServerSession *get_server_session() const override; + PoolableSession *get_server_session() const override; const char *get_protocol_string() const override; - void increment_current_active_client_connections_stat() override; - void decrement_current_active_client_connections_stat() override; + void increment_current_active_connections_stat() override; + void decrement_current_active_connections_stat() override; private: Http1ClientSession(Http1ClientSession &); @@ -96,7 +99,7 @@ private: HCS_CLOSED, }; - int magic = HTTP_SS_MAGIC_DEAD; + int magic = HTTP_CS_MAGIC_DEAD; int transact_count = 0; bool half_close = false; bool conn_decrease = false; @@ -109,7 +112,7 @@ private: VIO *ka_vio = nullptr; VIO *slave_ka_vio = nullptr; - Http1ServerSession *bound_ss = nullptr; + PoolableSession *bound_ss = nullptr; int released_transactions = 0; diff --git a/proxy/http/Http1ServerSession.cc b/proxy/http/Http1ServerSession.cc index e794668..b1b94fb 100644 --- a/proxy/http/Http1ServerSession.cc +++ b/proxy/http/Http1ServerSession.cc @@ -36,15 +36,13 @@ #include "HttpSessionManager.h" #include "HttpSM.h" -static int64_t next_ss_id = static_cast<int64_t>(0); ClassAllocator<Http1ServerSession> httpServerSessionAllocator("httpServerSessionAllocator"); void Http1ServerSession::destroy() { - ink_release_assert(server_vc == nullptr); + ink_release_assert(_vc == nullptr); ink_assert(read_buffer); - ink_assert(server_trans_stat == 0); magic = HTTP_SS_MAGIC_DEAD; if (read_buffer) { free_MIOBuffer(read_buffer); @@ -60,26 +58,30 @@ Http1ServerSession::destroy() } void -Http1ServerSession::new_connection(NetVConnection *new_vc) +Http1ServerSession::new_connection(NetVConnection *new_vc, MIOBuffer *iobuf, IOBufferReader *reader) { ink_assert(new_vc != nullptr); - server_vc = new_vc; + _vc = new_vc; // Used to do e.g. mutex = new_vc->thread->mutex; when per-thread pools enabled mutex = new_vc->mutex; - // Unique client session identifier. - con_id = ink_atomic_increment((&next_ss_id), 1); + // Unique session identifier. + con_id = ProxySession::next_connection_id(); magic = HTTP_SS_MAGIC_ALIVE; HTTP_SUM_GLOBAL_DYN_STAT(http_current_server_connections_stat, 1); // Update the true global stat HTTP_INCREMENT_DYN_STAT(http_total_server_connections_stat); - read_buffer = new_MIOBuffer(HTTP_SERVER_RESP_HDR_BUFFER_INDEX); - - buf_reader = read_buffer->alloc_reader(); + if (iobuf == nullptr) { + read_buffer = new_MIOBuffer(HTTP_SERVER_RESP_HDR_BUFFER_INDEX); + buf_reader = read_buffer->alloc_reader(); + } else { + read_buffer = iobuf; + buf_reader = reader; + } Debug("http_ss", "[%" PRId64 "] session born, netvc %p", con_id, new_vc); - state = HSS_INIT; + state = INIT; new_vc->set_tcp_congestion_control(SERVER_SIDE); } @@ -96,37 +98,18 @@ Http1ServerSession::enable_outbound_connection_tracking(OutboundConnTrack::Group } } -VIO * -Http1ServerSession::do_io_read(Continuation *c, int64_t nbytes, MIOBuffer *buf) -{ - return server_vc ? server_vc->do_io_read(c, nbytes, buf) : nullptr; -} - -VIO * -Http1ServerSession::do_io_write(Continuation *c, int64_t nbytes, IOBufferReader *buf, bool owner) -{ - return server_vc ? server_vc->do_io_write(c, nbytes, buf, owner) : nullptr; -} - -void -Http1ServerSession::do_io_shutdown(ShutdownHowTo_t howto) -{ - server_vc->do_io_shutdown(howto); -} - void Http1ServerSession::do_io_close(int alerrno) { ts::LocalBufferWriter<256> w; bool debug_p = is_debug_tag_set("http_ss"); - if (state == HSS_ACTIVE) { + if (state == SSN_IN_USE) { HTTP_DECREMENT_DYN_STAT(http_current_server_transactions_stat); - this->server_trans_stat--; } if (debug_p) { - w.print("[{}] session close: nevtc {:x}", con_id, server_vc); + w.print("[{}] session close: nevtc {:x}", con_id, _vc); } HTTP_SUM_GLOBAL_DYN_STAT(http_current_server_connections_stat, -1); // Make sure to work on the global stat @@ -149,10 +132,10 @@ Http1ServerSession::do_io_close(int alerrno) Debug("http_ss", "%.*s", static_cast<int>(w.size()), w.data()); } - if (server_vc) { - server_vc->do_io_close(alerrno); + if (_vc) { + _vc->do_io_close(alerrno); } - server_vc = nullptr; + _vc = nullptr; if (to_parent_proxy) { HTTP_DECREMENT_DYN_STAT(http_current_parent_proxy_connections_stat); @@ -160,27 +143,21 @@ Http1ServerSession::do_io_close(int alerrno) destroy(); } -void -Http1ServerSession::reenable(VIO *vio) -{ - server_vc->reenable(vio); -} - // void Http1ServerSession::release() // // Releases the session for K-A reuse // void -Http1ServerSession::release() +Http1ServerSession::release(ProxyTransaction *trans) { - Debug("http_ss", "Releasing session, private_session=%d, sharing_match=%d", private_session, sharing_match); + Debug("http_ss", "Releasing session, private_session=%d, sharing_match=%d", this->is_private(), sharing_match); // Set our state to KA for stat issues - state = HSS_KA_SHARED; + state = KA_POOLED; - server_vc->control_flags.set_flags(0); + _vc->control_flags.set_flags(0); // Private sessions are never released back to the shared pool - if (private_session || sharing_match == 0) { + if (this->is_private() || sharing_match == 0) { this->do_io_close(); return; } @@ -206,36 +183,37 @@ Http1ServerSession::release() } } -NetVConnection * -Http1ServerSession::get_netvc() const -{ - return server_vc; -}; - -void -Http1ServerSession::set_netvc(NetVConnection *new_vc) -{ - server_vc = new_vc; -} - // Keys for matching hostnames IpEndpoint const & Http1ServerSession::get_server_ip() const { - ink_release_assert(server_vc != nullptr); - return server_vc->get_remote_endpoint(); + ink_release_assert(_vc != nullptr); + return _vc->get_remote_endpoint(); } int -Http1ServerSession::populate_protocol(std::string_view *result, int size) const +Http1ServerSession::get_transact_count() const { - auto vc = this->get_netvc(); - return vc ? vc->populate_protocol(result, size) : 0; + return transact_count; } const char * -Http1ServerSession::protocol_contains(std::string_view tag_prefix) const +Http1ServerSession::get_protocol_string() const +{ + return "http"; +} +void +Http1ServerSession::increment_current_active_connections_stat() +{ + // TODO: Implement stats +} +void +Http1ServerSession::decrement_current_active_connections_stat() +{ + // TODO: Implement stats +} + +void +Http1ServerSession::start() { - auto vc = this->get_netvc(); - return vc ? vc->protocol_contains(tag_prefix) : nullptr; } diff --git a/proxy/http/Http1ServerSession.h b/proxy/http/Http1ServerSession.h index a46c6dd..9594006 100644 --- a/proxy/http/Http1ServerSession.h +++ b/proxy/http/Http1ServerSession.h @@ -36,64 +36,52 @@ #include "HttpConnectionCount.h" #include "HttpProxyAPIEnums.h" +#include "PoolableSession.h" class HttpSM; class MIOBuffer; class IOBufferReader; -enum HSS_State { - HSS_INIT, - HSS_ACTIVE, - HSS_KA_CLIENT_SLAVE, - HSS_KA_SHARED, -}; - enum { HTTP_SS_MAGIC_ALIVE = 0x0123FEED, HTTP_SS_MAGIC_DEAD = 0xDEADFEED, }; -class Http1ServerSession : public VConnection +class Http1ServerSession : public PoolableSession { using self_type = Http1ServerSession; - using super_type = VConnection; + using super_type = PoolableSession; public: - Http1ServerSession() : super_type(nullptr) {} + Http1ServerSession() : super_type() {} Http1ServerSession(self_type const &) = delete; self_type &operator=(self_type const &) = delete; //////////////////// // Methods - void new_connection(NetVConnection *new_vc); - void release(); - void destroy(); + void release(ProxyTransaction *) override; + void destroy() override; // VConnection Methods - VIO *do_io_read(Continuation *c, int64_t nbytes = INT64_MAX, MIOBuffer *buf = nullptr) override; - VIO *do_io_write(Continuation *c = nullptr, int64_t nbytes = INT64_MAX, IOBufferReader *buf = nullptr, - bool owner = false) override; void do_io_close(int lerrno = -1) override; - void do_io_shutdown(ShutdownHowTo_t howto) override; - void reenable(VIO *vio) override; + // ProxySession Methods + int get_transact_count() const override; + const char *get_protocol_string() const override; + void increment_current_active_connections_stat() override; + void decrement_current_active_connections_stat() override; + void new_connection(NetVConnection *new_vc, MIOBuffer *iobuf, IOBufferReader *reader) override; + void start() override; void enable_outbound_connection_tracking(OutboundConnTrack::Group *group); IOBufferReader *get_reader(); void attach_hostname(const char *hostname); - NetVConnection *get_netvc() const; - void set_netvc(NetVConnection *new_vc); IpEndpoint const &get_server_ip() const; - int populate_protocol(std::string_view *result, int size) const; - const char *protocol_contains(std::string_view tag_prefix) const; //////////////////// // Variables - CryptoHash hostname_hash; - int64_t con_id = 0; int transact_count = 0; - HSS_State state = HSS_INIT; // Used to determine whether the session is for parent proxy // it is session to origin server @@ -102,49 +90,6 @@ public: // proxy.process.http.current_parent_proxy_connections bool to_parent_proxy = false; - // Used to verify we are recording the server - // transaction stat properly - int server_trans_stat = 0; - - // Sessions become if authentication headers - // are sent over them - bool private_session = false; - - // Copy of the owning SM's server session sharing settings - TSServerSessionSharingMatchMask sharing_match = TS_SERVER_SESSION_SHARING_MATCH_MASK_NONE; - TSServerSessionSharingPoolType sharing_pool = TS_SERVER_SESSION_SHARING_POOL_GLOBAL; - - /// Hash map descriptor class for IP map. - struct IPLinkage { - self_type *_next = nullptr; - self_type *_prev = nullptr; - - static self_type *&next_ptr(self_type *); - static self_type *&prev_ptr(self_type *); - static uint32_t hash_of(sockaddr const *key); - static sockaddr const *key_of(self_type const *ssn); - static bool equal(sockaddr const *lhs, sockaddr const *rhs); - // Add a couple overloads for internal convenience. - static bool equal(sockaddr const *lhs, Http1ServerSession const *rhs); - static bool equal(Http1ServerSession const *lhs, sockaddr const *rhs); - } _ip_link; - - /// Hash map descriptor class for FQDN map. - struct FQDNLinkage { - self_type *_next = nullptr; - self_type *_prev = nullptr; - - static self_type *&next_ptr(self_type *); - static self_type *&prev_ptr(self_type *); - static uint64_t hash_of(CryptoHash const &key); - static CryptoHash const &key_of(self_type *ssn); - static bool equal(CryptoHash const &lhs, CryptoHash const &rhs); - } _fqdn_link; - - // Keep track of connection limiting and a pointer to the - // singleton that keeps track of the connection counts. - OutboundConnTrack::Group *conn_track_group = nullptr; - // The ServerSession owns the following buffer which use // for parsing the headers. The server session needs to // own the buffer so we can go from a keep-alive state @@ -155,8 +100,7 @@ public: MIOBuffer *read_buffer = nullptr; private: - NetVConnection *server_vc = nullptr; - int magic = HTTP_SS_MAGIC_DEAD; + int magic = HTTP_SS_MAGIC_DEAD; IOBufferReader *buf_reader = nullptr; }; @@ -179,78 +123,3 @@ Http1ServerSession::get_reader() { return buf_reader; }; - -// -// LINKAGE - -inline Http1ServerSession *& -Http1ServerSession::IPLinkage::next_ptr(self_type *ssn) -{ - return ssn->_ip_link._next; -} - -inline Http1ServerSession *& -Http1ServerSession::IPLinkage::prev_ptr(self_type *ssn) -{ - return ssn->_ip_link._prev; -} - -inline uint32_t -Http1ServerSession::IPLinkage::hash_of(sockaddr const *key) -{ - return ats_ip_hash(key); -} - -inline sockaddr const * -Http1ServerSession::IPLinkage::key_of(self_type const *ssn) -{ - return &ssn->get_server_ip().sa; -} - -inline bool -Http1ServerSession::IPLinkage::equal(sockaddr const *lhs, sockaddr const *rhs) -{ - return ats_ip_addr_port_eq(lhs, rhs); -} - -inline bool -Http1ServerSession::IPLinkage::equal(sockaddr const *lhs, Http1ServerSession const *rhs) -{ - return ats_ip_addr_port_eq(lhs, key_of(rhs)); -} - -inline bool -Http1ServerSession::IPLinkage::equal(Http1ServerSession const *lhs, sockaddr const *rhs) -{ - return ats_ip_addr_port_eq(key_of(lhs), rhs); -} - -inline Http1ServerSession *& -Http1ServerSession::FQDNLinkage::next_ptr(self_type *ssn) -{ - return ssn->_fqdn_link._next; -} - -inline Http1ServerSession *& -Http1ServerSession::FQDNLinkage::prev_ptr(self_type *ssn) -{ - return ssn->_fqdn_link._prev; -} - -inline uint64_t -Http1ServerSession::FQDNLinkage::hash_of(CryptoHash const &key) -{ - return key.fold(); -} - -inline CryptoHash const & -Http1ServerSession::FQDNLinkage::key_of(self_type *ssn) -{ - return ssn->hostname_hash; -} - -inline bool -Http1ServerSession::FQDNLinkage::equal(CryptoHash const &lhs, CryptoHash const &rhs) -{ - return lhs == rhs; -} diff --git a/proxy/http/Http1Transaction.cc b/proxy/http/Http1Transaction.cc index 29ebec0..6a37e7c 100644 --- a/proxy/http/Http1Transaction.cc +++ b/proxy/http/Http1Transaction.cc @@ -46,12 +46,6 @@ Http1Transaction::transaction_done() } } -void -Http1Transaction::reenable(VIO *vio) -{ - _proxy_ssn->reenable(vio); -} - bool Http1Transaction::allow_half_open() const { @@ -75,52 +69,6 @@ Http1Transaction::decrement_client_transactions_stat() HTTP_DECREMENT_DYN_STAT(http_current_client_transactions_stat); } -// Implement VConnection interface. -VIO * -Http1Transaction::do_io_read(Continuation *c, int64_t nbytes, MIOBuffer *buf) -{ - return _proxy_ssn->do_io_read(c, nbytes, buf); -} -VIO * -Http1Transaction::do_io_write(Continuation *c, int64_t nbytes, IOBufferReader *buf, bool owner) -{ - return _proxy_ssn->do_io_write(c, nbytes, buf, owner); -} - -void -Http1Transaction::do_io_close(int lerrno) -{ - _proxy_ssn->do_io_close(lerrno); - // this->destroy(); Parent owns this data structure. No need for separate destroy. -} - -void -Http1Transaction::do_io_shutdown(ShutdownHowTo_t howto) -{ - _proxy_ssn->do_io_shutdown(howto); -} - -void -Http1Transaction::set_active_timeout(ink_hrtime timeout_in) -{ - if (_proxy_ssn) { - _proxy_ssn->set_active_timeout(timeout_in); - } -} -void -Http1Transaction::set_inactivity_timeout(ink_hrtime timeout_in) -{ - if (_proxy_ssn) { - _proxy_ssn->set_inactivity_timeout(timeout_in); - } -} -void -Http1Transaction::cancel_inactivity_timeout() -{ - if (_proxy_ssn) { - _proxy_ssn->cancel_inactivity_timeout(); - } -} // int Http1Transaction::get_transaction_id() const diff --git a/proxy/http/Http1Transaction.h b/proxy/http/Http1Transaction.h index 407d73e..d9c423d 100644 --- a/proxy/http/Http1Transaction.h +++ b/proxy/http/Http1Transaction.h @@ -39,18 +39,7 @@ public: void release(IOBufferReader *r) override; void destroy() override; // todo make ~Http1Transaction() - // Implement VConnection interface. - VIO *do_io_read(Continuation *c, int64_t nbytes = INT64_MAX, MIOBuffer *buf = nullptr) override; - VIO *do_io_write(Continuation *c = nullptr, int64_t nbytes = INT64_MAX, IOBufferReader *buf = nullptr, - bool owner = false) override; - void do_io_close(int lerrno = -1) override; - void do_io_shutdown(ShutdownHowTo_t howto) override; - void reenable(VIO *vio) override; - bool allow_half_open() const override; - void set_active_timeout(ink_hrtime timeout_in) override; - void set_inactivity_timeout(ink_hrtime timeout_in) override; - void cancel_inactivity_timeout() override; void transaction_done() override; int get_transaction_id() const override; void increment_client_transactions_stat() override; diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc index dcde8fd..650107e 100644 --- a/proxy/http/HttpSM.cc +++ b/proxy/http/HttpSM.cc @@ -274,48 +274,48 @@ HttpVCTable::cleanup_all() * Helper functions to ensure that the parallel * API set timeouts are set consistenly with the records.config settings */ -void -HttpSM::set_server_netvc_inactivity_timeout(NetVConnection *netvc) +ink_hrtime +HttpSM::get_server_inactivity_timeout() { - if (netvc) { - if (t_state.api_txn_no_activity_timeout_value != -1) { - netvc->set_inactivity_timeout(HRTIME_MSECONDS(t_state.api_txn_no_activity_timeout_value)); - } else { - netvc->set_inactivity_timeout(HRTIME_SECONDS(t_state.txn_conf->transaction_no_activity_timeout_out)); - } + ink_hrtime retval = 0; + if (t_state.api_txn_no_activity_timeout_value != -1) { + retval = HRTIME_MSECONDS(t_state.api_txn_no_activity_timeout_value); + } else { + retval = HRTIME_SECONDS(t_state.txn_conf->transaction_no_activity_timeout_out); } + return retval; } -void -HttpSM::set_server_netvc_active_timeout(NetVConnection *netvc) +ink_hrtime +HttpSM::get_server_active_timeout() { - if (netvc) { - if (t_state.api_txn_active_timeout_value != -1) { - netvc->set_active_timeout(HRTIME_MSECONDS(t_state.api_txn_active_timeout_value)); - } else { - netvc->set_active_timeout(HRTIME_SECONDS(t_state.txn_conf->transaction_active_timeout_out)); - } + ink_hrtime retval = 0; + if (t_state.api_txn_active_timeout_value != -1) { + retval = HRTIME_MSECONDS(t_state.api_txn_active_timeout_value); + } else { + retval = HRTIME_SECONDS(t_state.txn_conf->transaction_active_timeout_out); } + return retval; } -void -HttpSM::set_server_netvc_connect_timeout(NetVConnection *netvc) +ink_hrtime +HttpSM::get_server_connect_timeout() { - if (netvc) { - if (t_state.api_txn_connect_timeout_value != -1) { - netvc->set_inactivity_timeout(HRTIME_MSECONDS(t_state.api_txn_connect_timeout_value)); + ink_hrtime retval = 0; + if (t_state.api_txn_connect_timeout_value != -1) { + retval = HRTIME_MSECONDS(t_state.api_txn_connect_timeout_value); + } else { + int connect_timeout; + if (t_state.method == HTTP_WKSIDX_POST || t_state.method == HTTP_WKSIDX_PUT) { + connect_timeout = t_state.txn_conf->post_connect_attempts_timeout; + } else if (t_state.current.server == &t_state.parent_info) { + connect_timeout = t_state.txn_conf->parent_connect_timeout; } else { - int connect_timeout; - if (t_state.method == HTTP_WKSIDX_POST || t_state.method == HTTP_WKSIDX_PUT) { - connect_timeout = t_state.txn_conf->post_connect_attempts_timeout; - } else if (t_state.current.server == &t_state.parent_info) { - connect_timeout = t_state.txn_conf->parent_connect_timeout; - } else { - connect_timeout = t_state.txn_conf->connect_attempts_timeout; - } - netvc->set_inactivity_timeout(HRTIME_SECONDS(connect_timeout)); + connect_timeout = t_state.txn_conf->connect_attempts_timeout; } + retval = HRTIME_SECONDS(connect_timeout); } + return retval; } HttpSM::HttpSM() : Continuation(nullptr), vc_table(this) {} @@ -1185,8 +1185,8 @@ HttpSM::state_raw_http_server_open(int event, void *data) t_state.current.state = HttpTransact::CONNECTION_ALIVE; ats_ip_copy(&t_state.server_info.src_addr, netvc->get_local_addr()); - set_server_netvc_inactivity_timeout(netvc); - set_server_netvc_active_timeout(netvc); + netvc->set_inactivity_timeout(get_server_inactivity_timeout()); + netvc->set_active_timeout(get_server_active_timeout()); break; case VC_EVENT_ERROR: @@ -1708,8 +1708,8 @@ HttpSM::handle_api_return() SMDebug("http_websocket", "(server session) Setting websocket active timeout=%" PRId64 "s and inactive timeout=%" PRId64 "s", t_state.txn_conf->websocket_active_timeout, t_state.txn_conf->websocket_inactive_timeout); - server_session->get_netvc()->set_active_timeout(HRTIME_SECONDS(t_state.txn_conf->websocket_active_timeout)); - server_session->get_netvc()->set_inactivity_timeout(HRTIME_SECONDS(t_state.txn_conf->websocket_inactive_timeout)); + server_session->set_active_timeout(HRTIME_SECONDS(t_state.txn_conf->websocket_active_timeout)); + server_session->set_inactivity_timeout(HRTIME_SECONDS(t_state.txn_conf->websocket_inactive_timeout)); } } @@ -1796,11 +1796,11 @@ HttpSM::state_http_server_open(int event, void *data) ink_release_assert(pending_action == nullptr || pending_action->continuation == vc->get_action()->continuation); pending_action = nullptr; - session->new_connection(vc); + session->new_connection(vc, nullptr, nullptr); ATS_PROBE1(new_origin_server_connection, t_state.current.server->name); - session->state = HSS_ACTIVE; + session->set_active(); ats_ip_copy(&t_state.server_info.src_addr, netvc->get_local_addr()); // If origin_max_connections or origin_min_keep_alive_connections is set then we are metering @@ -1839,7 +1839,7 @@ HttpSM::state_http_server_open(int event, void *data) server_entry->vc_handler = &HttpSM::state_send_server_request_header; // Reset the timeout to the non-connect timeout - set_server_netvc_inactivity_timeout(server_session->get_netvc()); + server_session->set_inactivity_timeout(get_server_inactivity_timeout()); handle_http_server_open(); return 0; case EVENT_INTERVAL: // Delayed call from another thread @@ -1935,7 +1935,7 @@ HttpSM::state_read_server_response_header(int event, void *data) if (server_response_hdr_bytes == 0) { milestones[TS_MILESTONE_SERVER_FIRST_READ] = Thread::get_hrtime(); - set_server_netvc_inactivity_timeout(server_session->get_netvc()); + server_session->set_inactivity_timeout(get_server_inactivity_timeout()); // For requests that contain a body, we can cancel the ua inactivity timeout. if (ua_txn && t_state.hdr_info.request_content_length) { @@ -1953,7 +1953,7 @@ HttpSM::state_read_server_response_header(int event, void *data) // Don't allow HTTP 0.9 (unparsable headers) on resued connections. // And don't allow empty headers from closed connections if ((state == PARSE_RESULT_DONE && t_state.hdr_info.server_response.version_get() == HTTPVersion(0, 9) && - server_session->transact_count > 1) || + server_session->get_transact_count() > 1) || (server_entry->eos && vio->ndone == 0)) { state = PARSE_RESULT_ERROR; } @@ -3144,7 +3144,6 @@ HttpSM::tunnel_handler_server(int event, HttpTunnelProducer *p) } } else { server_session->attach_hostname(t_state.current.server->name); - server_session->server_trans_stat--; HTTP_DECREMENT_DYN_STAT(http_current_server_transactions_stat); // If the option to attach the server session to the client session is set @@ -3161,8 +3160,8 @@ HttpSM::tunnel_handler_server(int event, HttpTunnelProducer *p) } if (release_origin_connection) { // Release the session back into the shared session pool - server_session->get_netvc()->set_inactivity_timeout(HRTIME_SECONDS(t_state.txn_conf->keep_alive_no_activity_timeout_out)); - server_session->release(); + server_session->set_inactivity_timeout(HRTIME_SECONDS(t_state.txn_conf->keep_alive_no_activity_timeout_out)); + server_session->release(nullptr); } } @@ -3291,7 +3290,7 @@ HttpSM::tunnel_handler_ua(int event, HttpTunnelConsumer *c) HTTP_INCREMENT_DYN_STAT(http_background_fill_current_count_stat); ink_assert(server_entry->vc == server_session); ink_assert(c->is_downstream_from(server_session)); - server_session->get_netvc()->set_active_timeout(HRTIME_SECONDS(t_state.txn_conf->background_fill_active_timeout)); + server_session->set_active_timeout(HRTIME_SECONDS(t_state.txn_conf->background_fill_active_timeout)); } // Even with the background fill, the client side should go down @@ -4988,7 +4987,7 @@ HttpSM::do_http_server_open(bool raw) // If there is already an attached server session mark it as private. if (server_session != nullptr && will_be_private_ss) { - set_server_session_private(true); + server_session->set_private(); } if ((raw == false) && TS_SERVER_SESSION_SHARING_MATCH_NONE != t_state.txn_conf->server_session_sharing_match && @@ -5022,16 +5021,16 @@ HttpSM::do_http_server_open(bool raw) // session when we already have an attached server session. else if ((TS_SERVER_SESSION_SHARING_MATCH_NONE == t_state.txn_conf->server_session_sharing_match || is_private()) && (ua_txn != nullptr)) { - Http1ServerSession *existing_ss = ua_txn->get_server_session(); + PoolableSession *existing_ss = ua_txn->get_server_session(); if (existing_ss) { // [amc] Not sure if this is the best option, but we don't get here unless session sharing is disabled // so there's no point in further checking on the match or pool values. But why check anything? The // client has already exchanged a request with this specific origin server and has sent another one // shouldn't we just automatically keep the association? - if (ats_ip_addr_port_eq(&existing_ss->get_server_ip().sa, &t_state.current.server->dst_addr.sa)) { + if (ats_ip_addr_port_eq(existing_ss->get_remote_addr(), &t_state.current.server->dst_addr.sa)) { ua_txn->attach_server_session(nullptr); - existing_ss->state = HSS_ACTIVE; + existing_ss->set_active(); this->attach_server_session(existing_ss); hsm_release_assert(server_session != nullptr); handle_http_server_open(); @@ -5040,7 +5039,7 @@ HttpSM::do_http_server_open(bool raw) // As this is in the non-sharing configuration, we want to close // the existing connection and call connect_re to get a new one existing_ss->get_netvc()->set_inactivity_timeout(HRTIME_SECONDS(t_state.txn_conf->keep_alive_no_activity_timeout_out)); - existing_ss->release(); + existing_ss->release(nullptr); ua_txn->attach_server_session(nullptr); } } @@ -5049,10 +5048,10 @@ HttpSM::do_http_server_open(bool raw) // to get a new one. // ua_txn is null when t_state.req_flavor == REQ_FLAVOR_SCHEDULED_UPDATE else if (ua_txn != nullptr) { - Http1ServerSession *existing_ss = ua_txn->get_server_session(); + PoolableSession *existing_ss = ua_txn->get_server_session(); if (existing_ss) { existing_ss->get_netvc()->set_inactivity_timeout(HRTIME_SECONDS(t_state.txn_conf->keep_alive_no_activity_timeout_out)); - existing_ss->release(); + existing_ss->release(nullptr); ua_txn->attach_server_session(nullptr); } } @@ -5462,12 +5461,11 @@ HttpSM::release_server_session(bool serve_from_cache) t_state.www_auth_content != HttpTransact::CACHE_AUTH_NONE)) && plugin_tunnel_type == HTTP_NO_PLUGIN_TUNNEL) { HTTP_DECREMENT_DYN_STAT(http_current_server_transactions_stat); - server_session->server_trans_stat--; server_session->attach_hostname(t_state.current.server->name); if (t_state.www_auth_content == HttpTransact::CACHE_AUTH_NONE || serve_from_cache == false) { // Must explicitly set the keep_alive_no_activity time before doing the release - server_session->get_netvc()->set_inactivity_timeout(HRTIME_SECONDS(t_state.txn_conf->keep_alive_no_activity_timeout_out)); - server_session->release(); + server_session->set_inactivity_timeout(HRTIME_SECONDS(t_state.txn_conf->keep_alive_no_activity_timeout_out)); + server_session->release(nullptr); } else { // an authenticated server connection - attach to the local client // we are serving from cache for the current transaction @@ -5887,7 +5885,7 @@ HttpSM::do_setup_post_tunnel(HttpVC_t to_vc_type) } ua_txn->set_inactivity_timeout(HRTIME_SECONDS(t_state.txn_conf->transaction_no_activity_timeout_in)); - set_server_netvc_inactivity_timeout(server_session->get_netvc()); + server_session->set_inactivity_timeout(get_server_inactivity_timeout()); tunnel.tunnel_run(p); @@ -6050,12 +6048,13 @@ HttpSM::write_header_into_buffer(HTTPHdr *h, MIOBuffer *b) } void -HttpSM::attach_server_session(Http1ServerSession *s) +HttpSM::attach_server_session(PoolableSession *s) { hsm_release_assert(server_session == nullptr); hsm_release_assert(server_entry == nullptr); - hsm_release_assert(s->state == HSS_ACTIVE); - server_session = s; + hsm_release_assert(s != nullptr); + hsm_release_assert(s->is_active()); + server_session = static_cast<Http1ServerSession *>(s); server_transact_count = server_session->transact_count++; // update the dst_addr when using an existing session @@ -6064,8 +6063,8 @@ HttpSM::attach_server_session(Http1ServerSession *s) ip_port_text_buffer ipb1, ipb2; Debug("http_ss", "updating ip when attaching server session from %s to %s", ats_ip_ntop(&t_state.current.server->dst_addr.sa, ipb1, sizeof(ipb1)), - ats_ip_ntop(&server_session->get_server_ip(), ipb2, sizeof(ipb2))); - ats_ip_copy(&t_state.current.server->dst_addr, &server_session->get_server_ip()); + ats_ip_ntop(server_session->get_remote_addr(), ipb2, sizeof(ipb2))); + ats_ip_copy(&t_state.current.server->dst_addr, server_session->get_remote_addr()); } // Propagate the per client IP debugging @@ -6080,7 +6079,6 @@ HttpSM::attach_server_session(Http1ServerSession *s) server_session->mutex = this->mutex; HTTP_INCREMENT_DYN_STAT(http_current_server_transactions_stat); - ++s->server_trans_stat; // Record the VC in our table server_entry = vc_table.new_entry(); @@ -6128,12 +6126,12 @@ HttpSM::attach_server_session(Http1ServerSession *s) // Set the inactivity timeout to the connect timeout so that we // we fail this server if it doesn't start sending the response // header - set_server_netvc_connect_timeout(server_session->get_netvc()); - set_server_netvc_active_timeout(server_session->get_netvc()); + server_session->set_inactivity_timeout(get_server_connect_timeout()); + server_session->set_active_timeout(get_server_active_timeout()); if (plugin_tunnel_type != HTTP_NO_PLUGIN_TUNNEL || will_be_private_ss) { SMDebug("http_ss", "Setting server session to private"); - set_server_session_private(true); + server_session->set_private(); } } @@ -6141,7 +6139,7 @@ void HttpSM::setup_server_send_request_api() { // Make sure the VC is on the correct timeout - set_server_netvc_inactivity_timeout(server_session->get_netvc()); + server_session->set_inactivity_timeout(get_server_inactivity_timeout()); t_state.api_next_action = HttpTransact::SM_ACTION_API_SEND_REQUEST_HDR; do_api_callout(); } @@ -6183,11 +6181,7 @@ HttpSM::setup_server_send_request() server_entry->write_vio = server_entry->vc->do_io_write(this, hdr_length, buf_start); // Make sure the VC is using correct timeouts. We may be reusing a previously used server session - if (t_state.api_txn_no_activity_timeout_value != -1) { - server_session->get_netvc()->set_inactivity_timeout(HRTIME_MSECONDS(t_state.api_txn_no_activity_timeout_value)); - } else { - server_session->get_netvc()->set_inactivity_timeout(HRTIME_SECONDS(t_state.txn_conf->transaction_no_activity_timeout_out)); - } + server_session->set_inactivity_timeout(get_server_inactivity_timeout()); } void @@ -8087,7 +8081,7 @@ bool HttpSM::set_server_session_private(bool private_session) { if (server_session != nullptr) { - server_session->private_session = private_session; + server_session->set_private(private_session); return true; } return false; @@ -8098,11 +8092,11 @@ HttpSM::is_private() { bool res = false; if (server_session) { - res = server_session->private_session; + res = server_session->is_private(); } else if (ua_txn) { - Http1ServerSession *ss = ua_txn->get_server_session(); + Http1ServerSession *ss = dynamic_cast<Http1ServerSession *>(ua_txn->get_server_session()); if (ss) { - res = ss->private_session; + res = ss->is_private(); } else if (will_be_private_ss) { res = will_be_private_ss; } @@ -8297,3 +8291,9 @@ PostDataBuffers::~PostDataBuffers() { this->clear(); } + +PoolableSession * +HttpSM::get_server_session() const +{ + return server_session; +} diff --git a/proxy/http/HttpSM.h b/proxy/http/HttpSM.h index c343d76..c2d325c 100644 --- a/proxy/http/HttpSM.h +++ b/proxy/http/HttpSM.h @@ -221,15 +221,11 @@ public: // Called by httpSessionManager so that we can reset // the session timeouts and initiate a read while // holding the lock for the server session - void attach_server_session(Http1ServerSession *s); + void attach_server_session(PoolableSession *s); // Used to read attributes of // the current active server session - Http1ServerSession * - get_server_session() - { - return server_session; - } + PoolableSession *get_server_session() const; ProxyTransaction * get_ua_txn() @@ -634,9 +630,9 @@ public: return _client_transaction_priority_dependence; } - void set_server_netvc_inactivity_timeout(NetVConnection *netvc); - void set_server_netvc_active_timeout(NetVConnection *netvc); - void set_server_netvc_connect_timeout(NetVConnection *netvc); + ink_hrtime get_server_inactivity_timeout(); + ink_hrtime get_server_active_timeout(); + ink_hrtime get_server_connect_timeout(); void rewind_state_machine(); private: diff --git a/proxy/http/HttpSessionManager.cc b/proxy/http/HttpSessionManager.cc index f0564cd..c4aa296 100644 --- a/proxy/http/HttpSessionManager.cc +++ b/proxy/http/HttpSessionManager.cc @@ -32,7 +32,6 @@ #include "HttpSessionManager.h" #include "../ProxySession.h" -#include "Http1ServerSession.h" #include "HttpSM.h" #include "HttpDebugNames.h" @@ -57,21 +56,21 @@ ServerSessionPool::purge() { // @c do_io_close can free the instance which clears the intrusive links and breaks the iterator. // Therefore @c do_io_close is called on a post-incremented iterator. - m_ip_pool.apply([](Http1ServerSession *ssn) -> void { ssn->do_io_close(); }); + m_ip_pool.apply([](PoolableSession *ssn) -> void { ssn->do_io_close(); }); m_ip_pool.clear(); m_fqdn_pool.clear(); } bool -ServerSessionPool::match(Http1ServerSession *ss, sockaddr const *addr, CryptoHash const &hostname_hash, +ServerSessionPool::match(PoolableSession *ss, sockaddr const *addr, CryptoHash const &hostname_hash, TSServerSessionSharingMatchMask match_style) { bool retval = match_style != 0; if (retval && (TS_SERVER_SESSION_SHARING_MATCH_MASK_IP & match_style)) { - retval = ats_ip_addr_port_eq(ss->get_server_ip(), addr); + retval = ats_ip_addr_port_eq(ss->get_remote_addr(), addr); } if (retval && (TS_SERVER_SESSION_SHARING_MATCH_MASK_HOSTONLY & match_style)) { - retval = (ats_ip_port_cast(addr) == ats_ip_port_cast(ss->get_server_ip()) && ss->hostname_hash == hostname_hash); + retval = (ats_ip_port_cast(addr) == ats_ip_port_cast(ss->get_remote_addr()) && ss->hostname_hash == hostname_hash); } return retval; } @@ -142,7 +141,7 @@ ServerSessionPool::validate_cert(HttpSM *sm, NetVConnection *netvc) HSMresult_t ServerSessionPool::acquireSession(sockaddr const *addr, CryptoHash const &hostname_hash, - TSServerSessionSharingMatchMask match_style, HttpSM *sm, Http1ServerSession *&to_return) + TSServerSessionSharingMatchMask match_style, HttpSM *sm, PoolableSession *&to_return) { HSMresult_t zret = HSM_NOT_FOUND; to_return = nullptr; @@ -151,12 +150,16 @@ ServerSessionPool::acquireSession(sockaddr const *addr, CryptoHash const &hostna // This is broken out because only in this case do we check the host hash first. The range must be checked // to verify an upstream that matches port and SNI name is selected. Walk backwards to select oldest. in_port_t port = ats_ip_port_cast(addr); - auto first = m_fqdn_pool.find(hostname_hash); - while (first != m_fqdn_pool.end() && first->hostname_hash == hostname_hash) { - if (port == ats_ip_port_cast(first->get_server_ip()) && - (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_SNI) || validate_sni(sm, first->get_netvc())) && - (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_HOSTSNISYNC) || validate_host_sni(sm, first->get_netvc())) && - (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_CERT) || validate_cert(sm, first->get_netvc()))) { + FQDNTable::iterator first, last; + // FreeBSD/clang++ bug workaround: explicit cast to super type to make overload work. Not needed on Fedora27 nor gcc. + // Not fixed on FreeBSD as of llvm 6.0.1. + std::tie(first, last) = static_cast<const decltype(m_fqdn_pool)::range::super_type &>(m_fqdn_pool.equal_range(hostname_hash)); + while (last != first) { + --last; + if (port == ats_ip_port_cast(last->get_remote_addr()) && + (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_SNI) || validate_sni(sm, last->get_netvc())) && + (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_HOSTSNISYNC) || validate_host_sni(sm, last->get_netvc())) && + (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_CERT) || validate_cert(sm, last->get_netvc()))) { zret = HSM_DONE; break; } @@ -173,7 +176,7 @@ ServerSessionPool::acquireSession(sockaddr const *addr, CryptoHash const &hostna // And matches the other constraints as well // Note the port is matched as part of the address key so it doesn't need to be checked again. if (match_style & (~TS_SERVER_SESSION_SHARING_MATCH_MASK_IP)) { - while (first != m_ip_pool.end() && ats_ip_addr_port_eq(first->get_server_ip(), addr)) { + while (first != m_ip_pool.end() && ats_ip_addr_port_eq(first->get_remote_addr(), addr)) { if ((!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_HOSTONLY) || first->hostname_hash == hostname_hash) && (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_SNI) || validate_sni(sm, first->get_netvc())) && (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_HOSTSNISYNC) || validate_host_sni(sm, first->get_netvc())) && @@ -196,21 +199,21 @@ ServerSessionPool::acquireSession(sockaddr const *addr, CryptoHash const &hostna } void -ServerSessionPool::releaseSession(Http1ServerSession *ss) +ServerSessionPool::releaseSession(PoolableSession *ss) { - ss->state = HSS_KA_SHARED; + ss->state = PoolableSession::KA_POOLED; // Now we need to issue a read on the connection to detect // if it closes on us. We will get called back in the // continuation for this bucket, ensuring we have the lock // to remove the connection from our lists - ss->do_io_read(this, INT64_MAX, ss->read_buffer); + ss->do_io_read(this, 0, nullptr); // Transfer control of the write side as well ss->do_io_write(this, 0, nullptr); // we probably don't need the active timeout set, but will leave it for now - ss->get_netvc()->set_inactivity_timeout(ss->get_netvc()->get_inactivity_timeout()); - ss->get_netvc()->set_active_timeout(ss->get_netvc()->get_active_timeout()); + ss->set_inactivity_timeout(ss->get_netvc()->get_inactivity_timeout()); + ss->set_active_timeout(ss->get_netvc()->get_active_timeout()); // put it in the pools. m_ip_pool.insert(ss); m_fqdn_pool.insert(ss); @@ -218,7 +221,7 @@ ServerSessionPool::releaseSession(Http1ServerSession *ss) Debug("http_ss", "[%" PRId64 "] [release session] " "session placed into shared pool", - ss->con_id); + ss->connection_id()); } // Called from the NetProcessor to let us know that a @@ -228,7 +231,7 @@ int ServerSessionPool::eventHandler(int event, void *data) { NetVConnection *net_vc = nullptr; - Http1ServerSession *s = nullptr; + PoolableSession *s = nullptr; switch (event) { case VC_EVENT_READ_READY: @@ -257,7 +260,7 @@ ServerSessionPool::eventHandler(int event, void *data) // keeping the connection alive will not keep us above the # of max connections // to the origin and we are below the min number of keep alive connections to this // origin, then reset the timeouts on our end and do not close the connection - if ((event == VC_EVENT_INACTIVITY_TIMEOUT || event == VC_EVENT_ACTIVE_TIMEOUT) && s->state == HSS_KA_SHARED && + if ((event == VC_EVENT_INACTIVITY_TIMEOUT || event == VC_EVENT_ACTIVE_TIMEOUT) && s->state == PoolableSession::KA_POOLED && s->conn_track_group) { Debug("http_ss", "s->conn_track_group->min_keep_alive_conns : %d", s->conn_track_group->min_keep_alive_conns); bool connection_count_below_min = s->conn_track_group->_count <= s->conn_track_group->min_keep_alive_conns; @@ -266,7 +269,7 @@ ServerSessionPool::eventHandler(int event, void *data) Debug("http_ss", "[%" PRId64 "] [session_bucket] session received io notice [%s], " "resetting timeout to maintain minimum number of connections", - s->con_id, HttpDebugNames::get_event_name(event)); + s->connection_id(), HttpDebugNames::get_event_name(event)); s->get_netvc()->set_inactivity_timeout(s->get_netvc()->get_inactivity_timeout()); s->get_netvc()->set_active_timeout(s->get_netvc()->get_active_timeout()); found = true; @@ -276,9 +279,9 @@ ServerSessionPool::eventHandler(int event, void *data) // We've found our server session. Remove it from // our lists and close it down - Debug("http_ss", "[%" PRId64 "] [session_pool] session %p received io notice [%s]", s->con_id, s, + Debug("http_ss", "[%" PRId64 "] [session_pool] session %p received io notice [%s]", s->connection_id(), s, HttpDebugNames::get_event_name(event)); - ink_assert(s->state == HSS_KA_SHARED); + ink_assert(s->state == PoolableSession::KA_POOLED); // Out of the pool! Now! m_ip_pool.erase(spot); m_fqdn_pool.erase(s); @@ -330,8 +333,7 @@ HSMresult_t HttpSessionManager::acquire_session(Continuation * /* cont ATS_UNUSED */, sockaddr const *ip, const char *hostname, ProxyTransaction *ua_txn, HttpSM *sm) { - // First test for any session bound to the ua_txn - Http1ServerSession *to_return = nullptr; + PoolableSession *to_return = nullptr; TSServerSessionSharingMatchMask match_style = static_cast<TSServerSessionSharingMatchMask>(sm->t_state.txn_conf->server_session_sharing_match); CryptoHash hostname_hash; @@ -356,8 +358,8 @@ HttpSessionManager::acquire_session(Continuation * /* cont ATS_UNUSED */, sockad ServerSessionPool::validate_host_sni(sm, to_return->get_netvc())) && (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_CERT) || ServerSessionPool::validate_cert(sm, to_return->get_netvc()))) { - Debug("http_ss", "[%" PRId64 "] [acquire session] returning attached session ", to_return->con_id); - to_return->state = HSS_ACTIVE; + Debug("http_ss", "[%" PRId64 "] [acquire session] returning attached session ", to_return->connection_id()); + to_return->state = PoolableSession::SSN_IN_USE; sm->attach_server_session(to_return); return HSM_DONE; } @@ -366,8 +368,8 @@ HttpSessionManager::acquire_session(Continuation * /* cont ATS_UNUSED */, sockad Debug("http_ss", "[%" PRId64 "] [acquire session] " "session not a match, returning to shared pool", - to_return->con_id); - to_return->release(); + to_return->connection_id()); + to_return->release(nullptr); to_return = nullptr; } @@ -389,8 +391,8 @@ HSMresult_t HttpSessionManager::_acquire_session(sockaddr const *ip, CryptoHash const &hostname_hash, HttpSM *sm, TSServerSessionSharingMatchMask match_style, TSServerSessionSharingPoolType pool_type) { - Http1ServerSession *to_return = nullptr; - HSMresult_t retval = HSM_NOT_FOUND; + PoolableSession *to_return = nullptr; + HSMresult_t retval = HSM_NOT_FOUND; // Extend the mutex window until the acquired Server session is attached // to the SM. Releasing the mutex before that results in race conditions @@ -444,8 +446,8 @@ HttpSessionManager::_acquire_session(sockaddr const *ip, CryptoHash const &hostn } if (to_return) { - Debug("http_ss", "[%" PRId64 "] [acquire session] return session from shared pool", to_return->con_id); - to_return->state = HSS_ACTIVE; + Debug("http_ss", "[%" PRId64 "] [acquire session] return session from shared pool", to_return->connection_id()); + to_return->state = PoolableSession::SSN_IN_USE; // the attach_server_session will issue the do_io_read under the sm lock sm->attach_server_session(to_return); retval = HSM_DONE; @@ -455,7 +457,7 @@ HttpSessionManager::_acquire_session(sockaddr const *ip, CryptoHash const &hostn } HSMresult_t -HttpSessionManager::release_session(Http1ServerSession *to_release) +HttpSessionManager::release_session(PoolableSession *to_release) { EThread *ethread = this_ethread(); ServerSessionPool *pool = @@ -471,7 +473,8 @@ HttpSessionManager::release_session(Http1ServerSession *to_release) to_release->sharing_pool = TS_SERVER_SESSION_SHARING_POOL_THREAD; return release_session(to_release); } else { - Debug("http_ss", "[%" PRId64 "] [release session] could not release session due to lock contention", to_release->con_id); + Debug("http_ss", "[%" PRId64 "] [release session] could not release session due to lock contention", + to_release->connection_id()); released_p = false; } diff --git a/proxy/http/HttpSessionManager.h b/proxy/http/HttpSessionManager.h index 66a98bd..45344582 100644 --- a/proxy/http/HttpSessionManager.h +++ b/proxy/http/HttpSessionManager.h @@ -33,7 +33,7 @@ #pragma once #include "P_EventSystem.h" -#include "Http1ServerSession.h" +#include "PoolableSession.h" #include "tscore/IntrusiveHashMap.h" class ProxyTransaction; @@ -74,13 +74,13 @@ public: } protected: - using IPTable = IntrusiveHashMap<Http1ServerSession::IPLinkage>; - using FQDNTable = IntrusiveHashMap<Http1ServerSession::FQDNLinkage>; + using IPTable = IntrusiveHashMap<PoolableSession::IPLinkage>; + using FQDNTable = IntrusiveHashMap<PoolableSession::FQDNLinkage>; public: /** Check if a session matches address and host name. */ - static bool match(Http1ServerSession *ss, sockaddr const *addr, CryptoHash const &host_hash, + static bool match(PoolableSession *ss, sockaddr const *addr, CryptoHash const &host_hash, TSServerSessionSharingMatchMask match_style); /** Get a session from the pool. @@ -91,10 +91,10 @@ public: @return A pointer to the session or @c NULL if not matching session was found. */ HSMresult_t acquireSession(sockaddr const *addr, CryptoHash const &host_hash, TSServerSessionSharingMatchMask match_style, - HttpSM *sm, Http1ServerSession *&server_session); + HttpSM *sm, PoolableSession *&server_session); /** Release a session to to pool. */ - void releaseSession(Http1ServerSession *ss); + void releaseSession(PoolableSession *ss); /// Close all sessions and then clear the table. void purge(); @@ -111,7 +111,7 @@ public: HttpSessionManager() {} ~HttpSessionManager() {} HSMresult_t acquire_session(Continuation *cont, sockaddr const *addr, const char *hostname, ProxyTransaction *ua_txn, HttpSM *sm); - HSMresult_t release_session(Http1ServerSession *to_release); + HSMresult_t release_session(PoolableSession *to_release); void purge_keepalives(); void init(); int main_handler(int event, void *data); diff --git a/proxy/http/HttpTransactHeaders.cc b/proxy/http/HttpTransactHeaders.cc index 1a54fe2..4ce0037 100644 --- a/proxy/http/HttpTransactHeaders.cc +++ b/proxy/http/HttpTransactHeaders.cc @@ -35,6 +35,7 @@ #include "HdrUtils.h" #include "HttpCompat.h" #include "HttpSM.h" +#include "PoolableSession.h" #include "I_Machine.h" diff --git a/proxy/http2/Http2ClientSession.cc b/proxy/http2/Http2ClientSession.cc index 4ec6d3d..d28d0b8 100644 --- a/proxy/http2/Http2ClientSession.cc +++ b/proxy/http2/Http2ClientSession.cc @@ -362,7 +362,7 @@ Http2ClientSession::main_event_handler(int event, void *edata) } else if (this->connection_state.get_stream_error_rate() > Http2::stream_error_rate_threshold) { // For a case many stream errors happened ip_port_text_buffer ipb; - const char *client_ip = ats_ip_ntop(get_client_addr(), ipb, sizeof(ipb)); + const char *client_ip = ats_ip_ntop(get_remote_addr(), ipb, sizeof(ipb)); Warning("HTTP/2 session error client_ip=%s session_id=%" PRId64 " closing a connection, because its stream error rate (%f) exceeded the threshold (%f)", client_ip, connection_id(), this->connection_state.get_stream_error_rate(), Http2::stream_error_rate_threshold); @@ -559,7 +559,7 @@ Http2ClientSession::state_process_frame_read(int event, VIO *vio, bool inside_fr Http2ErrorCode err = Http2ErrorCode::HTTP2_ERROR_NO_ERROR; if (this->connection_state.get_stream_error_rate() > std::min(1.0, Http2::stream_error_rate_threshold * 2.0)) { ip_port_text_buffer ipb; - const char *client_ip = ats_ip_ntop(get_client_addr(), ipb, sizeof(ipb)); + const char *client_ip = ats_ip_ntop(get_remote_addr(), ipb, sizeof(ipb)); Warning("HTTP/2 session error client_ip=%s session_id=%" PRId64 " closing a connection, because its stream error rate (%f) exceeded the threshold (%f)", client_ip, connection_id(), this->connection_state.get_stream_error_rate(), Http2::stream_error_rate_threshold); @@ -603,13 +603,13 @@ Http2ClientSession::state_process_frame_read(int event, VIO *vio, bool inside_fr } void -Http2ClientSession::increment_current_active_client_connections_stat() +Http2ClientSession::increment_current_active_connections_stat() { HTTP2_INCREMENT_THREAD_DYN_STAT(HTTP2_STAT_CURRENT_ACTIVE_CLIENT_CONNECTION_COUNT, this_ethread()); } void -Http2ClientSession::decrement_current_active_client_connections_stat() +Http2ClientSession::decrement_current_active_connections_stat() { HTTP2_DECREMENT_THREAD_DYN_STAT(HTTP2_STAT_CURRENT_ACTIVE_CLIENT_CONNECTION_COUNT, this_ethread()); } @@ -628,7 +628,7 @@ Http2ClientSession::_should_do_something_else() } sockaddr const * -Http2ClientSession::get_client_addr() +Http2ClientSession::get_remote_addr() const { return _vc ? _vc->get_remote_addr() : &cached_client_addr.sa; } diff --git a/proxy/http2/Http2ClientSession.h b/proxy/http2/Http2ClientSession.h index 26ce15f..5e2b00d 100644 --- a/proxy/http2/Http2ClientSession.h +++ b/proxy/http2/Http2ClientSession.h @@ -88,14 +88,14 @@ public: //////////////////// // Accessors - sockaddr const *get_client_addr() override; + sockaddr const *get_remote_addr() const override; sockaddr const *get_local_addr() override; int get_transact_count() const override; const char *get_protocol_string() const override; int populate_protocol(std::string_view *result, int size) const override; const char *protocol_contains(std::string_view prefix) const override; - void increment_current_active_client_connections_stat() override; - void decrement_current_active_client_connections_stat() override; + void increment_current_active_connections_stat() override; + void decrement_current_active_connections_stat() override; void set_upgrade_context(HTTPHdr *h); void set_dying_event(int event); diff --git a/proxy/http2/Http2ConnectionState.cc b/proxy/http2/Http2ConnectionState.cc index b2597e8..d1256cd 100644 --- a/proxy/http2/Http2ConnectionState.cc +++ b/proxy/http2/Http2ConnectionState.cc @@ -1068,7 +1068,7 @@ Http2ConnectionState::main_event_handler(int event, void *edata) if (error.cls != Http2ErrorClass::HTTP2_ERROR_CLASS_NONE) { ip_port_text_buffer ipb; - const char *client_ip = ats_ip_ntop(ua_session->get_client_addr(), ipb, sizeof(ipb)); + const char *client_ip = ats_ip_ntop(ua_session->get_remote_addr(), ipb, sizeof(ipb)); if (error.cls == Http2ErrorClass::HTTP2_ERROR_CLASS_CONNECTION) { if (error.msg) { Error("HTTP/2 connection error code=0x%02x client_ip=%s session_id=%" PRId64 " stream_id=%u %s", diff --git a/proxy/http2/Http2Stream.h b/proxy/http2/Http2Stream.h index 3e3467b..cb48229 100644 --- a/proxy/http2/Http2Stream.h +++ b/proxy/http2/Http2Stream.h @@ -96,7 +96,7 @@ public: // Accessors void set_active_timeout(ink_hrtime timeout_in) override; void set_inactivity_timeout(ink_hrtime timeout_in) override; - void cancel_active_timeout(); + void cancel_active_timeout() override; void cancel_inactivity_timeout() override; bool is_active_timeout_expired(ink_hrtime now); bool is_inactive_timeout_expired(ink_hrtime now); diff --git a/proxy/http3/Http3Session.cc b/proxy/http3/Http3Session.cc index aaea1dfd..8e1168b 100644 --- a/proxy/http3/Http3Session.cc +++ b/proxy/http3/Http3Session.cc @@ -170,13 +170,13 @@ Http3Session::~Http3Session() } void -Http3Session::increment_current_active_client_connections_stat() +Http3Session::increment_current_active_connections_stat() { // TODO Implement stats } void -Http3Session::decrement_current_active_client_connections_stat() +Http3Session::decrement_current_active_connections_stat() { // TODO Implement stats } @@ -202,13 +202,13 @@ Http09Session::~Http09Session() } void -Http09Session::increment_current_active_client_connections_stat() +Http09Session::increment_current_active_connections_stat() { // TODO Implement stats } void -Http09Session::decrement_current_active_client_connections_stat() +Http09Session::decrement_current_active_connections_stat() { // TODO Implement stats } diff --git a/proxy/http3/Http3Session.h b/proxy/http3/Http3Session.h index a6aec41..0d912ce 100644 --- a/proxy/http3/Http3Session.h +++ b/proxy/http3/Http3Session.h @@ -71,8 +71,8 @@ public: ~Http3Session(); // ProxySession interface - void increment_current_active_client_connections_stat() override; - void decrement_current_active_client_connections_stat() override; + void increment_current_active_connections_stat() override; + void decrement_current_active_connections_stat() override; QPACK *local_qpack(); QPACK *remote_qpack(); @@ -94,8 +94,8 @@ public: ~Http09Session(); // ProxySession interface - void increment_current_active_client_connections_stat() override; - void decrement_current_active_client_connections_stat() override; + void increment_current_active_connections_stat() override; + void decrement_current_active_connections_stat() override; private: }; diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc index eee68ed..18ebfca 100644 --- a/src/traffic_server/InkAPI.cc +++ b/src/traffic_server/InkAPI.cc @@ -4920,8 +4920,8 @@ TSHttpSsnClientVConnGet(TSHttpSsn ssnp) TSVConn TSHttpSsnServerVConnGet(TSHttpSsn ssnp) { - TSVConn vconn = nullptr; - Http1ServerSession *ss = reinterpret_cast<Http1ServerSession *>(ssnp); + TSVConn vconn = nullptr; + PoolableSession *ss = reinterpret_cast<PoolableSession *>(ssnp); if (ss != nullptr) { vconn = reinterpret_cast<TSVConn>(ss->get_netvc()); } @@ -4935,7 +4935,7 @@ TSHttpTxnServerVConnGet(TSHttpTxn txnp) sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS); HttpSM *sm = reinterpret_cast<HttpSM *>(txnp); if (sm != nullptr) { - Http1ServerSession *ss = sm->get_server_session(); + PoolableSession *ss = sm->get_server_session(); if (ss != nullptr) { vconn = reinterpret_cast<TSVConn>(ss->get_netvc()); } @@ -5745,7 +5745,7 @@ TSHttpSsnClientAddrGet(TSHttpSsn ssnp) if (cs == nullptr) { return nullptr; } - return cs->get_client_addr(); + return cs->get_remote_addr(); } sockaddr const * TSHttpTxnClientAddrGet(TSHttpTxn txnp) @@ -5782,7 +5782,7 @@ TSHttpTxnOutgoingAddrGet(TSHttpTxn txnp) HttpSM *sm = reinterpret_cast<HttpSM *>(txnp); - Http1ServerSession *ssn = sm->get_server_session(); + PoolableSession *ssn = sm->get_server_session(); if (ssn == nullptr) { return nullptr; } @@ -5916,12 +5916,14 @@ TSHttpTxnServerPacketMarkSet(TSHttpTxn txnp, int mark) HttpSM *sm = (HttpSM *)txnp; // change the mark on an active server session - Http1ServerSession *ssn = sm->get_server_session(); - if (nullptr != ssn) { - NetVConnection *vc = ssn->get_netvc(); - if (vc != nullptr) { - vc->options.packet_mark = (uint32_t)mark; - vc->apply_options(); + if (nullptr != sm->ua_txn) { + PoolableSession *ssn = sm->ua_txn->get_server_session(); + if (nullptr != ssn) { + NetVConnection *vc = ssn->get_netvc(); + if (vc != nullptr) { + vc->options.packet_mark = (uint32_t)mark; + vc->apply_options(); + } } } @@ -5956,12 +5958,14 @@ TSHttpTxnServerPacketTosSet(TSHttpTxn txnp, int tos) HttpSM *sm = (HttpSM *)txnp; // change the tos on an active server session - Http1ServerSession *ssn = sm->get_server_session(); - if (nullptr != ssn) { - NetVConnection *vc = ssn->get_netvc(); - if (vc != nullptr) { - vc->options.packet_tos = (uint32_t)tos; - vc->apply_options(); + if (nullptr != sm->ua_txn) { + PoolableSession *ssn = sm->ua_txn->get_server_session(); + if (nullptr != ssn) { + NetVConnection *vc = ssn->get_netvc(); + if (vc != nullptr) { + vc->options.packet_tos = (uint32_t)tos; + vc->apply_options(); + } } } @@ -5996,12 +6000,14 @@ TSHttpTxnServerPacketDscpSet(TSHttpTxn txnp, int dscp) HttpSM *sm = (HttpSM *)txnp; // change the tos on an active server session - Http1ServerSession *ssn = sm->get_server_session(); - if (nullptr != ssn) { - NetVConnection *vc = ssn->get_netvc(); - if (vc != nullptr) { - vc->options.packet_tos = (uint32_t)dscp << 2; - vc->apply_options(); + if (nullptr != sm->ua_txn) { + PoolableSession *ssn = sm->ua_txn->get_server_session(); + if (nullptr != ssn) { + NetVConnection *vc = ssn->get_netvc(); + if (vc != nullptr) { + vc->options.packet_tos = (uint32_t)dscp << 2; + vc->apply_options(); + } } } @@ -7782,7 +7788,7 @@ TSHttpTxnServerFdGet(TSHttpTxn txnp, int *fdp) HttpSM *sm = reinterpret_cast<HttpSM *>(txnp); *fdp = -1; - Http1ServerSession *ss = sm->get_server_session(); + PoolableSession *ss = sm->get_server_session(); if (ss == nullptr) { return TS_ERROR; } diff --git a/tests/gold_tests/continuations/session_id.test.py b/tests/gold_tests/continuations/session_id.test.py index a4e0293..3580a1c 100644 --- a/tests/gold_tests/continuations/session_id.test.py +++ b/tests/gold_tests/continuations/session_id.test.py @@ -96,6 +96,15 @@ tr.Processes.Default.ReturnCode = Any(0, 2) # AuTest already searches for errors in diags.log and fails if it encounters # them. The test plugin prints an error to this log if it sees duplicate ids. # The following is to verify that we encountered the expected ids. -ts.Streams.stderr += Testers.ContainsExpression( - "session id: 199", - "Verify the various session ids were found.") + + +def verify_session_count(output): + global numberOfRequests + nReq = numberOfRequests * 2 + session_ids = [line[0:line.find("\n")] for line in str(output).split("session id: ")[1:]] + if len(session_ids) != nReq: + return "Found {} session_id's, expected {}".format(len(session_ids), nReq) + return "" + + +ts.Streams.All += Testers.FileContentCallback(verify_session_count, 'verify_session_count')