You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by rr...@apache.org on 2022/06/01 14:33:48 UTC
[trafficserver] branch master updated: Expose setting some HTTP/2 tunables via sni.yaml (#8818)
This is an automated email from the ASF dual-hosted git repository.
rrm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/master by this push:
new 63d09be0f Expose setting some HTTP/2 tunables via sni.yaml (#8818)
63d09be0f is described below
commit 63d09be0f470628045f9c19848944a990dde3de9
Author: Randall Meyer <rr...@apache.org>
AuthorDate: Wed Jun 1 07:33:42 2022 -0700
Expose setting some HTTP/2 tunables via sni.yaml (#8818)
proxy.config.http2.default_buffer_water_mark can now be set on a
per-domain basis.
---
doc/admin-guide/files/records.config.en.rst | 8 +++++---
doc/admin-guide/files/sni.yaml.en.rst | 10 ++++++++++
iocore/net/I_NetVConnection.h | 4 ++--
iocore/net/P_SNIActionPerformer.h | 20 ++++++++++++++++++++
iocore/net/SSLSNIConfig.cc | 3 +++
iocore/net/TLSSNISupport.h | 5 +++++
iocore/net/YamlSNIConfig.cc | 4 ++++
iocore/net/YamlSNIConfig.h | 2 ++
proxy/http2/Http2ClientSession.cc | 15 ++++++++++++---
9 files changed, 63 insertions(+), 8 deletions(-)
diff --git a/doc/admin-guide/files/records.config.en.rst b/doc/admin-guide/files/records.config.en.rst
index 94330a9ba..ed7d3b97d 100644
--- a/doc/admin-guide/files/records.config.en.rst
+++ b/doc/admin-guide/files/records.config.en.rst
@@ -2047,7 +2047,7 @@ Security
mismatch check is only performed if a relevant security policy for the SNI is set in :file:`sni.yaml`. The
``proxy.config.http.host_sni_policy`` :file:`records.config` value is used as the default value if either of these
policies is set in the corresponding :file:`sni.yaml` file entry and the :file:`sni.yaml` entry does not override
- this value via a :ref:`host_sni_policy attribute<override-host-sni-policy>` action.
+ this value via a :ref:`host_sni_policy<override-host-sni-policy>` attribute.
Cache Control
@@ -3877,7 +3877,7 @@ Client-Related Configuration
Configures |TS| to verify the origin server certificate
with the Certificate Authority (CA). This configuration takes a value of :code:`DISABLED`, :code:`PERMISSIVE`, or :code:`ENFORCED`
- You can override this global setting on a per domain basis in the :file:`sni.yaml` file using the :ref:`verify_server_policy attribute<override-verify-server-policy>`.
+ You can override this global setting on a per domain basis in the :file:`sni.yaml` file using the :ref:`verify_server_policy<override-verify-server-policy>` attribute.
You can also override via the conf_remap plugin. Those changes will take precedence over the changes in :file:`sni.yaml`.
@@ -3894,7 +3894,7 @@ Client-Related Configuration
Configures |TS| for what the default verify callback should check during origin server verification.
- You can override this global setting on a per domain basis in the :file:`sni.yaml` file using the :ref:`verify_server_properties attribute<override-verify-server-properties>`.
+ You can override this global setting on a per domain basis in the :file:`sni.yaml` file using the :ref:`verify_server_properties<override-verify-server-properties>` attribute.
You can also override via the conf_remap plugin. Those changes will take precedence over the changes in .:file:`sni.yaml`
@@ -4302,6 +4302,8 @@ HTTP/2 Configuration
Specifies the high water mark for all HTTP/2 frames on an outoging connection.
Default is -1 to preserve existing water marking behavior.
+ You can override this global setting on a per domain basis in the :file:`sni.yaml` file using the :ref:`http2_buffer_water_mark <override-h2-properties>` attribute.
+
HTTP/3 Configuration
====================
diff --git a/doc/admin-guide/files/sni.yaml.en.rst b/doc/admin-guide/files/sni.yaml.en.rst
index 7a04e4b15..5c1142014 100644
--- a/doc/admin-guide/files/sni.yaml.en.rst
+++ b/doc/admin-guide/files/sni.yaml.en.rst
@@ -42,9 +42,15 @@ Each table is a set of key / value pairs that create a configuration item. This
wildcard entries. To apply an SNI based setting on all the server names with a common upper level domain name,
the user needs to enter the fqdn in the configuration with a ``*.`` followed by the common domain name. (``*.yahoo.com`` for example).
+For some settings, there is no guarantee that they will be applied to a connection under certain conditions.
+An established TLS connection may be reused for another server name if it’s used for HTTP/2. This also means that settings
+for server name A may affects requests for server name B as well. See https://daniel.haxx.se/blog/2016/08/18/http2-connection-coalescing/
+for a more detailed description of HTTP/2 connection coalescing.
+
.. _override-verify-server-policy:
.. _override-verify-server-properties:
.. _override-host-sni-policy:
+.. _override-h2-properties:
========================= ========= ========================================================================================
Key Direction Meaning
@@ -130,6 +136,10 @@ client_sni_policy Outbound Policy of SNI on outbound connection.
http2 Inbound Indicates whether the H2 protocol should be added to or removed from the
protocol negotiation list. The valid values are :code:`on` or :code:`off`.
+http2_buffer_water_mark Inbound Specifies the high water mark for all HTTP/2 frames on an outoging connection.
+ By default this is :ts:cv:`proxy.config.http2.default_buffer_water_mark`.
+ NOTE: Connection coalescing may prevent this taking effect.
+
disable_h2 Inbound Deprecated for the more general h2 setting. Setting disable_h2
to :code:`true` is the same as setting http2 to :code:`on`.
diff --git a/iocore/net/I_NetVConnection.h b/iocore/net/I_NetVConnection.h
index f74c75091..12a889040 100644
--- a/iocore/net/I_NetVConnection.h
+++ b/iocore/net/I_NetVConnection.h
@@ -228,8 +228,6 @@ struct NetVCOptions {
bool tls_upstream = false;
- /// Reset all values to defaults.
-
/**
* Set to DISABLED, PERFMISSIVE, or ENFORCED
* Controls how the server certificate verification is handled
@@ -241,6 +239,8 @@ struct NetVCOptions {
* Currently SIGNATURE and NAME
*/
YamlSNIConfig::Property verifyServerProperties = YamlSNIConfig::Property::NONE;
+
+ /// Reset all values to defaults.
void reset();
void set_sock_param(int _recv_bufsize, int _send_bufsize, unsigned long _opt_flags, unsigned long _packet_mark = 0,
diff --git a/iocore/net/P_SNIActionPerformer.h b/iocore/net/P_SNIActionPerformer.h
index 13668816c..32d803dea 100644
--- a/iocore/net/P_SNIActionPerformer.h
+++ b/iocore/net/P_SNIActionPerformer.h
@@ -98,6 +98,26 @@ private:
bool enable_h2 = false;
};
+class HTTP2BufferWaterMark : public ActionItem
+{
+public:
+ HTTP2BufferWaterMark(int value) : value(value) {}
+ ~HTTP2BufferWaterMark() override {}
+
+ int
+ SNIAction(TLSSNISupport *snis, const Context &ctx) const override
+ {
+ auto ssl_vc = dynamic_cast<SSLNetVConnection *>(snis);
+ if (ssl_vc) {
+ ssl_vc->hints_from_sni.http2_buffer_water_mark = value;
+ }
+ return SSL_TLSEXT_ERR_OK;
+ }
+
+private:
+ int value = -1;
+};
+
class TunnelDestination : public ActionItem
{
public:
diff --git a/iocore/net/SSLSNIConfig.cc b/iocore/net/SSLSNIConfig.cc
index f48211205..b7938dcd7 100644
--- a/iocore/net/SSLSNIConfig.cc
+++ b/iocore/net/SSLSNIConfig.cc
@@ -87,6 +87,9 @@ SNIConfigParams::loadSNIConfig()
if (!item.client_sni_policy.empty()) {
ai->actions.push_back(std::make_unique<OutboundSNIPolicy>(item.client_sni_policy));
}
+ if (item.http2_buffer_water_mark.has_value()) {
+ ai->actions.push_back(std::make_unique<HTTP2BufferWaterMark>(item.http2_buffer_water_mark.value()));
+ }
ai->actions.push_back(std::make_unique<SNI_IpAllow>(item.ip_allow, item.fqdn));
diff --git a/iocore/net/TLSSNISupport.h b/iocore/net/TLSSNISupport.h
index 0470b6c28..2f5d6467c 100644
--- a/iocore/net/TLSSNISupport.h
+++ b/iocore/net/TLSSNISupport.h
@@ -23,6 +23,7 @@
*/
#pragma once
+#include <optional>
#include <string_view>
#include <memory>
#include <openssl/ssl.h>
@@ -49,6 +50,10 @@ public:
#endif
void on_servername(SSL *ssl, int *al, void *arg);
+ struct HintsFromSNI {
+ std::optional<uint32_t> http2_buffer_water_mark;
+ } hints_from_sni;
+
protected:
virtual void _fire_ssl_servername_event() = 0;
diff --git a/iocore/net/YamlSNIConfig.cc b/iocore/net/YamlSNIConfig.cc
index 6ee194af3..3f90fe99c 100644
--- a/iocore/net/YamlSNIConfig.cc
+++ b/iocore/net/YamlSNIConfig.cc
@@ -143,6 +143,7 @@ std::set<std::string> valid_sni_config_keys = {TS_fqdn,
TS_client_key,
TS_client_sni_policy,
TS_http2,
+ TS_http2_buffer_water_mark,
TS_ip_allow,
#if TS_USE_HELLO_CB || defined(OPENSSL_IS_BORINGSSL)
TS_valid_tls_versions_in,
@@ -173,6 +174,9 @@ template <> struct convert<YamlSNIConfig::Item> {
if (node[TS_http2]) {
item.offer_h2 = node[TS_http2].as<bool>();
}
+ if (node[TS_http2_buffer_water_mark]) {
+ item.http2_buffer_water_mark = node[TS_http2_buffer_water_mark].as<int>();
+ }
// enum
if (node[TS_verify_client]) {
diff --git a/iocore/net/YamlSNIConfig.h b/iocore/net/YamlSNIConfig.h
index 13887b683..dbb79ba29 100644
--- a/iocore/net/YamlSNIConfig.h
+++ b/iocore/net/YamlSNIConfig.h
@@ -55,6 +55,7 @@ TSDECL(client_sni_policy);
TSDECL(ip_allow);
TSDECL(valid_tls_versions_in);
TSDECL(http2);
+TSDECL(http2_buffer_water_mark);
TSDECL(host_sni_policy);
#undef TSDECL
@@ -84,6 +85,7 @@ struct YamlSNIConfig {
bool protocol_unset = true;
unsigned long protocol_mask;
std::vector<int> tunnel_alpn{};
+ std::optional<int> http2_buffer_water_mark;
bool tunnel_prewarm_srv = false;
uint32_t tunnel_prewarm_min = 0;
diff --git a/proxy/http2/Http2ClientSession.cc b/proxy/http2/Http2ClientSession.cc
index 415bec13b..62c6f9f95 100644
--- a/proxy/http2/Http2ClientSession.cc
+++ b/proxy/http2/Http2ClientSession.cc
@@ -25,6 +25,7 @@
#include "HttpDebugNames.h"
#include "tscore/ink_base64.h"
#include "Http2CommonSessionInternal.h"
+#include "TLSSNISupport.h"
#include "TLSEarlyDataSupport.h"
ClassAllocator<Http2ClientSession, true> http2ClientSessionAllocator("http2ClientSessionAllocator");
@@ -116,9 +117,17 @@ Http2ClientSession::new_connection(NetVConnection *new_vc, MIOBuffer *iobuf, IOB
this->_read_buffer_reader = reader ? reader : this->read_buffer->alloc_reader();
// This block size is the buffer size that we pass to SSLWriteBuffer
- auto buffer_block_size_index = iobuffer_size_to_index(Http2::write_buffer_block_size, MAX_BUFFER_SIZE_INDEX);
- this->write_buffer = new_MIOBuffer(buffer_block_size_index);
- this->write_buffer->water_mark = Http2::buffer_water_mark;
+ auto buffer_block_size_index = iobuffer_size_to_index(Http2::write_buffer_block_size, MAX_BUFFER_SIZE_INDEX);
+ this->write_buffer = new_MIOBuffer(buffer_block_size_index);
+
+ uint32_t buffer_water_mark;
+ TLSSNISupport *snis = dynamic_cast<TLSSNISupport *>(this->_vc);
+ if (snis && snis->hints_from_sni.http2_buffer_water_mark.has_value()) {
+ buffer_water_mark = snis->hints_from_sni.http2_buffer_water_mark.value();
+ } else {
+ buffer_water_mark = Http2::buffer_water_mark;
+ }
+ this->write_buffer->water_mark = buffer_water_mark;
this->_write_buffer_reader = this->write_buffer->alloc_reader();
this->_write_size_threshold = index_to_buffer_size(buffer_block_size_index) * Http2::write_size_threshold;