1 /** @file
2 
3   PoolableSession - class that extends ProxySession so that they can be cataloged for reuse.
4 
5   @section license License
6 
7   Licensed to the Apache Software Foundation (ASF) under one
8   or more contributor license agreements.  See the NOTICE file
9   distributed with this work for additional information
10   regarding copyright ownership.  The ASF licenses this file
11   to you under the Apache License, Version 2.0 (the
12   "License"); you may not use this file except in compliance
13   with the License.  You may obtain a copy of the License at
14 
15       http://www.apache.org/licenses/LICENSE-2.0
16 
17   Unless required by applicable law or agreed to in writing, software
18   distributed under the License is distributed on an "AS IS" BASIS,
19   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20   See the License for the specific language governing permissions and
21   limitations under the License.
22  */
23 
24 #pragma once
25 
26 #include "ProxySession.h"
27 
28 class PoolableSession : public ProxySession
29 {
30   using self_type  = PoolableSession;
31   using super_type = ProxySession;
32 
33 public:
34   enum PooledState {
35     INIT,
36     SSN_IN_USE,  // actively in use
37     KA_RESERVED, // stuck to client
38     KA_POOLED,   // free for reuse
39   };
40 
41   /// Hash map descriptor class for IP map.
42   struct IPLinkage {
43     self_type *_next = nullptr;
44     self_type *_prev = nullptr;
45 
46     static self_type *&next_ptr(self_type *);
47     static self_type *&prev_ptr(self_type *);
48     static uint32_t hash_of(sockaddr const *key);
49     static sockaddr const *key_of(self_type const *ssn);
50     static bool equal(sockaddr const *lhs, sockaddr const *rhs);
51     // Add a couple overloads for internal convenience.
52     static bool equal(sockaddr const *lhs, PoolableSession const *rhs);
53     static bool equal(PoolableSession const *lhs, sockaddr const *rhs);
54   } _ip_link;
55 
56   /// Hash map descriptor class for FQDN map.
57   struct FQDNLinkage {
58     self_type *_next = nullptr;
59     self_type *_prev = nullptr;
60 
61     static self_type *&next_ptr(self_type *);
62     static self_type *&prev_ptr(self_type *);
63     static uint64_t hash_of(CryptoHash const &key);
64     static CryptoHash const &key_of(self_type *ssn);
65     static bool equal(CryptoHash const &lhs, CryptoHash const &rhs);
66   } _fqdn_link;
67 
68   CryptoHash hostname_hash;
69   PooledState state = INIT;
70 
71   // Copy of the owning SM's server session sharing settings
72   TSServerSessionSharingMatchMask sharing_match = TS_SERVER_SESSION_SHARING_MATCH_MASK_NONE;
73   TSServerSessionSharingPoolType sharing_pool   = TS_SERVER_SESSION_SHARING_POOL_GLOBAL;
74 
75   // Keep track of connection limiting and a pointer to the
76   // singleton that keeps track of the connection counts.
77   OutboundConnTrack::Group *conn_track_group = nullptr;
78 
79   void set_active();
80   bool is_active();
81   void set_private(bool new_private = true);
82   bool is_private() const;
83 
84   void set_netvc(NetVConnection *newvc);
85 
86   virtual IOBufferReader *get_reader() = 0;
87 
88 private:
89   // Sessions become if authentication headers
90   //  are sent over them
91   bool private_session = false;
92 };
93 
94 inline void
set_active()95 PoolableSession::set_active()
96 {
97   state = SSN_IN_USE;
98 }
99 inline bool
is_active()100 PoolableSession::is_active()
101 {
102   return state == SSN_IN_USE;
103 }
104 inline void
set_private(bool new_private)105 PoolableSession::set_private(bool new_private)
106 {
107   private_session = new_private;
108 }
109 inline bool
is_private()110 PoolableSession::is_private() const
111 {
112   return private_session;
113 }
114 
115 inline void
set_netvc(NetVConnection * newvc)116 PoolableSession::set_netvc(NetVConnection *newvc)
117 {
118   ProxySession::_vc = newvc;
119 }
120 
121 //
122 // LINKAGE
123 
124 inline PoolableSession *&
next_ptr(self_type * ssn)125 PoolableSession::IPLinkage::next_ptr(self_type *ssn)
126 {
127   return ssn->_ip_link._next;
128 }
129 
130 inline PoolableSession *&
prev_ptr(self_type * ssn)131 PoolableSession::IPLinkage::prev_ptr(self_type *ssn)
132 {
133   return ssn->_ip_link._prev;
134 }
135 
136 inline uint32_t
hash_of(sockaddr const * key)137 PoolableSession::IPLinkage::hash_of(sockaddr const *key)
138 {
139   return ats_ip_hash(key);
140 }
141 
142 inline sockaddr const *
key_of(self_type const * ssn)143 PoolableSession::IPLinkage::key_of(self_type const *ssn)
144 {
145   return ssn->get_remote_addr();
146 }
147 
148 inline bool
equal(sockaddr const * lhs,sockaddr const * rhs)149 PoolableSession::IPLinkage::equal(sockaddr const *lhs, sockaddr const *rhs)
150 {
151   return ats_ip_addr_port_eq(lhs, rhs);
152 }
153 
154 inline bool
equal(sockaddr const * lhs,PoolableSession const * rhs)155 PoolableSession::IPLinkage::equal(sockaddr const *lhs, PoolableSession const *rhs)
156 {
157   return ats_ip_addr_port_eq(lhs, key_of(rhs));
158 }
159 
160 inline bool
equal(PoolableSession const * lhs,sockaddr const * rhs)161 PoolableSession::IPLinkage::equal(PoolableSession const *lhs, sockaddr const *rhs)
162 {
163   return ats_ip_addr_port_eq(key_of(lhs), rhs);
164 }
165 
166 inline PoolableSession *&
next_ptr(self_type * ssn)167 PoolableSession::FQDNLinkage::next_ptr(self_type *ssn)
168 {
169   return ssn->_fqdn_link._next;
170 }
171 
172 inline PoolableSession *&
prev_ptr(self_type * ssn)173 PoolableSession::FQDNLinkage::prev_ptr(self_type *ssn)
174 {
175   return ssn->_fqdn_link._prev;
176 }
177 
178 inline uint64_t
hash_of(CryptoHash const & key)179 PoolableSession::FQDNLinkage::hash_of(CryptoHash const &key)
180 {
181   return key.fold();
182 }
183 
184 inline CryptoHash const &
key_of(self_type * ssn)185 PoolableSession::FQDNLinkage::key_of(self_type *ssn)
186 {
187   return ssn->hostname_hash;
188 }
189 
190 inline bool
equal(CryptoHash const & lhs,CryptoHash const & rhs)191 PoolableSession::FQDNLinkage::equal(CryptoHash const &lhs, CryptoHash const &rhs)
192 {
193   return lhs == rhs;
194 }
195