1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-14 10:13:05 +02:00

Set TCP keepalives on S3 connections.

Keepalives may help in situations where RST packets are being blocked by a firewall or otherwise do not arrive.

The C code uses select on all reads so it should never block, but add keepalives just in case.

Suggested by Ronan Dunklau.
This commit is contained in:
David Steele 2018-12-18 22:12:59 +02:00
parent 96028073cb
commit 23b583336f
4 changed files with 38 additions and 2 deletions

View File

@ -45,6 +45,14 @@
</release-bug-list>
<release-improvement-list>
<release-item>
<release-item-contributor-list>
<release-item-ideator id="ronan.dunklau"/>
</release-item-contributor-list>
<p>Set TCP keepalives on <proper>S3</proper> connections.</p>
</release-item>
<release-item>
<release-item-contributor-list>
<release-item-ideator id="ryan.lambert"/>

View File

@ -12,6 +12,7 @@ use English '-no_match_vars';
use Exporter qw(import);
our @EXPORT = qw();
use IO::Socket::SSL;
use Socket qw(SOL_SOCKET SO_KEEPALIVE);
use pgBackRest::Common::Exception;
use pgBackRest::Common::Io::Buffered;
@ -100,7 +101,7 @@ sub new
{
$oSocket = IO::Socket::SSL->new(
PeerHost => $strHost, PeerPort => $iPort, SSL_verify_mode => $bVerifySsl ? SSL_VERIFY_PEER : SSL_VERIFY_NONE,
SSL_ca_path => $strCaPath, SSL_ca_file => $strCaFile);
SSL_ca_path => $strCaPath, SSL_ca_file => $strCaFile, Sockopts => [[SOL_SOCKET, SO_KEEPALIVE]]);
return 1;
}

View File

@ -307,6 +307,32 @@ tlsClientOpen(TlsClient *this)
if (connect(this->socket, (struct sockaddr *)&socketAddr, sizeof(socketAddr)) == -1)
THROW_SYS_ERROR_FMT(FileOpenError, "unable to connect to '%s:%u'", strPtr(this->host), this->port);
// Enable TCP keepalives
int socketValue = 1;
THROW_ON_SYS_ERROR(
setsockopt(this->socket, SOL_SOCKET, SO_KEEPALIVE, &socketValue, sizeof(int)) == -1, ProtocolError,
"unable set SO_KEEPALIVE");
// Set per-connection keepalive options if they are available
#ifdef TCP_KEEPIDLE
socketValue = 3;
THROW_ON_SYS_ERROR(
setsockopt(this->socket, SOL_SOCKET, TCP_KEEPIDLE, &socketValue, sizeof(int)) == -1, ProtocolError,
"unable set SO_KEEPIDLE");
THROW_ON_SYS_ERROR(
setsockopt(this->socket, SOL_SOCKET, TCP_KEEPINTVL, &socketValue, sizeof(int)) == -1, ProtocolError,
"unable set SO_KEEPINTVL");
socketValue = this->timeout / socketValue;
THROW_ON_SYS_ERROR(
setsockopt(this->socket, SOL_SOCKET, TCP_KEEPCNT, &socketValue, sizeof(int)) == -1, ProtocolError,
"unable set SO_KEEPCNT");
#endif
// Negotiate TLS
cryptoError((this->session = SSL_new(this->context)) == NULL, "unable to create TLS context");

View File

@ -5253,6 +5253,7 @@ static const EmbeddedModule embeddedModule[] =
"use Exporter qw(import);\n"
"our @EXPORT = qw();\n"
"use IO::Socket::SSL;\n"
"use Socket qw(SOL_SOCKET SO_KEEPALIVE);\n"
"\n"
"use pgBackRest::Common::Exception;\n"
"use pgBackRest::Common::Io::Buffered;\n"
@ -5333,7 +5334,7 @@ static const EmbeddedModule embeddedModule[] =
"{\n"
"$oSocket = IO::Socket::SSL->new(\n"
"PeerHost => $strHost, PeerPort => $iPort, SSL_verify_mode => $bVerifySsl ? SSL_VERIFY_PEER : SSL_VERIFY_NONE,\n"
"SSL_ca_path => $strCaPath, SSL_ca_file => $strCaFile);\n"
"SSL_ca_path => $strCaPath, SSL_ca_file => $strCaFile, Sockopts => [[SOL_SOCKET, SO_KEEPALIVE]]);\n"
"\n"
"return 1;\n"
"}\n"