Skip to content

Commit c408114

Browse files
author
Brian Olsen
committed
add host_override to parent.config and other sni name fixes
1 parent 9b7734e commit c408114

14 files changed

Lines changed: 380 additions & 29 deletions

include/proxy/ParentSelection.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ class ParentRecord : public ControlBase
167167
int max_unavailable_server_retries = 1;
168168
int secondary_mode = 1;
169169
bool ignore_self_detect = false;
170+
bool host_override = false;
170171
ParentHashAlgorithm consistent_hash_algorithm = ParentHashAlgorithm::SIPHASH24;
171172
uint64_t consistent_hash_seed0 = 0;
172173
uint64_t consistent_hash_seed1 = 0;
@@ -242,6 +243,20 @@ struct ParentResult {
242243
return is_api_result() ? ParentRetry_t::NONE : rec->parent_retry;
243244
}
244245

246+
bool
247+
host_override() const
248+
{
249+
if (is_api_result()) {
250+
return false;
251+
}
252+
253+
if (!is_some()) {
254+
return false;
255+
}
256+
257+
return rec->host_override;
258+
}
259+
245260
unsigned
246261
max_retries(ParentRetry_t method) const
247262
{

include/proxy/http/remap/NextHopSelectionStrategy.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include <utility>
2828

2929
#include "ts/apidefs.h"
30-
#include "proxy/ParentSelection.h"
3130
#include "proxy/http/HttpTransact.h"
3231

3332
#ifndef _NH_UNIT_TESTS_
@@ -199,8 +198,6 @@ class NextHopSelectionStrategy
199198
const time_t now = 0);
200199
bool nextHopExists(TSHttpTxn txnp, void *ih = nullptr);
201200

202-
void setHostHeader(TSHttpTxn txnp, const char *hostname);
203-
204201
virtual ParentRetry_t responseIsRetryable(int64_t sm_id, HttpTransact::CurrentInfo &current_info, HTTPStatus response_code);
205202

206203
void retryComplete(TSHttpTxn txn, const char *hostname, const int port);

src/proxy/ParentSelection.cc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,13 @@ ParentRecord::Init(matcher_line *line_info)
797797
ignore_self_detect = false;
798798
}
799799
used = true;
800+
} else if (strcasecmp(label, "host_override") == 0) {
801+
if (strcasecmp(val, "true") == 0) {
802+
host_override = true;
803+
} else {
804+
host_override = false;
805+
}
806+
used = true;
800807
} else if (strcasecmp(label, "hash_algorithm") == 0) {
801808
consistent_hash_algorithm = parseHashAlgorithm(val);
802809
used = true;

src/proxy/http/HttpSM.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5274,11 +5274,11 @@ HttpSM::get_outbound_sni() const
52745274
// By default the host header field value is used for the SNI.
52755275
zret = t_state.hdr_info.server_request.host_get();
52765276
} else if (_ua.get_txn() && policy == "server_name"_tv) {
5277-
const char *server_name = snis->get_sni_server_name();
5278-
if (server_name[0] == '\0') {
5277+
const char *const server_name = snis->get_sni_server_name();
5278+
if (nullptr == server_name || server_name[0] == '\0') {
52795279
zret.assign(nullptr, swoc::TextView::npos);
52805280
} else {
5281-
zret.assign(snis->get_sni_server_name(), swoc::TextView::npos);
5281+
zret.assign(server_name, swoc::TextView::npos);
52825282
}
52835283
} else if (policy.front() == '@') { // guaranteed non-empty from previous clause
52845284
zret = policy.remove_prefix(1);

src/proxy/http/HttpTransact.cc

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -139,19 +139,51 @@ bypass_ok(HttpTransact::State *s)
139139
return false;
140140
}
141141
142+
// wrapper to choose between a remap next hop strategy or use parent.config
143+
// remap next hop strategy is preferred
144+
inline static bool
145+
host_override(HttpTransact::State *s)
146+
{
147+
if (s->response_action.handled) { // should be handled by the plugin
148+
return false;
149+
} else if (nullptr != s->next_hop_strategy) {
150+
// remap strategies do not support the TSHttpTxnParentProxySet API.
151+
return s->next_hop_strategy->host_override;
152+
} else if (nullptr != s->parent_params) {
153+
return s->parent_result.host_override();
154+
}
155+
return false;
156+
}
157+
158+
// wrapper to choose between a remap next hop strategy or use parent.config
159+
// remap next hop strategy is preferred
160+
inline static bool
161+
is_some(HttpTransact::State *s)
162+
{
163+
if (s->response_action.handled) {
164+
return true;
165+
} else if (nullptr != s->next_hop_strategy) {
166+
// remap strategies do not support the TSHttpTxnParentProxySet API.
167+
return s->parent_result.result == ParentResultType::SPECIFIED;
168+
} else if (nullptr != s->parent_params) {
169+
return s->parent_result.is_some();
170+
}
171+
return false;
172+
}
173+
142174
// wrapper to choose between a remap next hop strategy or use parent.config
143175
// remap next hop strategy is preferred
144176
inline static bool
145177
is_api_result(HttpTransact::State *s)
146178
{
147-
bool r = false;
179+
bool res = false;
148180
if (nullptr != s->next_hop_strategy) {
149181
// remap strategies do not support the TSHttpTxnParentProxySet API.
150-
r = false;
182+
res = false;
151183
} else if (nullptr != s->parent_params) {
152-
r = s->parent_result.is_api_result();
184+
res = s->parent_result.is_api_result();
153185
}
154-
return r;
186+
return res;
155187
}
156188
157189
// wrapper to get the max_retries.
@@ -207,6 +239,8 @@ retry_type(HttpTransact::State *s)
207239
inline static void
208240
findParent(HttpTransact::State *s)
209241
{
242+
TxnDbg(dbg_ctl_http_trans, "findParent");
243+
210244
Metrics::Counter::increment(http_rsb.parent_count);
211245
if (s->response_action.handled) {
212246
s->parent_result.hostname = s->response_action.action.hostname;
@@ -295,6 +329,8 @@ parentExists(HttpTransact::State *s)
295329
inline static void
296330
nextParent(HttpTransact::State *s)
297331
{
332+
TxnDbg(dbg_ctl_http_trans, "nextParent");
333+
298334
TxnDbg(dbg_ctl_parent_down, "connection to parent %s failed, conn_state: %s, request to origin: %s", s->parent_result.hostname,
299335
HttpDebugNames::get_server_state_name(s->current.state), s->request_data.get_host());
300336
Metrics::Counter::increment(http_rsb.parent_count);
@@ -599,10 +635,11 @@ find_server_and_update_current_info(HttpTransact::State *s)
599635
} else {
600636
findParent(s);
601637
}
602-
if (!s->parent_result.is_some() || is_api_result(s) || parent_is_proxy(s)) {
638+
if (!is_some(s) || is_api_result(s) || parent_is_proxy(s)) {
603639
TxnDbg(dbg_ctl_http_trans, "request not cacheable, so bypass parent");
604640
s->parent_result.result = ParentResultType::DIRECT;
605641
}
642+
606643
} else if (s->txn_conf->uncacheable_requests_bypass_parent && s->txn_conf->no_dns_forward_to_parent == 0 &&
607644
!HttpTransact::is_request_cache_lookupable(s)) {
608645
// request not lookupable and cacheable, so bypass parent if the parent is not an origin server.
@@ -616,10 +653,12 @@ find_server_and_update_current_info(HttpTransact::State *s)
616653
} else {
617654
findParent(s);
618655
}
619-
if (!s->parent_result.is_some() || is_api_result(s) || parent_is_proxy(s)) {
656+
657+
if (!is_some(s) || is_api_result(s) || parent_is_proxy(s)) {
620658
TxnDbg(dbg_ctl_http_trans, "request not cacheable, so bypass parent");
621659
s->parent_result.result = ParentResultType::DIRECT;
622660
}
661+
623662
} else {
624663
switch (s->parent_result.result) {
625664
case ParentResultType::UNDEFINED:
@@ -660,14 +699,32 @@ find_server_and_update_current_info(HttpTransact::State *s)
660699
}
661700
662701
switch (s->parent_result.result) {
663-
case ParentResultType::SPECIFIED:
664-
s->parent_info.name = s->arena.str_store(s->parent_result.hostname, strlen(s->parent_result.hostname));
702+
case ParentResultType::SPECIFIED: {
703+
char const *const hostname = s->parent_result.hostname;
704+
705+
if (nullptr != hostname) {
706+
s->parent_info.name = s->arena.str_store(hostname, strlen(hostname));
707+
708+
// if host header override option enabled
709+
if (host_override(s)) {
710+
TxnDbg(dbg_ctl_http_trans, "overriding host header with parent %s", hostname);
711+
if (!s->hdr_info.server_request.valid()) {
712+
s->hdr_info.client_request.value_set(static_cast<std::string_view>(MIME_FIELD_HOST), hostname);
713+
s->hdr_info.client_request.mark_target_dirty();
714+
} else {
715+
s->hdr_info.server_request.value_set(static_cast<std::string_view>(MIME_FIELD_HOST), hostname);
716+
s->hdr_info.server_request.mark_target_dirty();
717+
}
718+
}
719+
}
720+
665721
update_current_info(&s->current, &s->parent_info, ResolveInfo::PARENT_PROXY, false);
666722
update_dns_info(&s->dns_info, &s->current);
667723
ink_assert(s->dns_info.looking_up == ResolveInfo::PARENT_PROXY);
668724
s->next_hop_scheme = URL_WKSIDX_HTTP;
669725
670726
return ResolveInfo::PARENT_PROXY;
727+
}
671728
case ParentResultType::FAIL:
672729
// No more parents - need to return an error message
673730
s->current.request_to = ResolveInfo::HOST_NONE;

src/proxy/http/remap/NextHopConsistentHash.cc

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -547,8 +547,4 @@ NextHopConsistentHash::findNextHop(TSHttpTxn txnp, void * /* ih ATS_UNUSED */, t
547547
NH_Dbg(NH_DBG_CTL, "[%" PRIu64 "] result.result: %s set hostname null port 0 retry false", sm_id,
548548
ParentResultStr[static_cast<int>(result.result)]);
549549
}
550-
551-
setHostHeader(txnp, result.hostname);
552-
553-
return;
554550
}

src/proxy/http/remap/NextHopRoundRobin.cc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,6 @@ NextHopRoundRobin::findNextHop(TSHttpTxn txnp, void * /* ih ATS_UNUSED */, time_
170170
result->last_parent = cur_hst_index;
171171
result->last_group = cur_grp_index;
172172
result->retry = parentRetry;
173-
setHostHeader(txnp, result->hostname);
174173
ink_assert(result->hostname != nullptr);
175174
ink_assert(result->port != 0);
176175
NH_Dbg(NH_DBG_CTL, "[%" PRIu64 "] Chosen parent = %s.%d", sm_id, result->hostname, result->port);

src/proxy/http/remap/NextHopSelectionStrategy.cc

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -265,16 +265,6 @@ NextHopSelectionStrategy::markNextHop(TSHttpTxn txnp, const char *hostname, cons
265265
return passive_health.markNextHop(txnp, hostname, port, status, ih, now);
266266
}
267267

268-
void
269-
NextHopSelectionStrategy::setHostHeader(TSHttpTxn txnp, const char *hostname)
270-
{
271-
if (host_override && nullptr != hostname) {
272-
HttpSM *sm = reinterpret_cast<HttpSM *>(txnp);
273-
sm->t_state.hdr_info.client_request.value_set(static_cast<std::string_view>(MIME_FIELD_HOST), hostname);
274-
NH_Dbg(NH_DBG_CTL, "[%" PRIu64 "] overriding host header with parent %s", sm->sm_id, hostname);
275-
}
276-
}
277-
278268
bool
279269
NextHopSelectionStrategy::nextHopExists(TSHttpTxn txnp, void * /* ih ATS_UNUSED */)
280270
{
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
# bash script used to generate sni parent test certs
18+
19+
for name in foo bar
20+
do
21+
openssl req -x509 -newkey rsa:2048 \
22+
-keyout server-${name}.key -out server-${name}.pem \
23+
-days 3650 -nodes \
24+
-subj "/C=US/ST=CO/L=Denver/O=Comcast/OU=Edge/CN=${name}.com" \
25+
-addext "subjectAltName=DNS:${name}.com,DNS:www.${name}.com,DNS:*.${name}.com" \
26+
-addext "basicConstraints=critical,CA:TRUE" \
27+
-addext "keyUsage=critical,keyCertSign,cRLSign" \
28+
-addext "subjectKeyIdentifier=hash"
29+
done
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
-----BEGIN PRIVATE KEY-----
2+
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC7hSSKR+PDyaK9
3+
Qf5Wi2DoBedwTaIiHRVUOmjGMhb9bHH/xQ1xXbIlXhl9LB5z6KWZTLN/6tDbJMlk
4+
SF5CEPLXt0+XSwpx1ZZpBaxInKCZoiUbfazwb95y8evPYfOOmMR8tP/BKtygo0+U
5+
MbzjpIGZEdOkyWF6U4BtMJopC41JOxkrwvGG3DDBDNMui3qAgpmedylGhz7Lilpu
6+
XLc2cprtIBbo8jcQj4G0My5flZhvHmFe29L2YboLG2JtS8e39zOe+pfLb7T0JmDm
7+
UgxeJB7KH/d7BI90J1tYctVH2ky20oXQ2R1IC2bhsfuDEIo5OhPu56rINSmvXYDD
8+
RHL1nJH9AgMBAAECggEAJYzSVdxyeBzS+UoTR7pOU/gGsd7h5injwQOXQoT6RJIo
9+
O9r2R6rHByOSQBYLHRPLwWhyE13up8t0hp/VPC6PqnG7PuUYeNYX8fzgVIQExu8I
10+
tjoS3OzR4zudiGApePcPdZd7FW/jUUmSoG7bT8x75S6ELp3i5q986qCOZkS5bJ3Q
11+
Tr6LdgwYsdRMuwTBmHFym3obd8rVe1oQ4QY2M0mYAraGnFxiCNV+S+hDNsJ7na3F
12+
hbeBk+YpFKZ/dGDrKClhNbOmpSZmazihHaYoKrBc+fhJSzxVU5YfN+Ds7jsOptpa
13+
m0pr8Di3QnibkIUrjNiB3ewkIi+tyo0YO5Zzq406oQKBgQDxt4r/6hni0mBY3VrR
14+
UT74gzGihqxfXTLjq7Hiju9BC5qK9MaVRl+s5I6+phfSg4kyJSFsoWxcoKYFE/Km
15+
4xpk3sJlVIBwRBmx76h5B3eEpLayhoBR2TT0Cl5M8yhvz2p8CQO/MmGLP3qe/PqH
16+
32rBNLAs65e4ts2uKUJMC+AkrQKBgQDGmcM6vgRtq/DASFMMqpimSX+8fj9AGqLf
17+
mVcItXHx7pS1Aiq1G3PSA4efSryMjoleez3mfqFoPvTSP0ASIaQua9rAerfWfYaG
18+
/P8yAG7oddBb0SDe7f05VjY5jv3dS7sSDHpfaIa06xtRxd6HqUo7iPOir0FR6UzA
19+
iNkxKfR8kQKBgQCnhxxxjmDukfxw2soM9RB90P/fsxNY7RFONjuN2J7+J/qugEP6
20+
RdId1DMS867jGoNGG/H0hlTCRh2Ku26cOB6c9r8o185FAQ4GAyJy77foWPi+9vWM
21+
xMwsr9r33jeSduFIoj7UjyiICDEGbDN/ZFtrGQdZutdnEFuxb6shZcGt6QKBgFJj
22+
r65K7iNhVTsvxeRXUYSKsUdNSIgbhL4mKwkd3Ot1ApQlFfqULPRPKpBWvOnCqBJe
23+
Jkvc9LD+jSo7uyTKeAYaEGIRhvqgkJKnmmbv7xLY7Vtp4q0ZJhgHP++Y9pA7vpu6
24+
OXojLt8XOfoukCbPgFA6fHhdJEgK9SBapV/T++1BAoGBAMzO2jugm25fBzqWQpSe
25+
JV/CoQIbw2SUyXunsReIMqnYBETUDvzPrvQ0aRWUPtkzwf+vlbU7vauX4CRogB8e
26+
PWakmkCuSjPlxqycYUk/xIYEuaXn7Kk7IeF3UEbeSJLq9+cXeDun8OSE9lmD2Phn
27+
ITIVjf8kn1qEPgfr9GlGnaSN
28+
-----END PRIVATE KEY-----

0 commit comments

Comments
 (0)