Merge pull request #2575 from etschannen/feature-wait-handshake

Wait for TLS handshake to return before accepting a connection
This commit is contained in:
Evan Tschannen 2020-01-21 19:07:26 -08:00 committed by GitHub
commit a9eede7bc4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 53 additions and 23 deletions

View File

@ -10,38 +10,38 @@ macOS
The macOS installation package is supported on macOS 10.7+. It includes the client and (optionally) the server.
* `FoundationDB-6.2.14.pkg <https://www.foundationdb.org/downloads/6.2.14/macOS/installers/FoundationDB-6.2.14.pkg>`_
* `FoundationDB-6.2.15.pkg <https://www.foundationdb.org/downloads/6.2.15/macOS/installers/FoundationDB-6.2.15.pkg>`_
Ubuntu
------
The Ubuntu packages are supported on 64-bit Ubuntu 12.04+, but beware of the Linux kernel bug in Ubuntu 12.x.
* `foundationdb-clients-6.2.14-1_amd64.deb <https://www.foundationdb.org/downloads/6.2.14/ubuntu/installers/foundationdb-clients_6.2.14-1_amd64.deb>`_
* `foundationdb-server-6.2.14-1_amd64.deb <https://www.foundationdb.org/downloads/6.2.14/ubuntu/installers/foundationdb-server_6.2.14-1_amd64.deb>`_ (depends on the clients package)
* `foundationdb-clients-6.2.15-1_amd64.deb <https://www.foundationdb.org/downloads/6.2.15/ubuntu/installers/foundationdb-clients_6.2.15-1_amd64.deb>`_
* `foundationdb-server-6.2.15-1_amd64.deb <https://www.foundationdb.org/downloads/6.2.15/ubuntu/installers/foundationdb-server_6.2.15-1_amd64.deb>`_ (depends on the clients package)
RHEL/CentOS EL6
---------------
The RHEL/CentOS EL6 packages are supported on 64-bit RHEL/CentOS 6.x.
* `foundationdb-clients-6.2.14-1.el6.x86_64.rpm <https://www.foundationdb.org/downloads/6.2.14/rhel6/installers/foundationdb-clients-6.2.14-1.el6.x86_64.rpm>`_
* `foundationdb-server-6.2.14-1.el6.x86_64.rpm <https://www.foundationdb.org/downloads/6.2.14/rhel6/installers/foundationdb-server-6.2.14-1.el6.x86_64.rpm>`_ (depends on the clients package)
* `foundationdb-clients-6.2.15-1.el6.x86_64.rpm <https://www.foundationdb.org/downloads/6.2.15/rhel6/installers/foundationdb-clients-6.2.15-1.el6.x86_64.rpm>`_
* `foundationdb-server-6.2.15-1.el6.x86_64.rpm <https://www.foundationdb.org/downloads/6.2.15/rhel6/installers/foundationdb-server-6.2.15-1.el6.x86_64.rpm>`_ (depends on the clients package)
RHEL/CentOS EL7
---------------
The RHEL/CentOS EL7 packages are supported on 64-bit RHEL/CentOS 7.x.
* `foundationdb-clients-6.2.14-1.el7.x86_64.rpm <https://www.foundationdb.org/downloads/6.2.14/rhel7/installers/foundationdb-clients-6.2.14-1.el7.x86_64.rpm>`_
* `foundationdb-server-6.2.14-1.el7.x86_64.rpm <https://www.foundationdb.org/downloads/6.2.14/rhel7/installers/foundationdb-server-6.2.14-1.el7.x86_64.rpm>`_ (depends on the clients package)
* `foundationdb-clients-6.2.15-1.el7.x86_64.rpm <https://www.foundationdb.org/downloads/6.2.15/rhel7/installers/foundationdb-clients-6.2.15-1.el7.x86_64.rpm>`_
* `foundationdb-server-6.2.15-1.el7.x86_64.rpm <https://www.foundationdb.org/downloads/6.2.15/rhel7/installers/foundationdb-server-6.2.15-1.el7.x86_64.rpm>`_ (depends on the clients package)
Windows
-------
The Windows installer is supported on 64-bit Windows XP and later. It includes the client and (optionally) the server.
* `foundationdb-6.2.14-x64.msi <https://www.foundationdb.org/downloads/6.2.14/windows/installers/foundationdb-6.2.14-x64.msi>`_
* `foundationdb-6.2.15-x64.msi <https://www.foundationdb.org/downloads/6.2.15/windows/installers/foundationdb-6.2.15-x64.msi>`_
API Language Bindings
=====================
@ -58,18 +58,18 @@ On macOS and Windows, the FoundationDB Python API bindings are installed as part
If you need to use the FoundationDB Python API from other Python installations or paths, download the Python package:
* `foundationdb-6.2.14.tar.gz <https://www.foundationdb.org/downloads/6.2.14/bindings/python/foundationdb-6.2.14.tar.gz>`_
* `foundationdb-6.2.15.tar.gz <https://www.foundationdb.org/downloads/6.2.15/bindings/python/foundationdb-6.2.15.tar.gz>`_
Ruby 1.9.3/2.0.0+
-----------------
* `fdb-6.2.14.gem <https://www.foundationdb.org/downloads/6.2.14/bindings/ruby/fdb-6.2.14.gem>`_
* `fdb-6.2.15.gem <https://www.foundationdb.org/downloads/6.2.15/bindings/ruby/fdb-6.2.15.gem>`_
Java 8+
-------
* `fdb-java-6.2.14.jar <https://www.foundationdb.org/downloads/6.2.14/bindings/java/fdb-java-6.2.14.jar>`_
* `fdb-java-6.2.14-javadoc.jar <https://www.foundationdb.org/downloads/6.2.14/bindings/java/fdb-java-6.2.14-javadoc.jar>`_
* `fdb-java-6.2.15.jar <https://www.foundationdb.org/downloads/6.2.15/bindings/java/fdb-java-6.2.15.jar>`_
* `fdb-java-6.2.15-javadoc.jar <https://www.foundationdb.org/downloads/6.2.15/bindings/java/fdb-java-6.2.15-javadoc.jar>`_
Go 1.11+
--------

View File

@ -2,6 +2,14 @@
Release Notes
#############
6.2.15
======
Fixes
-----
* TLS throttling could block legitimate connections. `(PR #2575) <https://github.com/apple/foundationdb/pull/2575>`_.
6.2.14
======

View File

@ -75,10 +75,12 @@ ACTOR static Future<Void> handshake( TLSConnection* self ) {
if(!self->is_client) {
auto iter(g_network->networkInfo.serverTLSConnectionThrottler.find(peerIP));
if(iter != g_network->networkInfo.serverTLSConnectionThrottler.end()) {
if (now() < iter->second) {
TraceEvent("TLSIncomingConnectionThrottlingWarning", self->getDebugID()).suppressFor(1.0).detail("PeerIP", peerIP.first.toString());
wait(delay(FLOW_KNOBS->CONNECTION_MONITOR_TIMEOUT));
throw connection_failed();
if (now() < iter->second.second) {
if(iter->second.first >= FLOW_KNOBS->TLS_SERVER_CONNECTION_THROTTLE_ATTEMPTS) {
TraceEvent("TLSIncomingConnectionThrottlingWarning", self->getDebugID()).suppressFor(1.0).detail("PeerIP", peerIP.first.toString());
wait(delay(FLOW_KNOBS->CONNECTION_MONITOR_TIMEOUT));
throw connection_failed();
}
} else {
g_network->networkInfo.serverTLSConnectionThrottler.erase(peerIP);
}
@ -93,7 +95,12 @@ ACTOR static Future<Void> handshake( TLSConnection* self ) {
if ( r == ITLSSession::SUCCESS ) break;
if ( r == ITLSSession::FAILED ) {
TraceEvent("TLSConnectionHandshakeError", self->getDebugID()).suppressFor(1.0).detail("Peer", self->getPeerAddress());
g_network->networkInfo.serverTLSConnectionThrottler[peerIP] = now() + (self->is_client ? FLOW_KNOBS->TLS_CLIENT_CONNECTION_THROTTLE_TIMEOUT : FLOW_KNOBS->TLS_SERVER_CONNECTION_THROTTLE_TIMEOUT);
auto iter(g_network->networkInfo.serverTLSConnectionThrottler.find(peerIP));
if(iter != g_network->networkInfo.serverTLSConnectionThrottler.end()) {
iter->second.first++;
} else {
g_network->networkInfo.serverTLSConnectionThrottler[peerIP] = std::make_pair(0,now() + (self->is_client ? FLOW_KNOBS->TLS_CLIENT_CONNECTION_THROTTLE_TIMEOUT : FLOW_KNOBS->TLS_SERVER_CONNECTION_THROTTLE_TIMEOUT));
}
throw connection_failed();
}
ASSERT( r == ITLSSession::WANT_WRITE || r == ITLSSession::WANT_READ );
@ -174,8 +181,17 @@ int TLSConnection::write( SendBuffer const* buffer, int limit ) {
}
ACTOR Future<Reference<IConnection>> wrap( Reference<ITLSPolicy> policy, bool is_client, Future<Reference<IConnection>> c, std::string host) {
Reference<IConnection> conn = wait(c);
return Reference<IConnection>(new TLSConnection( conn, policy, is_client, host ));
state Reference<IConnection> conn = wait(c);
try {
state Reference<TLSConnection> tlsConn(new TLSConnection( conn, policy, is_client, host ));
if(is_client) {
wait(tlsConn->handshook);
}
return tlsConn;
} catch( Error &e ) {
conn->close();
throw e;
}
}
Future<Reference<IConnection>> TLSListener::accept() {
@ -198,9 +214,11 @@ Future<Reference<IConnection>> TLSNetworkConnections::connect( NetworkAddress to
std::pair<IPAddress,uint16_t> peerIP = std::make_pair(toAddr.ip, toAddr.port);
auto iter(g_network->networkInfo.serverTLSConnectionThrottler.find(peerIP));
if(iter != g_network->networkInfo.serverTLSConnectionThrottler.end()) {
if (now() < iter->second) {
TraceEvent("TLSOutgoingConnectionThrottlingWarning").suppressFor(1.0).detail("PeerIP", toAddr);
return waitAndFailConnection();
if (now() < iter->second.second) {
if(iter->second.first >= FLOW_KNOBS->TLS_CLIENT_CONNECTION_THROTTLE_ATTEMPTS) {
TraceEvent("TLSOutgoingConnectionThrottlingWarning").suppressFor(1.0).detail("PeerIP", toAddr);
return waitAndFailConnection();
}
} else {
g_network->networkInfo.serverTLSConnectionThrottler.erase(peerIP);
}

View File

@ -75,6 +75,8 @@ FlowKnobs::FlowKnobs(bool randomize, bool isSimulated) {
init( TLS_CERT_REFRESH_DELAY_SECONDS, 12*60*60 );
init( TLS_SERVER_CONNECTION_THROTTLE_TIMEOUT, 9.0 );
init( TLS_CLIENT_CONNECTION_THROTTLE_TIMEOUT, 11.0 );
init( TLS_SERVER_CONNECTION_THROTTLE_ATTEMPTS, 1 );
init( TLS_CLIENT_CONNECTION_THROTTLE_ATTEMPTS, 0 );
//AsyncFileCached
init( PAGE_CACHE_4K, 2LL<<30 );

View File

@ -93,6 +93,8 @@ public:
int TLS_CERT_REFRESH_DELAY_SECONDS;
double TLS_SERVER_CONNECTION_THROTTLE_TIMEOUT;
double TLS_CLIENT_CONNECTION_THROTTLE_TIMEOUT;
int TLS_SERVER_CONNECTION_THROTTLE_ATTEMPTS;
int TLS_CLIENT_CONNECTION_THROTTLE_ATTEMPTS;
//AsyncFileCached
int64_t PAGE_CACHE_4K;

View File

@ -326,7 +326,7 @@ struct NetworkInfo {
double newestAlternativesFailure = 0;
double lastAlternativesFailureSkipDelay = 0;
std::map<std::pair<IPAddress, uint16_t>, double> serverTLSConnectionThrottler;
std::map<std::pair<IPAddress, uint16_t>, std::pair<int,double>> serverTLSConnectionThrottler;
NetworkInfo() {}
};