Skip to content

Commit b2bfc24

Browse files
shinrichzwoop
authored andcommitted
Fix session pool to add and fetch to beginning of hash chain rather than end (#6805)
Co-authored-by: Susan Hinrichs <shinrich@verizonmedia.com> (cherry picked from commit b973268)
1 parent d26ff2b commit b2bfc24

File tree

3 files changed

+25
-42
lines changed

3 files changed

+25
-42
lines changed

include/tscore/IntrusiveHashMap.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -539,16 +539,6 @@ IntrusiveHashMap<H>::insert(value_type *v)
539539
if (spot != bucket->_v) {
540540
mixed_p = true; // found some other key, it's going to be mixed.
541541
}
542-
if (spot != limit) {
543-
// If an equal key was found, walk past those to insert at the upper end of the range.
544-
do {
545-
spot = H::next_ptr(spot);
546-
} while (spot != limit && H::equal(key, H::key_of(spot)));
547-
if (spot != limit) { // something not equal past last equivalent, it's going to be mixed.
548-
mixed_p = true;
549-
}
550-
}
551-
552542
_list.insert_before(spot, v);
553543
if (spot == bucket->_v) { // added before the bucket start, update the start.
554544
bucket->_v = v;

proxy/http/HttpSessionManager.cc

Lines changed: 19 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -150,51 +150,44 @@ ServerSessionPool::acquireSession(sockaddr const *addr, CryptoHash const &hostna
150150
// This is broken out because only in this case do we check the host hash first. The range must be checked
151151
// to verify an upstream that matches port and SNI name is selected. Walk backwards to select oldest.
152152
in_port_t port = ats_ip_port_cast(addr);
153-
FQDNTable::iterator first, last;
154-
// FreeBSD/clang++ bug workaround: explicit cast to super type to make overload work. Not needed on Fedora27 nor gcc.
155-
// Not fixed on FreeBSD as of llvm 6.0.1.
156-
std::tie(first, last) = static_cast<const decltype(m_fqdn_pool)::range::super_type &>(m_fqdn_pool.equal_range(hostname_hash));
157-
while (last != first) {
158-
--last;
159-
if (port == ats_ip_port_cast(last->get_server_ip()) &&
160-
(!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_SNI) || validate_sni(sm, last->get_netvc())) &&
161-
(!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_HOSTSNISYNC) || validate_host_sni(sm, last->get_netvc())) &&
162-
(!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_CERT) || validate_cert(sm, last->get_netvc()))) {
153+
auto first = m_fqdn_pool.find(hostname_hash);
154+
while (first != m_fqdn_pool.end() && first->hostname_hash == hostname_hash) {
155+
if (port == ats_ip_port_cast(first->get_server_ip()) &&
156+
(!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_SNI) || validate_sni(sm, first->get_netvc())) &&
157+
(!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_HOSTSNISYNC) || validate_host_sni(sm, first->get_netvc())) &&
158+
(!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_CERT) || validate_cert(sm, first->get_netvc()))) {
163159
zret = HSM_DONE;
164160
break;
165161
}
162+
++first;
166163
}
167164
if (zret == HSM_DONE) {
168-
to_return = last;
169-
m_fqdn_pool.erase(last);
165+
to_return = first;
166+
m_fqdn_pool.erase(first);
170167
m_ip_pool.erase(to_return);
171168
}
172169
} else if (TS_SERVER_SESSION_SHARING_MATCH_MASK_IP & match_style) { // matching is not disabled.
173-
IPTable::iterator first, last;
174-
// FreeBSD/clang++ bug workaround: explicit cast to super type to make overload work. Not needed on Fedora27 nor gcc.
175-
// Not fixed on FreeBSD as of llvm 6.0.1.
176-
std::tie(first, last) = static_cast<const decltype(m_ip_pool)::range::super_type &>(m_ip_pool.equal_range(addr));
170+
auto first = m_ip_pool.find(addr);
177171
// The range is all that is needed in the match IP case, otherwise need to scan for matching fqdn
178172
// And matches the other constraints as well
179173
// Note the port is matched as part of the address key so it doesn't need to be checked again.
180174
if (match_style & (~TS_SERVER_SESSION_SHARING_MATCH_MASK_IP)) {
181-
while (last != first) {
182-
--last;
183-
if ((!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_HOSTONLY) || last->hostname_hash == hostname_hash) &&
184-
(!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_SNI) || validate_sni(sm, last->get_netvc())) &&
185-
(!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_HOSTSNISYNC) || validate_host_sni(sm, last->get_netvc())) &&
186-
(!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_CERT) || validate_cert(sm, last->get_netvc()))) {
175+
while (first != m_ip_pool.end() && ats_ip_addr_port_eq(first->get_server_ip(), addr)) {
176+
if ((!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_HOSTONLY) || first->hostname_hash == hostname_hash) &&
177+
(!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_SNI) || validate_sni(sm, first->get_netvc())) &&
178+
(!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_HOSTSNISYNC) || validate_host_sni(sm, first->get_netvc())) &&
179+
(!(match_style & TS_SERVER_SESSION_SHARING_MATCH_MASK_CERT) || validate_cert(sm, first->get_netvc()))) {
187180
zret = HSM_DONE;
188181
break;
189182
}
183+
++first;
190184
}
191-
} else if (last != first) {
192-
--last;
185+
} else if (first != m_ip_pool.end()) {
193186
zret = HSM_DONE;
194187
}
195188
if (zret == HSM_DONE) {
196-
to_return = last;
197-
m_ip_pool.erase(last);
189+
to_return = first;
190+
m_ip_pool.erase(first);
198191
m_fqdn_pool.erase(to_return);
199192
}
200193
}

src/tscore/unit_tests/test_IntrusiveHashMap.cc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ TEST_CASE("IntrusiveHashMap", "[libts][IntrusiveHashMap]")
123123
auto r = map.equal_range("dup"sv);
124124
REQUIRE(r.first != r.second);
125125
REQUIRE(r.first->_payload == "dup"sv);
126-
REQUIRE(r.first->_n == 79);
126+
REQUIRE(r.first->_n == 81);
127127

128128
Map::iterator idx;
129129

@@ -138,13 +138,13 @@ TEST_CASE("IntrusiveHashMap", "[libts][IntrusiveHashMap]")
138138
REQUIRE(r.first != r.second);
139139
idx = r.first;
140140
REQUIRE(idx->_payload == "dup"sv);
141-
REQUIRE(idx->_n == 79);
141+
REQUIRE(idx->_n == 81);
142142
REQUIRE((++idx)->_payload == "dup"sv);
143143
REQUIRE(idx->_n != r.first->_n);
144-
REQUIRE(idx->_n == 80);
144+
REQUIRE(idx->_n == 79);
145145
REQUIRE((++idx)->_payload == "dup"sv);
146146
REQUIRE(idx->_n != r.first->_n);
147-
REQUIRE(idx->_n == 81);
147+
REQUIRE(idx->_n == 80);
148148
REQUIRE(++idx == map.end());
149149
// Verify only the "dup" items are left.
150150
for (auto &&elt : map) {
@@ -200,7 +200,7 @@ TEST_CASE("IntrusiveHashMapManyStrings", "[IntrusiveHashMap]")
200200
}
201201
for (int idx = 23; idx < N; idx += 23) {
202202
auto spot = ihm.find(strings[idx]);
203-
if (spot == ihm.end() || spot->_n != idx || ++spot == ihm.end() || spot->_n != 2000 + idx) {
203+
if (spot == ihm.end() || spot->_n != 2000 + idx || ++spot == ihm.end() || spot->_n != idx) {
204204
miss_p = true;
205205
}
206206
}
@@ -213,7 +213,7 @@ TEST_CASE("IntrusiveHashMapManyStrings", "[IntrusiveHashMap]")
213213
}
214214
for (int idx = 31; idx < N; idx += 31) {
215215
auto spot = ihm.find(strings[idx]);
216-
if (spot == ihm.end() || spot->_n != idx || ++spot == ihm.end() || (idx != (23 * 31) && spot->_n != 3000 + idx) ||
216+
if (spot == ihm.end() || spot->_n != 3000 + idx || ++spot == ihm.end() || (idx != (23 * 31) && spot->_n != idx) ||
217217
(idx == (23 * 31) && spot->_n != 2000 + idx)) {
218218
miss_p = true;
219219
}

0 commit comments

Comments
 (0)