| 157 | } |
| 158 | |
| 159 | HSMresult_t |
| 160 | ServerSessionPool::acquireSession(sockaddr const *addr, CryptoHash const &hostname_hash, |
| 161 | TSServerSessionSharingMatchMask match_style, HttpSM *sm, PoolableSession *&to_return) |
| 162 | { |
| 163 | HSMresult_t zret = HSM_NOT_FOUND; |
| 164 | to_return = nullptr; |
| 165 | |
| 166 | if ((TS_SERVER_SESSION_SHARING_MATCH_MASK_HOSTONLY & match_style) && !(TS_SERVER_SESSION_SHARING_MATCH_MASK_IP & match_style)) { |
| 167 | Dbg(dbg_ctl_http_ss, "Search for host name only not IP. Pool size %zu", m_fqdn_pool.count()); |
| 168 | // This is broken out because only in this case do we check the host hash first. The range must be checked |
| 169 | // to verify an upstream that matches port and SNI name is selected. Walk backwards to select oldest. |
| 170 | in_port_t port = ats_ip_port_cast(addr); |
| 171 | auto range = m_fqdn_pool.equal_range(hostname_hash); |
| 172 | auto iter = std::make_reverse_iterator(range.end()); |
| 173 | auto const end = std::make_reverse_iterator(range.begin()); |
| 174 | while (iter != end) { |
| 175 | Dbg(dbg_ctl_http_ss, "Compare port 0x%x against 0x%x", port, ats_ip_port_cast(iter->get_remote_addr())); |
| 176 | if (port == ats_ip_port_cast(iter->get_remote_addr()) && |
| 177 | (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_SNI) || validate_sni(sm, iter->get_netvc())) && |
| 178 | (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_HOSTSNISYNC) || validate_host_sni(sm, iter->get_netvc())) && |
| 179 | (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_CERT) || validate_cert(sm, iter->get_netvc()))) { |
| 180 | zret = HSM_DONE; |
| 181 | break; |
| 182 | } |
| 183 | ++iter; |
| 184 | } |
| 185 | if (zret == HSM_DONE) { |
| 186 | to_return = &*iter; |
| 187 | if (!to_return->is_multiplexing()) { |
| 188 | this->removeSession(to_return); |
| 189 | } |
| 190 | } else if (iter != end) { |
| 191 | Dbg(dbg_ctl_http_ss, "Failed find entry due to name mismatch %s", sm->t_state.current.server->name); |
| 192 | } |
| 193 | } else if (TS_SERVER_SESSION_SHARING_MATCH_MASK_IP & match_style) { // matching is not disabled. |
| 194 | auto range = m_ip_pool.equal_range(addr); |
| 195 | // We want to access the sessions in LIFO order, so start from the back of the list. |
| 196 | auto iter = std::make_reverse_iterator(range.end()); |
| 197 | auto const end = std::make_reverse_iterator(range.begin()); |
| 198 | // The range is all that is needed in the match IP case, otherwise need to scan for matching fqdn |
| 199 | // And matches the other constraints as well |
| 200 | // Note the port is matched as part of the address key so it doesn't need to be checked again. |
| 201 | if (match_style & (~TS_SERVER_SESSION_SHARING_MATCH_MASK_IP)) { |
| 202 | while (iter != end) { |
| 203 | if ((!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_HOSTONLY) || iter->hostname_hash == hostname_hash) && |
| 204 | (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_SNI) || validate_sni(sm, iter->get_netvc())) && |
| 205 | (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_HOSTSNISYNC) || validate_host_sni(sm, iter->get_netvc())) && |
| 206 | (!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_CERT) || validate_cert(sm, iter->get_netvc()))) { |
| 207 | zret = HSM_DONE; |
| 208 | break; |
| 209 | } |
| 210 | ++iter; |
| 211 | } |
| 212 | } else if (iter != end) { |
| 213 | zret = HSM_DONE; |
| 214 | } |
| 215 | if (zret == HSM_DONE) { |
| 216 | to_return = &*iter; |
no test coverage detected