Skip to content

Commit

Permalink
APIs to get the h2 error codes and a plugin to use them (#10571)
Browse files Browse the repository at this point in the history
  • Loading branch information
bryancall committed Oct 9, 2023
1 parent de7c8a7 commit a49e575
Show file tree
Hide file tree
Showing 10 changed files with 545 additions and 1 deletion.
73 changes: 73 additions & 0 deletions doc/admin-guide/plugins/block_errors.en.rst
@@ -0,0 +1,73 @@
.. 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
.. _admin-plugins-block_errors:

Block Errors Plugin
*******************

Description
===========
The `block_errors` plugin blocks connections or downgrades the protocol from HTTP/2 to HTTP/1.1 for clients that have too many HTTP/2 errors on the server.

The plugin tracks users based on their IP address and blocks them for a configurable amount of time. `block_errors` can be configured to either block or downgrade the protocol, only use HTTP/1.1, for any new connections.
The existing connection that experience errors and is over the error limit will be closed. The plugin also supports on the fly configuration changes using the `traffic_ctl` command.


Configuration
=============

To enable the `block_errors` plugin, insert the following line in :file:`plugin.config`:

block_errors.so

Additional configuration options are available and can be set in :file:`plugin.config`:

block_errors.so <error limit> <timeout> <shutdown> <enable>

- ``error limit``: The number of errors allowed before blocking the client. Default: 1000 (per minute)
- ``timeout``: The time in minutes to block the client. Default: 4 (minutes)
- ``shutdown``: Shutdown (1) or downgrade (0) the protocol for new connections. Default: 0 (downgrade to HTTP/1.1)
- ``enable``: Enable (1) or disable (0) the plugin. Default: 1 (enabled)

Example Configuration
=====================

block_errors.so 1000 4 0 1

Run Time Configuration
======================
The plugin can be configured at run time using the `traffic_ctl` command. The following commands are available:

- ``block_errors.error_limit``: Set the error limit. Takes a single argument, the number of errors allowed before blocking the client.
- ``block_errors.timeout``: Set the block timeout. Takes a single argument, the number of minutes to block the client.
- ``block_errors.shutdown``: Set the shutdown mode. Takes a single argument, 0 to downgrade to HTTP/1.1, 1 to close the connection.
- ``block_errors.enable``: Enable or disable the plugin. Takes a single argument, 0 to disable, 1 to enable.

Example Run Time Configuration
==============================

traffic_ctl plugin msg block_errors.error_limit 10000

traffic_ctl plugin msg block_errors.timeout 10

traffic_ctl plugin msg block_errors.shutdown 1

traffic_ctl plugin msg block_errors.enable 1
4 changes: 4 additions & 0 deletions doc/admin-guide/plugins/index.en.rst
Expand Up @@ -151,6 +151,7 @@ directory of the |TS| source tree. Experimental plugins can be compiled by passi
:hidden:

Access Control <access_control.en>
Block Errors <block_errors.en>
Cache Fill <cache_fill.en>
Certifier <certifier.en>
Cert Reporting Tool <cert_reporting_tool.en>
Expand Down Expand Up @@ -187,6 +188,9 @@ directory of the |TS| source tree. Experimental plugins can be compiled by passi
:doc:`Access Control <access_control.en>`
Access control plugin that handles various access control use-cases.

:doc:`Block Errors <block_errors.en>`
Blocks or downgrades new connections when the server receives too many errors from an IP address.

:doc:`Certifier <certifier.en>`
Manages and/or generates certificates for incoming HTTPS requests.

Expand Down
36 changes: 36 additions & 0 deletions include/ts/ts.h
Expand Up @@ -2663,6 +2663,42 @@ tsapi void TSHttpTxnResponseActionGet(TSHttpTxn txnp, TSResponseAction *action);
*/
tsapi TSIOBufferReader TSHttpTxnPostBufferReaderGet(TSHttpTxn txnp);

/**
* @brief Get the client error received from the transaction
*
* @param txnp The transaction where the error code is stored
* @param error_class Either session/connection or stream/transaction error
* @param error_code Error code received from the client
*/
void TSHttpTxnClientReceivedErrorGet(TSHttpTxn txnp, uint32_t *error_class, uint64_t *error_code);

/**
* @brief Get the client error sent from the transaction
*
* @param txnp The transaction where the error code is stored
* @param error_class Either session/connection or stream/transaction error
* @param error_code Error code sent to the client
*/
void TSHttpTxnClientSentErrorGet(TSHttpTxn txnp, uint32_t *error_class, uint64_t *error_code);

/**
* @brief Get the server error received from the transaction
*
* @param txnp The transaction where the error code is stored
* @param error_class Either session/connection or stream/transaction error
* @param error_code Error code sent from the server
*/
void TSHttpTxnServerReceivedErrorGet(TSHttpTxn txnp, uint32_t *error_class, uint64_t *error_code);

/**
* @brief Get the server error sent from the transaction
*
* @param txnp The transaction where the error code is stored
* @param error_class Either session/connection or stream/transaction error
* @param error_code Error code sent to the server
*/
void TSHttpTxnServerSentErrorGet(TSHttpTxn txnp, uint32_t *error_class, uint64_t *error_code);

/**
* Initiate an HTTP/2 Server Push preload request.
* Use this api to register a URL that you want to preload with HTTP/2 Server Push.
Expand Down
26 changes: 26 additions & 0 deletions include/tscore/ink_inet.h
Expand Up @@ -1268,6 +1268,7 @@ struct IpAddr {
- Else: 0.
*/
uint32_t hash() const;
uint64_t hash64() const;

/** The hashing function embedded in a functor.
@see hash
Expand Down Expand Up @@ -1476,6 +1477,18 @@ IpAddr::hash() const
return zret;
}

inline uint64_t
IpAddr::hash64() const
{
uint64_t zret = 0;
if (this->isIp4()) {
zret = ntohl(_addr._ip4);
} else if (this->isIp6()) {
zret = _addr._u64[0] ^ _addr._u64[1];
}
return zret;
}

/// Write IP @a addr to storage @a dst.
/// @return @s dst.
sockaddr *ats_ip_set(sockaddr *dst, ///< Destination storage.
Expand Down Expand Up @@ -1611,3 +1624,16 @@ namespace bwf
detail::MemDump Hex_Dump(IpEndpoint const &addr);
} // namespace bwf
} // namespace ts

namespace std
{
/// Standard hash support for @a IPAddr.
template <> struct hash<IpAddr> {
size_t
operator()(IpAddr const &addr) const
{
return addr.hash64();
}
};

} // namespace std
1 change: 1 addition & 0 deletions plugins/Makefile.am
Expand Up @@ -61,6 +61,7 @@ if BUILD_EXPERIMENTAL_PLUGINS

include experimental/access_control/Makefile.inc
include experimental/acme/Makefile.inc
include experimental/block_errors/Makefile.inc
include experimental/cache_fill/Makefile.inc
include experimental/cert_reporting_tool/Makefile.inc
include experimental/collapsed_forwarding/Makefile.inc
Expand Down
22 changes: 22 additions & 0 deletions plugins/experimental/block_errors/CMakeLists.txt
@@ -0,0 +1,22 @@
#######################
#
# 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.
#
#######################

project(block_errors)

add_atsplugin(block_errors
block_errors.cc
)
20 changes: 20 additions & 0 deletions plugins/experimental/block_errors/Makefile.inc
@@ -0,0 +1,20 @@
# 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.

pkglib_LTLIBRARIES += experimental/block_errors/block_errors.la

experimental_block_errors_block_errors_la_SOURCES = \
experimental/block_errors/block_errors.cc

0 comments on commit a49e575

Please sign in to comment.