diff --git a/doc/.tx/config b/doc/.tx/config index 65eedbc82e8..b3e1f737f4e 100644 --- a/doc/.tx/config +++ b/doc/.tx/config @@ -752,6 +752,11 @@ file_filter = locale//LC_MESSAGES/developer-guide/api/functions/TSHttpConn source_file = _build/locale/pot/developer-guide/api/functions/TSHttpConnect.en.pot source_lang = en +[apache-traffic-server-6x.developer-guide--api--functions--TSHttpConnectPlugin_en] +file_filter = locale//LC_MESSAGES/developer-guide/api/functions/TSHttpConnectPlugin.en.po +source_file = _build/locale/pot/developer-guide/api/functions/TSHttpConnectPlugin.en.pot +source_lang = en + [apache-traffic-server-6x.developer-guide--api--functions--TSHttpConnectWithPluginId_en] file_filter = locale//LC_MESSAGES/developer-guide/api/functions/TSHttpConnectWithPluginId.en.po source_file = _build/locale/pot/developer-guide/api/functions/TSHttpConnectWithPluginId.en.pot @@ -1342,6 +1347,21 @@ file_filter = locale//LC_MESSAGES/developer-guide/api/functions/TSPluginIn source_file = _build/locale/pot/developer-guide/api/functions/TSPluginInit.en.pot source_lang = en +[apache-traffic-server-6x.developer-guide--api--functions--TSPluginVCIOBufferIndexGet] +file_filter = locale//LC_MESSAGES/developer-guide/api/functions/TSPluginVCIOBufferIndexGet.en.po +source_file = _build/locale/pot/developer-guide/api/functions/TSPluginVCIOBufferIndexGet.en.pot +source_lang = en + +[apache-traffic-server-6x.developer-guide--api--functions--TSPluginVCIOBufferWaterMarkGet] +file_filter = locale//LC_MESSAGES/developer-guide/api/functions/TSPluginVCIOBufferWaterMarkGet.en.po +source_file = _build/locale/pot/developer-guide/api/functions/TSPluginVCIOBufferWaterMarkGet.en.pot +source_lang = en + +[apache-traffic-server-6x.developer-guide--api--functions--TSHttpConnectOptionsGet] +file_filter = locale//LC_MESSAGES/developer-guide/api/functions/TSHttpConnectOptionsGet.en.po +source_file = _build/locale/pot/developer-guide/api/functions/TSHttpConnectOptionsGet.en.pot +source_lang = e + [apache-traffic-server-6x.developer-guide--api--functions--TSRemap_en] file_filter = locale//LC_MESSAGES/developer-guide/api/functions/TSRemap.en.po source_file = _build/locale/pot/developer-guide/api/functions/TSRemap.en.pot diff --git a/doc/admin-guide/files/records.config.en.rst b/doc/admin-guide/files/records.config.en.rst index 3eccb04a4d6..c50bdf6609a 100644 --- a/doc/admin-guide/files/records.config.en.rst +++ b/doc/admin-guide/files/records.config.en.rst @@ -4350,6 +4350,21 @@ Plug-in Configuration Enables (``1``) or disables (``0``) the dynamic reload feature for remap plugins (`remap.config`). Global plugins (`plugin.config`) do not have dynamic reload feature yet. +.. ts:cv:: CONFIG proxy.config.plugin.vc.default_buffer_index INT 8 + :reloadable: + :overridable: + + Specifies the buffer index and thus size to use when constructing IO buffers within the PluginVC. + Tuning this can impact performance of intercept plugins. Default is 8, which aligns with the + default value of ts:cv:`CONFIG proxy.config.http.default_buffer_size`. + +.. ts:cv:: CONFIG proxy.config.plugin.vc.default_buffer_water_mark INT 0 + :reloadable: + :overridable: + + Specifies the buffer water mark size in bytes used to control the flow of data through IO buffers + within the PluginVC. Default is zero to preserve existing PluginVC water marking behavior. + SOCKS Processor =============== diff --git a/doc/admin-guide/logging/formatting.en.rst b/doc/admin-guide/logging/formatting.en.rst index 7bc46aec568..6ebfa64fe75 100644 --- a/doc/admin-guide/logging/formatting.en.rst +++ b/doc/admin-guide/logging/formatting.en.rst @@ -539,10 +539,12 @@ Field Source Description ===== ================ ============================================================ piid Proxy Plugin Plugin ID for the current transaction. This is set for plugin driven transactions via - :c:func:`TSHttpConnectWithPluginId`. + :c:func:`TSHttpConnectWithPluginId`. or + :c:func:`TSHttpConnectPlugin`. pitag Proxy Plugin Plugin tag for the current transaction. This is set for plugin driven transactions via - :c:func:`TSHttpConnectWithPluginId`. + :c:func:`TSHttpConnectWithPluginId`. or + :c:func:`TSHttpConnectPlugin`. cqint Client Request If a request was generated internally (via a plugin), then this has a value of ``1``, otherwise ``0``. This can be useful when tracking internal only requests, such as those diff --git a/doc/developer-guide/api/functions/TSHttpConnectOptionsGet.en.rst b/doc/developer-guide/api/functions/TSHttpConnectOptionsGet.en.rst new file mode 100644 index 00000000000..c9f57cfb0b1 --- /dev/null +++ b/doc/developer-guide/api/functions/TSHttpConnectOptionsGet.en.rst @@ -0,0 +1,37 @@ +.. Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright + ownership. The ASF licenses this file to you under the Apache + License, Version 2.0 (the "License"); you may not use this file + except in compliance with the License. You may obtain a copy of + the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + +.. include:: ../../../common.defs + +.. default-domain:: c + +TSHttpConnectOptionsGet +*********************** + +Synopsis +======== + +.. code-block:: cpp + + #include + +.. function:: TSHttpConnectOptions TSHttpConnectOptionsGet(TSConnectType connect_type) + +Description +=========== + +Convenience function to obtain a :type:`TSHttpConnectOptions` struct of the given +:type:`TSConnectType` provided in :arg:`connect_type` with default values. diff --git a/doc/developer-guide/api/functions/TSHttpConnectPlugin.en.rst b/doc/developer-guide/api/functions/TSHttpConnectPlugin.en.rst new file mode 100644 index 00000000000..41bdde9db1e --- /dev/null +++ b/doc/developer-guide/api/functions/TSHttpConnectPlugin.en.rst @@ -0,0 +1,89 @@ +.. Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright + ownership. The ASF licenses this file to you under the Apache + License, Version 2.0 (the "License"); you may not use this file + except in compliance with the License. You may obtain a copy of + the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + +.. include:: ../../../common.defs + +.. default-domain:: c + +TSHttpConnectPlugin +************************* + +Allows the plugin to initiate an http connection. This will tag the +HTTP state machine with extra data that can be accessed by the +logging interface. Additional arguments provide buffer settings that +are used when constructing IOBuffers. The connection is treated as +an HTTP transaction as if it came from a client. + +Synopsis +======== + +.. code-block:: cpp + + #include + +.. function:: TSVConn TSHttpConnectPlugin(TSHttpConnectOptions * options); + +Description +=========== + +This call attempts to create an HTTP state machine and a virtual +connection to that state machine. This is more efficient than using +:c:func:`TSNetConnect` because it avoids using the operating system +stack via the loopback interface. + +:arg:`options` + A :c:type:`TSHttpConnectOptions` structure that contains fields + that provide the network address of the target, a tag that can be + passed through to the HTTP state machine, a plugin ID, a buffer + index and buffer water mark. + +The virtual connection returned as the :c:type:`TSVConn` is API +equivalent to a network virtual connection both to the plugin and +to internal mechanisms. Data is read and written to the connection +(and thence to the target system) by reading and writing on this +virtual connection. + +.. note:: + + This function only opens the connection. To drive the transaction an actual + HTTP request must be sent and the HTTP response handled. The transaction is + handled as a standard HTTP transaction and all of the standard configuration + options and plugins will operate on it. + +The combination of :arg:`tag` and :arg:`id` is intended to enable correlation +in log post processing. The :arg:`tag` identifies the connection as related +to the plugin and the :arg:`id` can be used in conjunction with plugin +generated logs to correlate the log records. + +Notes +===== + +The H2 implementation uses this to correlate client sessions +with H2 streams. Each client connection is assigned a distinct +numeric identifier. This is passed in the options structure via +the member variable `id` to the :c:func:`TSHttpConnectPlugin` function. +The :arg:`tag` is selected to be the NPN string for the client session +protocol, e.g. "h2". Log post processing can then count the number of +connections for the various supported protocols and the number of H2 +virtual streams for each real client connection to Traffic Server. + +See Also +======== + +:manpage:`TSHttpConnectWithPluginId(3ts)`, +:manpage:`TSHttpConnect(3ts)`, +:manpage:`TSNetConnect(3ts)`, +:manpage:`TSAPI(3ts)` diff --git a/doc/developer-guide/api/functions/TSHttpConnectWithPluginId.en.rst b/doc/developer-guide/api/functions/TSHttpConnectWithPluginId.en.rst index c291c3859cf..8e35698c4f5 100644 --- a/doc/developer-guide/api/functions/TSHttpConnectWithPluginId.en.rst +++ b/doc/developer-guide/api/functions/TSHttpConnectWithPluginId.en.rst @@ -26,6 +26,13 @@ HTTP state machine with extra data that can be accessed by the logging interface. The connection is treated as an HTTP transaction as if it came from a client. +.. note:: + + This is a convenience function for :c:func:`TSHttpConnectPlugin` to provide + a simpler interface and backward compatibility for existing implementations. + When this function is used instead of `TSHttpConnectPlugin`, default buffer + index and watermark values will be used when creating IOBuffers. + Synopsis ======== @@ -99,6 +106,7 @@ real client connection to Traffic Server. See Also ======== +:manpage:`TSHttpConnectPlugin(3ts)`, :manpage:`TSHttpConnect(3ts)`, :manpage:`TSNetConnect(3ts)`, :manpage:`TSAPI(3ts)` diff --git a/doc/developer-guide/api/functions/TSHttpOverridableConfig.en.rst b/doc/developer-guide/api/functions/TSHttpOverridableConfig.en.rst index 9b7c7b13290..531993390b3 100644 --- a/doc/developer-guide/api/functions/TSHttpOverridableConfig.en.rst +++ b/doc/developer-guide/api/functions/TSHttpOverridableConfig.en.rst @@ -183,6 +183,8 @@ TSOverridableConfigKey Value Config :c:enumerator:`TS_CONFIG_SSL_CLIENT_PRIVATE_KEY_FILENAME` :ts:cv:`proxy.config.ssl.client.private_key.filename` :c:enumerator:`TS_CONFIG_SSL_CLIENT_CA_CERT_FILENAME` :ts:cv:`proxy.config.ssl.client.CA.cert.filename` :c:enumerator:`TS_CONFIG_HTTP_HOST_RESOLUTION_PREFERENCE` :ts:cv:`proxy.config.hostdb.ip_resolve` +:c:enumerator:`TS_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_INDEX` :ts:cv:`proxy.config.plugin.vc.default_buffer_index` +:c:enumerator:`TS_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_WATER_MARK` :ts:cv:`proxy.config.plugin.vc.default_buffer_water_mark` ======================================================================== ==================================================================== Examples diff --git a/doc/developer-guide/api/functions/TSHttpTxnPluginTagGet.en.rst b/doc/developer-guide/api/functions/TSHttpTxnPluginTagGet.en.rst index 5286c277879..78b1d5d46a2 100644 --- a/doc/developer-guide/api/functions/TSHttpTxnPluginTagGet.en.rst +++ b/doc/developer-guide/api/functions/TSHttpTxnPluginTagGet.en.rst @@ -38,5 +38,6 @@ tag is set by the plugin that created the transaction. See also ======== +:manpage:`TSHttpConnectPlugin(3ts)`, :manpage:`TSHttpConnectWithPluginId(3ts)`, :manpage:`TSAPI(3ts)` diff --git a/doc/developer-guide/api/functions/TSPluginVCIOBufferIndexGet.en.rst b/doc/developer-guide/api/functions/TSPluginVCIOBufferIndexGet.en.rst new file mode 100644 index 00000000000..a8dd03cdf0b --- /dev/null +++ b/doc/developer-guide/api/functions/TSPluginVCIOBufferIndexGet.en.rst @@ -0,0 +1,41 @@ +.. Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright + ownership. The ASF licenses this file to you under the Apache + License, Version 2.0 (the "License"); you may not use this file + except in compliance with the License. You may obtain a copy of + the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + +.. include:: ../../../common.defs + +.. default-domain:: c + +TSPluginVCIOBufferIndexGet +************************** + +Synopsis +======== + +.. code-block:: cpp + + #include + +.. function:: TSIOBufferSizeIndex TSPluginVCIOBufferIndexGet(TSHttpTxn txnp) + +Description +=========== + +Convenience function to obtain the current value of the +:ts:cv:`proxy.config.plugin.vc.default_buffer_index` parameter from the +transaction provided in :arg:`txnp`. If no errors are encountered and the +buffer index on the transaction is greater than or equal to the minimum value, +and less than or equal to the maximum value, this value is returned. Otherwise +the default buffer index is returned. diff --git a/doc/developer-guide/api/functions/TSPluginVCIOBufferWaterMarkGet.en.rst b/doc/developer-guide/api/functions/TSPluginVCIOBufferWaterMarkGet.en.rst new file mode 100644 index 00000000000..4e81d099c44 --- /dev/null +++ b/doc/developer-guide/api/functions/TSPluginVCIOBufferWaterMarkGet.en.rst @@ -0,0 +1,40 @@ +.. Licensed to the Apache Software Foundation (ASF) under one or more + contributor license agreements. See the NOTICE file distributed + with this work for additional information regarding copyright + ownership. The ASF licenses this file to you under the Apache + License, Version 2.0 (the "License"); you may not use this file + except in compliance with the License. You may obtain a copy of + the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + +.. include:: ../../../common.defs + +.. default-domain:: c + +TSPluginVCIOBufferWaterMarkGet +****************************** + +Synopsis +======== + +.. code-block:: cpp + + #include + +.. function:: TSIOBufferWaterMark TSPluginVCIOBufferWaterMarkGet(TSHttpTxn txnp) + +Description +=========== + +Convenience function to obtain the current value of the +:ts:cv:`proxy.config.plugin.vc.default_buffer_water_mark` parameter from the +transaction provided in :arg:`txnp`. If no errors are encountered and the +watermark on the transaction is greater than or equal to zero, this value +is returned. Otherwise the default value is returned. diff --git a/doc/developer-guide/api/functions/TSTypes.en.rst b/doc/developer-guide/api/functions/TSTypes.en.rst index 770b909dd8d..d5552c38501 100644 --- a/doc/developer-guide/api/functions/TSTypes.en.rst +++ b/doc/developer-guide/api/functions/TSTypes.en.rst @@ -78,6 +78,42 @@ more widely. Those are described on this page. A 64 bit time value, measured in nanoseconds. +.. type:: TSHttpConnectOptions + + A type that encapsulates options passed into the :func:`TSHttpConnectPlugin` function. + + .. member:: TSConnectType connect_type + + The type of data represented in the struct. + + .. member:: sockaddr const *addr + + Network address of the target of the connection. + + .. member:: const char *tag + + Tag that is passed through to the HTTP state machine. + + .. member:: int64_t id + + Numeric identifier passed through to the HTTP state machine. + + .. member:: TSIOBufferSizeIndex buffer_index + + A numeric buffer size index used to derive actual sizes used when constructing + IOBuffers; see :type:`TSIOBufferSizeIndex`. + + .. member:: TSIOBufferWaterMark buffer_water_mark + + A numeric value specifying the minimum number of bytes that must be written to + an IOBuffer before any continuation is called back to read from the buffer. + See the :c:func:`TSIOBufferWaterMarkGet` and :c:func:`TSIOBufferWaterMarkSet` + functions for further detail. + +.. type:: TSConnectType + + Enumeration that specifies the type of data within a :c:type:`TSHttpConnectOptions` structure. + .. type:: TSHttpParser .. type:: TSHttpSsn @@ -96,6 +132,10 @@ more widely. Those are described on this page. .. type:: TSIOBufferSizeIndex +.. type:: TSIOBufferWaterMark + + An enumeration that contains valid watermark values, currently only defaults. + .. type:: TSLifecycleHookID An enumeration that identifies a :ref:`life cycle hook `. diff --git a/doc/developer-guide/api/types/TSOverridableConfigKey.en.rst b/doc/developer-guide/api/types/TSOverridableConfigKey.en.rst index b29c3e61af3..8e1a919ddc5 100644 --- a/doc/developer-guide/api/types/TSOverridableConfigKey.en.rst +++ b/doc/developer-guide/api/types/TSOverridableConfigKey.en.rst @@ -150,6 +150,8 @@ Enumeration Members .. c:enumerator:: TS_CONFIG_SSL_CLIENT_PRIVATE_KEY_FILENAME .. c:enumerator:: TS_CONFIG_SSL_CLIENT_CA_CERT_FILENAME .. c:enumerator:: TS_CONFIG_HTTP_HOST_RESOLUTION_PREFERENCE +.. c:enumerator:: TS_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_INDEX +.. c:enumerator:: TS_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_WATER_MARK Description diff --git a/include/ts/apidefs.h.in b/include/ts/apidefs.h.in index 698c1c3c53f..63ccd20e20f 100644 --- a/include/ts/apidefs.h.in +++ b/include/ts/apidefs.h.in @@ -643,6 +643,12 @@ typedef enum { TS_IOBUFFER_SIZE_INDEX_2M = 14 } TSIOBufferSizeIndex; +typedef enum { + TS_IOBUFFER_WATER_MARK_UNDEFINED = -1, + TS_IOBUFFER_WATER_MARK_PLUGIN_VC_DEFAULT = 0, // mirror of DEFAULT_PLUGIN_VC_BUFFER_WATER_MARK + TS_IOBUFFER_WATER_MARK_HTTP_DEFAULT = 32768, // mirror of default_buffer_water_mark +} TSIOBufferWaterMark; + typedef enum { TS_ERROR = -1, TS_SUCCESS = 0, @@ -855,6 +861,8 @@ typedef enum { TS_CONFIG_SSL_CLIENT_CA_CERT_FILENAME, TS_CONFIG_HTTP_HOST_RESOLUTION_PREFERENCE, TS_CONFIG_HTTP_CONNECT_DEAD_POLICY, + TS_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_INDEX, + TS_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_WATER_MARK, TS_CONFIG_LAST_ENTRY } TSOverridableConfigKey; @@ -1040,6 +1048,17 @@ typedef struct TSSecretID_s { size_t key_name_len; } TSSecretID; +typedef enum { TS_CONNECT_UNDEFINED, TS_CONNECT_PLUGIN, TS_CONNECT_LAST_ENTRY } TSConnectType; + +typedef struct TSHttpConnectOptions_s { + TSConnectType connect_type; + struct sockaddr const *addr; + const char *tag; + int64_t id; + TSIOBufferSizeIndex buffer_index; + TSIOBufferWaterMark buffer_water_mark; +} TSHttpConnectOptions; + /* -------------------------------------------------------------------------- Init */ diff --git a/include/ts/ts.h b/include/ts/ts.h index af12a7b0d26..1dc9bec0d37 100644 --- a/include/ts/ts.h +++ b/include/ts/ts.h @@ -1775,6 +1775,13 @@ tsapi void TSHttpTxnServerIntercept(TSCont contp, TSHttpTxn txnp); This returns a VConn that connected to the transaction. + @param options a TSHttpConnectPluginOptions structure that specifies options. + */ +tsapi TSVConn TSHttpConnectPlugin(TSHttpConnectOptions *options); + +/** Backwards compatible version. + This function calls This provides a @a buffer_index of 8 and a @a buffer_water_mark of 0. + @param addr Target address of the origin server. @param tag A logging tag that can be accessed via the pitag field. May be @c NULL. @param id A logging id that can be access via the piid field. @@ -1786,6 +1793,21 @@ tsapi TSVConn TSHttpConnectWithPluginId(struct sockaddr const *addr, const char */ tsapi TSVConn TSHttpConnect(struct sockaddr const *addr); +/** + Get an instance of TSHttpConnectOptions with default values. + */ +tsapi TSHttpConnectOptions TSHttpConnectOptionsGet(TSConnectType connect_type); + +/** + Get the value of proxy.config.plugin.vc.default_buffer_index from the TSHttpTxn + */ +tsapi TSIOBufferSizeIndex TSPluginVCIOBufferIndexGet(TSHttpTxn txnp); + +/** + Get the value of proxy.config.plugin.vc.default_buffer_water_mark from the TSHttpTxn + */ +tsapi TSIOBufferWaterMark TSPluginVCIOBufferWaterMarkGet(TSHttpTxn txnp); + /* -------------------------------------------------------------------------- Initiate Transparent Http Connection */ /** diff --git a/iocore/eventsystem/I_IOBuffer.h b/iocore/eventsystem/I_IOBuffer.h index c3acde99dac..640b8b33675 100644 --- a/iocore/eventsystem/I_IOBuffer.h +++ b/iocore/eventsystem/I_IOBuffer.h @@ -63,6 +63,7 @@ enum AllocType { #define MAX_MIOBUFFER_READERS 5 #define DEFAULT_BUFFER_ALIGNMENT 8192 // should be disk/page size #define DEFAULT_BUFFER_BASE_SIZE 128 +#define DEFAULT_PLUGIN_VC_BUFFER_WATER_MARK 0 // ensure we retain existing behavior //////////////////////////////////////////////// // These are defines so that code that used 2 // diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc index ad29c08506a..60233fedc82 100644 --- a/mgmt/RecordsConfig.cc +++ b/mgmt/RecordsConfig.cc @@ -386,6 +386,10 @@ static const RecordElement RecordsConfig[] = , {RECT_CONFIG, "proxy.config.http.default_buffer_water_mark", RECD_INT, "32768", RECU_DYNAMIC, RR_NULL, RECC_NULL, nullptr, RECA_NULL} , + {RECT_CONFIG, "proxy.config.plugin.vc.default_buffer_index", RECD_INT, "8", RECU_DYNAMIC, RR_NULL, RECC_STR, "^([0-9]|1[0-4])$", RECA_NULL} + , + {RECT_CONFIG, "proxy.config.plugin.vc.default_buffer_water_mark", RECD_INT, "0", RECU_DYNAMIC, RR_NULL, RECC_STR, "^[0-9]+$", RECA_NULL} + , {RECT_CONFIG, "proxy.config.http.enable_http_info", RECD_INT, "0", RECU_DYNAMIC, RR_NULL, RECC_NULL, nullptr, RECA_NULL} , {RECT_CONFIG, "proxy.config.http.server_max_connections", RECD_INT, "0", RECU_DYNAMIC, RR_NULL, RECC_STR, "^[0-9]+$", RECA_NULL} diff --git a/plugins/lua/ts_lua_http_config.c b/plugins/lua/ts_lua_http_config.c index 2d384c067e1..6ad8de00a01 100644 --- a/plugins/lua/ts_lua_http_config.c +++ b/plugins/lua/ts_lua_http_config.c @@ -137,6 +137,8 @@ typedef enum { TS_LUA_CONFIG_SSL_CLIENT_PRIVATE_KEY_FILENAME = TS_CONFIG_SSL_CLIENT_PRIVATE_KEY_FILENAME, TS_LUA_CONFIG_SSL_CLIENT_CA_CERT_FILENAME = TS_CONFIG_SSL_CLIENT_CA_CERT_FILENAME, TS_LUA_CONFIG_HTTP_HOST_RESOLUTION_PREFERENCE = TS_CONFIG_HTTP_HOST_RESOLUTION_PREFERENCE, + TS_LUA_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_INDEX = TS_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_INDEX, + TS_LUA_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_WATER_MARK = TS_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_WATER_MARK, TS_LUA_CONFIG_LAST_ENTRY = TS_CONFIG_LAST_ENTRY, } TSLuaOverridableConfigKey; @@ -266,6 +268,8 @@ ts_lua_var_item ts_lua_http_config_vars[] = { TS_LUA_MAKE_VAR_ITEM(TS_CONFIG_HTTP_SERVER_MIN_KEEP_ALIVE_CONNS), TS_LUA_MAKE_VAR_ITEM(TS_LUA_CONFIG_HTTP_PER_SERVER_CONNECTION_MAX), TS_LUA_MAKE_VAR_ITEM(TS_LUA_CONFIG_HTTP_PER_SERVER_CONNECTION_MATCH), + TS_LUA_MAKE_VAR_ITEM(TS_LUA_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_INDEX), + TS_LUA_MAKE_VAR_ITEM(TS_LUA_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_WATER_MARK), TS_LUA_MAKE_VAR_ITEM(TS_LUA_CONFIG_LAST_ENTRY), }; diff --git a/proxy/PluginVC.cc b/proxy/PluginVC.cc index adb0eafb468..87a8fe8171b 100644 --- a/proxy/PluginVC.cc +++ b/proxy/PluginVC.cc @@ -77,7 +77,6 @@ #include "tscore/Regression.h" #define PVC_LOCK_RETRY_TIME HRTIME_MSECONDS(10) -#define PVC_DEFAULT_MAX_BYTES 32768 #define MIN_BLOCK_TRANSFER_BYTES 128 #define PVC_TYPE ((vc_type == PLUGIN_VC_ACTIVE) ? "Active" : "Passive") @@ -511,7 +510,7 @@ PluginVC::process_write_side(bool other_side_call) // Bytes available, try to transfer to the PluginVCCore // intermediate buffer // - int64_t buf_space = PVC_DEFAULT_MAX_BYTES - core_buffer->max_read_avail(); + int64_t buf_space = core_obj->buffer_size - core_buffer->max_read_avail(); if (buf_space <= 0) { Debug("pvc", "[%u] %s: process_write_side no buffer space", core_obj->id, PVC_TYPE); return; @@ -522,7 +521,7 @@ PluginVC::process_write_side(bool other_side_call) if (added < 0) { // Couldn't actually get the buffer space. This only // happens on small transfers with the above - // PVC_DEFAULT_MAX_BYTES factor doesn't apply + // buffer_size factor doesn't apply Debug("pvc", "[%u] %s: process_write_side out of buffer space", core_obj->id, PVC_TYPE); return; } @@ -632,7 +631,7 @@ PluginVC::process_read_side(bool other_side_call) MIOBuffer *output_buffer = read_state.vio.get_writer(); int64_t water_mark = output_buffer->water_mark; - water_mark = std::max(water_mark, static_cast(PVC_DEFAULT_MAX_BYTES)); + water_mark = std::max(water_mark, static_cast(core_obj->buffer_size)); int64_t buf_space = water_mark - output_buffer->max_read_avail(); if (buf_space <= 0) { Debug("pvc", "[%u] %s: process_read_side no buffer space", core_obj->id, PVC_TYPE); @@ -644,7 +643,7 @@ PluginVC::process_read_side(bool other_side_call) if (added <= 0) { // Couldn't actually get the buffer space. This only // happens on small transfers with the above - // PVC_DEFAULT_MAX_BYTES factor doesn't apply + // buffer_size factor doesn't apply Debug("pvc", "[%u] %s: process_read_side out of buffer space", core_obj->id, PVC_TYPE); return; } @@ -1054,16 +1053,16 @@ int32_t PluginVCCore::nextid; PluginVCCore::~PluginVCCore() = default; PluginVCCore * -PluginVCCore::alloc(Continuation *acceptor) +PluginVCCore::alloc(Continuation *acceptor, int64_t buffer_index, int64_t buffer_water_mark) { PluginVCCore *pvc = new PluginVCCore; - pvc->init(); + pvc->init(buffer_index, buffer_water_mark); pvc->connect_to = acceptor; return pvc; } void -PluginVCCore::init() +PluginVCCore::init(int64_t buffer_index, int64_t buffer_water_mark) { mutex = new_ProxyMutex(); @@ -1079,13 +1078,20 @@ PluginVCCore::init() passive_vc.mutex = mutex; passive_vc.thread = active_vc.thread; - p_to_a_buffer = new_MIOBuffer(BUFFER_SIZE_INDEX_32K); - p_to_a_reader = p_to_a_buffer->alloc_reader(); + p_to_a_buffer = new_MIOBuffer(buffer_index); + p_to_a_buffer->water_mark = buffer_water_mark; + p_to_a_reader = p_to_a_buffer->alloc_reader(); - a_to_p_buffer = new_MIOBuffer(BUFFER_SIZE_INDEX_32K); - a_to_p_reader = a_to_p_buffer->alloc_reader(); + a_to_p_buffer = new_MIOBuffer(buffer_index); + a_to_p_buffer->water_mark = buffer_water_mark; + a_to_p_reader = a_to_p_buffer->alloc_reader(); - Debug("pvc", "[%u] Created PluginVCCore at %p, active %p, passive %p", id, this, &active_vc, &passive_vc); + buffer_size = BUFFER_SIZE_FOR_INDEX(buffer_index); + + Debug("pvc", + "[%u] Created PluginVCCore at %p, active %p, passive %p, buffer_index %" PRId64 ", buffer_size %" PRId64 + ", buffer_water_mark %" PRId64, + id, this, &active_vc, &passive_vc, buffer_index, buffer_size, buffer_water_mark); } void @@ -1341,7 +1347,7 @@ PVCTestDriver::run_next_test() NetVCTest *p = new NetVCTest; NetVCTest *a = new NetVCTest; - PluginVCCore *core = PluginVCCore::alloc(p); + PluginVCCore *core = PluginVCCore::alloc(p, BUFFER_SIZE_INDEX_32K); p->init_test(NET_VC_TEST_PASSIVE, this, nullptr, r, &netvc_tests_def[p_index], "PluginVC", "pvc_test_detail"); PluginVC *a_vc = core->connect(); diff --git a/proxy/PluginVC.h b/proxy/PluginVC.h index cb0460de0b2..46058432839 100644 --- a/proxy/PluginVC.h +++ b/proxy/PluginVC.h @@ -203,7 +203,8 @@ class PluginVCCore : public Continuation // Allocate a PluginVCCore object, passing the continuation which // will receive NET_EVENT_ACCEPT to accept the new session. - static PluginVCCore *alloc(Continuation *acceptor); + static PluginVCCore *alloc(Continuation *acceptor, int64_t buffer_index = BUFFER_SIZE_INDEX_32K, + int64_t buffer_water_mark = DEFAULT_PLUGIN_VC_BUFFER_WATER_MARK); int state_send_accept(int event, void *data); int state_send_accept_failed(int event, void *data); @@ -246,7 +247,7 @@ class PluginVCCore : public Continuation PluginVC passive_vc; private: - void init(); + void init(int64_t buffer_index = BUFFER_SIZE_INDEX_32K, int64_t buffer_water_mark = DEFAULT_PLUGIN_VC_BUFFER_WATER_MARK); void destroy(); Continuation *connect_to = nullptr; @@ -266,6 +267,8 @@ class PluginVCCore : public Continuation static int32_t nextid; unsigned id = 0; + + uint64_t buffer_size = BUFFER_SIZE_FOR_INDEX(BUFFER_SIZE_INDEX_32K); }; inline PluginVCCore::PluginVCCore() : active_vc(this), passive_vc(this) diff --git a/proxy/http/HttpConfig.cc b/proxy/http/HttpConfig.cc index b503eea991b..79ba53262ce 100644 --- a/proxy/http/HttpConfig.cc +++ b/proxy/http/HttpConfig.cc @@ -1359,6 +1359,11 @@ HttpConfig::startup() HttpEstablishStaticConfigLongLong(c.oride.default_buffer_size_index, "proxy.config.http.default_buffer_size"); HttpEstablishStaticConfigLongLong(c.oride.default_buffer_water_mark, "proxy.config.http.default_buffer_water_mark"); + // Plugin VC buffer size and watermark + HttpEstablishStaticConfigLongLong(c.oride.plugin_vc_default_buffer_index, "proxy.config.plugin.vc.default_buffer_index"); + HttpEstablishStaticConfigLongLong(c.oride.plugin_vc_default_buffer_water_mark, + "proxy.config.plugin.vc.default_buffer_water_mark"); + // Stat Page Info HttpEstablishStaticConfigByte(c.enable_http_info, "proxy.config.http.enable_http_info"); @@ -1661,6 +1666,9 @@ HttpConfig::reconfigure() params->oride.host_res_data = m_master.oride.host_res_data; params->oride.host_res_data.conf_value = ats_strdup(m_master.oride.host_res_data.conf_value); + params->oride.plugin_vc_default_buffer_index = m_master.oride.plugin_vc_default_buffer_index; + params->oride.plugin_vc_default_buffer_water_mark = m_master.oride.plugin_vc_default_buffer_water_mark; + m_id = configProcessor.set(m_id, params); } diff --git a/proxy/http/HttpConfig.h b/proxy/http/HttpConfig.h index 186a6584fcc..1deab81f83a 100644 --- a/proxy/http/HttpConfig.h +++ b/proxy/http/HttpConfig.h @@ -697,6 +697,9 @@ struct OverridableHttpConfigParams { OutboundConnTrack::TxnConfig outbound_conntrack; + MgmtInt plugin_vc_default_buffer_index = BUFFER_SIZE_INDEX_32K; + MgmtInt plugin_vc_default_buffer_water_mark = DEFAULT_PLUGIN_VC_BUFFER_WATER_MARK; + /////////////////////////////////////////////////////////////////// // Server header // /////////////////////////////////////////////////////////////////// diff --git a/src/shared/overridable_txn_vars.cc b/src/shared/overridable_txn_vars.cc index 598f508b5a2..7a66a6d5e7d 100644 --- a/src/shared/overridable_txn_vars.cc +++ b/src/shared/overridable_txn_vars.cc @@ -160,4 +160,6 @@ const std::unordered_mapplugin_tag; } +TSHttpConnectOptions +TSHttpConnectOptionsGet(TSConnectType connect_type) +{ + sdk_assert(connect_type > TS_CONNECT_UNDEFINED); + sdk_assert(connect_type < TS_CONNECT_LAST_ENTRY); + + return TSHttpConnectOptions{.connect_type = connect_type, + .addr = nullptr, + .tag = nullptr, + .id = 0, + .buffer_index = TS_IOBUFFER_SIZE_INDEX_32K, + .buffer_water_mark = TS_IOBUFFER_WATER_MARK_PLUGIN_VC_DEFAULT}; +} + TSVConn TSHttpConnectWithPluginId(sockaddr const *addr, const char *tag, int64_t id) { - sdk_assert(addr); + TSHttpConnectOptions options = TSHttpConnectOptionsGet(TS_CONNECT_PLUGIN); + options.addr = addr; + options.tag = tag; + options.id = id; - sdk_assert(ats_is_ip(addr)); - sdk_assert(ats_ip_port_cast(addr)); + return TSHttpConnectPlugin(&options); +} + +TSVConn +TSHttpConnectPlugin(TSHttpConnectOptions *options) +{ + sdk_assert(options != nullptr); + sdk_assert(options->connect_type == TS_CONNECT_PLUGIN); + sdk_assert(options->addr); + + sdk_assert(ats_is_ip(options->addr)); + sdk_assert(ats_ip_port_cast(options->addr)); + + if (options->buffer_index < TS_IOBUFFER_SIZE_INDEX_128 || options->buffer_index > MAX_BUFFER_SIZE_INDEX) { + options->buffer_index = TS_IOBUFFER_SIZE_INDEX_32K; // out of range, set to the default for safety + } + + if (options->buffer_water_mark < TS_IOBUFFER_WATER_MARK_PLUGIN_VC_DEFAULT) { + options->buffer_water_mark = TS_IOBUFFER_WATER_MARK_PLUGIN_VC_DEFAULT; + } if (plugin_http_accept) { - PluginVCCore *new_pvc = PluginVCCore::alloc(plugin_http_accept); + PluginVCCore *new_pvc = PluginVCCore::alloc(plugin_http_accept, options->buffer_index, options->buffer_water_mark); - new_pvc->set_active_addr(addr); - new_pvc->set_plugin_id(id); - new_pvc->set_plugin_tag(tag); + new_pvc->set_active_addr(options->addr); + new_pvc->set_plugin_id(options->id); + new_pvc->set_plugin_tag(options->tag); PluginVC *return_vc = new_pvc->connect(); @@ -7215,8 +7250,11 @@ TSHttpTxnServerIntercept(TSCont contp, TSHttpTxn txnp) sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS); sdk_assert(sdk_sanity_check_continuation(contp) == TS_SUCCESS); + TSIOBufferSizeIndex buffer_index = TSPluginVCIOBufferIndexGet(txnp); + TSIOBufferWaterMark buffer_water_mark = TSPluginVCIOBufferWaterMarkGet(txnp); + http_sm->plugin_tunnel_type = HTTP_PLUGIN_AS_SERVER; - http_sm->plugin_tunnel = PluginVCCore::alloc((INKContInternal *)contp); + http_sm->plugin_tunnel = PluginVCCore::alloc((INKContInternal *)contp, buffer_index, buffer_water_mark); } void @@ -7227,8 +7265,37 @@ TSHttpTxnIntercept(TSCont contp, TSHttpTxn txnp) sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS); sdk_assert(sdk_sanity_check_continuation(contp) == TS_SUCCESS); + TSIOBufferSizeIndex buffer_index = TSPluginVCIOBufferIndexGet(txnp); + TSIOBufferWaterMark buffer_water_mark = TSPluginVCIOBufferWaterMarkGet(txnp); + http_sm->plugin_tunnel_type = HTTP_PLUGIN_AS_INTERCEPT; - http_sm->plugin_tunnel = PluginVCCore::alloc((INKContInternal *)contp); + http_sm->plugin_tunnel = PluginVCCore::alloc((INKContInternal *)contp, buffer_index, buffer_water_mark); +} + +TSIOBufferSizeIndex +TSPluginVCIOBufferIndexGet(TSHttpTxn txnp) +{ + TSMgmtInt index; + + if (TSHttpTxnConfigIntGet(txnp, TS_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_INDEX, &index) == TS_SUCCESS && + index >= TS_IOBUFFER_SIZE_INDEX_128 && index <= MAX_BUFFER_SIZE_INDEX) { + return static_cast(index); + } + + return TS_IOBUFFER_SIZE_INDEX_32K; +} + +TSIOBufferWaterMark +TSPluginVCIOBufferWaterMarkGet(TSHttpTxn txnp) +{ + TSMgmtInt water_mark; + + if (TSHttpTxnConfigIntGet(txnp, TS_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_WATER_MARK, &water_mark) == TS_SUCCESS && + water_mark > TS_IOBUFFER_WATER_MARK_UNDEFINED) { + return static_cast(water_mark); + } + + return TS_IOBUFFER_WATER_MARK_PLUGIN_VC_DEFAULT; } // The API below require timer values as TSHRTime parameters @@ -8804,6 +8871,12 @@ _conf_to_memberp(TSOverridableConfigKey conf, OverridableHttpConfigParams *overr ret = &overridableHttpConfig->host_res_data; conv = &HttpTransact::HOST_RES_CONV; break; + case TS_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_INDEX: + ret = _memberp_to_generic(&overridableHttpConfig->plugin_vc_default_buffer_index, conv); + break; + case TS_CONFIG_PLUGIN_VC_DEFAULT_BUFFER_WATER_MARK: + ret = _memberp_to_generic(&overridableHttpConfig->plugin_vc_default_buffer_water_mark, conv); + break; // This helps avoiding compiler warnings, yet detect unhandled enum members. case TS_CONFIG_NULL: case TS_CONFIG_LAST_ENTRY: diff --git a/src/traffic_server/InkAPITest.cc b/src/traffic_server/InkAPITest.cc index af0374eca9f..5892386740c 100644 --- a/src/traffic_server/InkAPITest.cc +++ b/src/traffic_server/InkAPITest.cc @@ -8694,7 +8694,9 @@ std::array SDK_Overridable_Configs = { "proxy.config.ssl.client.private_key.filename", "proxy.config.ssl.client.CA.cert.filename", "proxy.config.hostdb.ip_resolve", - "proxy.config.http.connect.dead.policy"}}; + "proxy.config.http.connect.dead.policy", + "proxy.config.plugin.vc.default_buffer_index", + "proxy.config.plugin.vc.default_buffer_water_mark"}}; REGRESSION_TEST(SDK_API_OVERRIDABLE_CONFIGS)(RegressionTest *test, int /* atype ATS_UNUSED */, int *pstatus) {