|
34 | 34 | #include "proxy/ProxySession.h" |
35 | 35 | #include "proxy/http/HttpSM.h" |
36 | 36 | #include "proxy/http/HttpDebugNames.h" |
| 37 | +#include <iterator> |
37 | 38 |
|
38 | 39 | // Initialize a thread to handle HTTP session management |
39 | 40 | void |
@@ -151,47 +152,52 @@ ServerSessionPool::acquireSession(sockaddr const *addr, CryptoHash const &hostna |
151 | 152 | // This is broken out because only in this case do we check the host hash first. The range must be checked |
152 | 153 | // to verify an upstream that matches port and SNI name is selected. Walk backwards to select oldest. |
153 | 154 | in_port_t port = ats_ip_port_cast(addr); |
154 | | - auto first = m_fqdn_pool.find(hostname_hash); |
155 | | - while (first != m_fqdn_pool.end() && first->hostname_hash == hostname_hash) { |
156 | | - Debug("http_ss", "Compare port 0x%x against 0x%x", port, ats_ip_port_cast(first->get_remote_addr())); |
157 | | - if (port == ats_ip_port_cast(first->get_remote_addr()) && |
158 | | - (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_SNI) || validate_sni(sm, first->get_netvc())) && |
159 | | - (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_HOSTSNISYNC) || validate_host_sni(sm, first->get_netvc())) && |
160 | | - (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_CERT) || validate_cert(sm, first->get_netvc()))) { |
| 155 | + auto range = m_fqdn_pool.equal_range(hostname_hash); |
| 156 | + auto iter = std::make_reverse_iterator(range.end()); |
| 157 | + auto const end = std::make_reverse_iterator(range.begin()); |
| 158 | + while (iter != end) { |
| 159 | + Debug("http_ss", "Compare port 0x%x against 0x%x", port, ats_ip_port_cast(iter->get_remote_addr())); |
| 160 | + if (port == ats_ip_port_cast(iter->get_remote_addr()) && |
| 161 | + (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_SNI) || validate_sni(sm, iter->get_netvc())) && |
| 162 | + (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_HOSTSNISYNC) || validate_host_sni(sm, iter->get_netvc())) && |
| 163 | + (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_CERT) || validate_cert(sm, iter->get_netvc()))) { |
161 | 164 | zret = HSM_DONE; |
162 | 165 | break; |
163 | 166 | } |
164 | | - ++first; |
| 167 | + ++iter; |
165 | 168 | } |
166 | 169 | if (zret == HSM_DONE) { |
167 | | - to_return = first; |
| 170 | + to_return = iter.base(); |
168 | 171 | if (!to_return->is_multiplexing()) { |
169 | 172 | this->removeSession(to_return); |
170 | 173 | } |
171 | | - } else if (first != m_fqdn_pool.end()) { |
| 174 | + } else if (iter != end) { |
172 | 175 | Debug("http_ss", "Failed find entry due to name mismatch %s", sm->t_state.current.server->name); |
173 | 176 | } |
174 | 177 | } else if (TS_SERVER_SESSION_SHARING_MATCH_MASK_IP & match_style) { // matching is not disabled. |
175 | | - auto first = m_ip_pool.find(addr); |
| 178 | + auto range = m_ip_pool.equal_range(addr); |
| 179 | + // We want to access the sessions in LIFO order, so start from the back of the list. |
| 180 | + auto iter = std::make_reverse_iterator(range.end()); |
| 181 | + auto const end = std::make_reverse_iterator(range.begin()); |
176 | 182 | // The range is all that is needed in the match IP case, otherwise need to scan for matching fqdn |
177 | 183 | // And matches the other constraints as well |
178 | 184 | // Note the port is matched as part of the address key so it doesn't need to be checked again. |
179 | 185 | if (match_style & (~TS_SERVER_SESSION_SHARING_MATCH_MASK_IP)) { |
180 | | - while (first != m_ip_pool.end() && ats_ip_addr_port_eq(first->get_remote_addr(), addr)) { |
181 | | - if ((!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_HOSTONLY) || first->hostname_hash == hostname_hash) && |
182 | | - (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_SNI) || validate_sni(sm, first->get_netvc())) && |
183 | | - (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_HOSTSNISYNC) || validate_host_sni(sm, first->get_netvc())) && |
184 | | - (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_CERT) || validate_cert(sm, first->get_netvc()))) { |
| 186 | + while (iter != end) { |
| 187 | + if ((!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_HOSTONLY) || iter->hostname_hash == hostname_hash) && |
| 188 | + (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_SNI) || validate_sni(sm, iter->get_netvc())) && |
| 189 | + (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_HOSTSNISYNC) || validate_host_sni(sm, iter->get_netvc())) && |
| 190 | + (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_CERT) || validate_cert(sm, iter->get_netvc()))) { |
185 | 191 | zret = HSM_DONE; |
186 | 192 | break; |
187 | 193 | } |
188 | | - ++first; |
| 194 | + ++iter; |
189 | 195 | } |
190 | | - } else if (first != m_ip_pool.end()) { |
| 196 | + } else if (iter != end) { |
191 | 197 | zret = HSM_DONE; |
192 | 198 | } |
193 | 199 | if (zret == HSM_DONE) { |
194 | | - to_return = first; |
| 200 | + to_return = iter.base(); |
195 | 201 | if (!to_return->is_multiplexing()) { |
196 | 202 | this->removeSession(to_return); |
197 | 203 | } |
|
0 commit comments