Skip to content

Commit

Permalink
cloud_storage: add handling for GnuTLS system_errors
Browse files Browse the repository at this point in the history
These are a proxy for underlying connection issues, e.g.
- "error GnuTLS:-110, The TLS connection was non-properly terminated."
- "error GnuTLS:-53, Error in the push function."

Treat them as retryable the same way we do other transient
network errors when communicating with an S3 endpoint.
  • Loading branch information
jcsp committed Sep 26, 2022
1 parent c4b4fe3 commit 201886c
Showing 1 changed file with 29 additions and 10 deletions.
39 changes: 29 additions & 10 deletions src/v/cloud_storage/remote.cc
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <boost/beast/http/error.hpp>
#include <boost/beast/http/field.hpp>
#include <fmt/chrono.h>
#include <gnutls/gnutls.h>

#include <exception>
#include <utility>
Expand All @@ -47,20 +48,38 @@ enum class error_outcome {
notfound
};

/**
* Identify error cases that should be quickly retried, e.g.
* TCP disconnects, timeouts. Network errors may also show up
* indirectly as errors from the TLS layer.
*/
bool system_error_retryable(const std::system_error& e) {
auto v = e.code().value();

switch (v) {
case ECONNREFUSED:
case ENETUNREACH:
case ETIMEDOUT:
case ECONNRESET:
case EPIPE:
return true;
default:
return false;
// The name() of seastar's gnutls_error_category class
constexpr std::string_view gnutls_cateogry_name{"GnuTLS"};

if (e.code().category().name() == gnutls_cateogry_name) {
switch (v) {
case GNUTLS_E_PUSH_ERROR:
case GNUTLS_E_PULL_ERROR:
case GNUTLS_E_PREMATURE_TERMINATION:
return true;
default:
return false;
}
} else {
switch (v) {
case ECONNREFUSED:
case ENETUNREACH:
case ETIMEDOUT:
case ECONNRESET:
case EPIPE:
return true;
default:
return false;
}
}

__builtin_unreachable();
}

Expand Down

0 comments on commit 201886c

Please sign in to comment.