mirror of
https://github.com/apple/foundationdb.git
synced 2025-06-02 03:12:12 +08:00
code cleanup
This commit is contained in:
parent
3bcecea30b
commit
761da5a059
@ -82,8 +82,7 @@ void fdb_flow_test() {
|
||||
fdb->setupNetwork();
|
||||
startThread(networkThread, fdb);
|
||||
|
||||
boost::asio::ssl::context sslContext(boost::asio::ssl::context::tlsv12);
|
||||
g_network = newNet2( &sslContext, false );
|
||||
g_network = newNet2(false);
|
||||
|
||||
openTraceFile(NetworkAddress(), 1000000, 1000000, ".");
|
||||
systemMonitor();
|
||||
|
@ -1748,8 +1748,7 @@ ACTOR void startTest(std::string clusterFilename, StringRef prefix, int apiVersi
|
||||
populateOpsThatCreateDirectories(); // FIXME
|
||||
|
||||
// This is "our" network
|
||||
boost::asio::ssl::context sslContext(boost::asio::ssl::context::tlsv12);
|
||||
g_network = newNet2(&sslContext, false);
|
||||
g_network = newNet2(false);
|
||||
|
||||
ASSERT(!API::isAPIVersionSelected());
|
||||
try {
|
||||
@ -1792,8 +1791,7 @@ ACTOR void startTest(std::string clusterFilename, StringRef prefix, int apiVersi
|
||||
|
||||
ACTOR void _test_versionstamp() {
|
||||
try {
|
||||
boost::asio::ssl::context sslContext(boost::asio::ssl::context::tlsv12);
|
||||
g_network = newNet2(&sslContext, false);
|
||||
g_network = newNet2(false);
|
||||
|
||||
API *fdb = FDB::API::selectAPIVersion(620);
|
||||
|
||||
|
@ -38,7 +38,6 @@
|
||||
#include "fdbclient/json_spirit/json_spirit_writer_template.h"
|
||||
|
||||
#include "fdbrpc/Platform.h"
|
||||
#include "fdbrpc/TLSConnection.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
@ -3072,22 +3071,22 @@ int main(int argc, char* argv[]) {
|
||||
blobCredentials.push_back(args->OptionArg());
|
||||
break;
|
||||
#ifndef TLS_DISABLED
|
||||
case TLSOptions::OPT_TLS_PLUGIN:
|
||||
case TLSParams::OPT_TLS_PLUGIN:
|
||||
args->OptionArg();
|
||||
break;
|
||||
case TLSOptions::OPT_TLS_CERTIFICATES:
|
||||
case TLSParams::OPT_TLS_CERTIFICATES:
|
||||
tlsCertPath = args->OptionArg();
|
||||
break;
|
||||
case TLSOptions::OPT_TLS_PASSWORD:
|
||||
case TLSParams::OPT_TLS_PASSWORD:
|
||||
tlsPassword = args->OptionArg();
|
||||
break;
|
||||
case TLSOptions::OPT_TLS_CA_FILE:
|
||||
case TLSParams::OPT_TLS_CA_FILE:
|
||||
tlsCAPath = args->OptionArg();
|
||||
break;
|
||||
case TLSOptions::OPT_TLS_KEY:
|
||||
case TLSParams::OPT_TLS_KEY:
|
||||
tlsKeyPath = args->OptionArg();
|
||||
break;
|
||||
case TLSOptions::OPT_TLS_VERIFY_PEERS:
|
||||
case TLSParams::OPT_TLS_VERIFY_PEERS:
|
||||
tlsVerifyPeers = args->OptionArg();
|
||||
break;
|
||||
#endif
|
||||
|
@ -33,7 +33,6 @@
|
||||
|
||||
#include "flow/DeterministicRandom.h"
|
||||
#include "flow/SignalSafeUnwind.h"
|
||||
#include "fdbrpc/TLSConnection.h"
|
||||
#include "fdbrpc/Platform.h"
|
||||
|
||||
#include "flow/SimpleOpt.h"
|
||||
@ -2503,22 +2502,22 @@ struct CLIOptions {
|
||||
|
||||
#ifndef TLS_DISABLED
|
||||
// TLS Options
|
||||
case TLSOptions::OPT_TLS_PLUGIN:
|
||||
case TLSParams::OPT_TLS_PLUGIN:
|
||||
args.OptionArg();
|
||||
break;
|
||||
case TLSOptions::OPT_TLS_CERTIFICATES:
|
||||
case TLSParams::OPT_TLS_CERTIFICATES:
|
||||
tlsCertPath = args.OptionArg();
|
||||
break;
|
||||
case TLSOptions::OPT_TLS_CA_FILE:
|
||||
case TLSParams::OPT_TLS_CA_FILE:
|
||||
tlsCAPath = args.OptionArg();
|
||||
break;
|
||||
case TLSOptions::OPT_TLS_KEY:
|
||||
case TLSParams::OPT_TLS_KEY:
|
||||
tlsKeyPath = args.OptionArg();
|
||||
break;
|
||||
case TLSOptions::OPT_TLS_PASSWORD:
|
||||
case TLSParams::OPT_TLS_PASSWORD:
|
||||
tlsPassword = args.OptionArg();
|
||||
break;
|
||||
case TLSOptions::OPT_TLS_VERIFY_PEERS:
|
||||
case TLSParams::OPT_TLS_VERIFY_PEERS:
|
||||
tlsVerifyPeers = args.OptionArg();
|
||||
break;
|
||||
#endif
|
||||
|
@ -38,7 +38,6 @@
|
||||
#include "fdbrpc/LoadBalance.h"
|
||||
#include "fdbrpc/Net2FileSystem.h"
|
||||
#include "fdbrpc/simulator.h"
|
||||
#include "fdbrpc/TLSConnection.h"
|
||||
#include "flow/ActorCollection.h"
|
||||
#include "flow/DeterministicRandom.h"
|
||||
#include "flow/Knobs.h"
|
||||
@ -988,7 +987,7 @@ void setupNetwork(uint64_t transportId, bool useMetrics) {
|
||||
|
||||
initTLSPolicy();
|
||||
|
||||
g_network = newNet2(&networkOptions.sslContext, false, useMetrics || networkOptions.traceDirectory.present(), tlsPolicy, tlsParams);
|
||||
g_network = newNet2(false, useMetrics || networkOptions.traceDirectory.present(), tlsPolicy, tlsParams);
|
||||
FlowTransport::createInstance(true, transportId);
|
||||
Net2FileSystem::newFileSystem();
|
||||
}
|
||||
|
@ -61,14 +61,12 @@ struct NetworkOptions {
|
||||
Optional<bool> logClientInfo;
|
||||
Standalone<VectorRef<ClientVersionRef>> supportedVersions;
|
||||
bool slowTaskProfilingEnabled;
|
||||
boost::asio::ssl::context sslContext;
|
||||
std::string tlsPassword;
|
||||
|
||||
// The default values, TRACE_DEFAULT_ROLL_SIZE and TRACE_DEFAULT_MAX_LOGS_SIZE are located in Trace.h.
|
||||
NetworkOptions()
|
||||
: localAddress(""), clusterFile(""), traceDirectory(Optional<std::string>()),
|
||||
traceRollSize(TRACE_DEFAULT_ROLL_SIZE), traceMaxLogsSize(TRACE_DEFAULT_MAX_LOGS_SIZE), traceLogGroup("default"),
|
||||
traceFormat("xml"), slowTaskProfilingEnabled(false), sslContext(boost::asio::ssl::context(boost::asio::ssl::context::tlsv12)), tlsPassword("") {}
|
||||
traceFormat("xml"), slowTaskProfilingEnabled(false) {}
|
||||
};
|
||||
|
||||
class Database {
|
||||
|
@ -27,7 +27,6 @@ set(FDBRPC_SRCS
|
||||
sim2.actor.cpp
|
||||
sim_validation.cpp
|
||||
TimedRequest.h
|
||||
TLSConnection.actor.cpp
|
||||
TraceFileIO.cpp)
|
||||
|
||||
set(FDBRPC_THIRD_PARTY_SRCS
|
||||
|
@ -1,136 +0,0 @@
|
||||
/*
|
||||
* ITLSPlugin.h
|
||||
*
|
||||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
#ifndef FDB_ITLSPLUGIN_H
|
||||
#define FDB_ITLSPLUGIN_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct ITLSSession {
|
||||
enum { SUCCESS = 0, WANT_READ = -1, WANT_WRITE = -2, FAILED = -3 };
|
||||
|
||||
virtual void addref() = 0;
|
||||
virtual void delref() = 0;
|
||||
|
||||
// handshake should return SUCCESS if the handshake is complete,
|
||||
// FAILED on fatal error, or one of WANT_READ or WANT_WRITE if the
|
||||
// handshake should be reattempted after more data can be
|
||||
// read/written on the underlying connection.
|
||||
virtual int handshake() = 0;
|
||||
|
||||
// read should return the (non-zero) number of bytes read,
|
||||
// WANT_READ or WANT_WRITE if the operation is blocked by the
|
||||
// underlying stream, or FAILED if there is an error (including a
|
||||
// closed connection).
|
||||
virtual int read(uint8_t* data, int length) = 0;
|
||||
|
||||
// write should return the (non-zero) number of bytes written, or
|
||||
// WANT_READ or WANT_WRITE if the operation is blocked by the
|
||||
// underlying stream, or FAILED if there is an error.
|
||||
virtual int write(const uint8_t* data, int length) = 0;
|
||||
};
|
||||
|
||||
// Returns the number of bytes sent (possibly 0), or -1 on error
|
||||
// (including connection close)
|
||||
typedef int(*TLSSendCallbackFunc)(void* ctx, const uint8_t* buf, int len);
|
||||
|
||||
// Returns the number of bytes read (possibly 0), or -1 on error
|
||||
// (including connection close)
|
||||
typedef int(*TLSRecvCallbackFunc)(void* ctx, uint8_t* buf, int len);
|
||||
|
||||
struct ITLSPolicy {
|
||||
virtual void addref() = 0;
|
||||
virtual void delref() = 0;
|
||||
|
||||
// set_ca_data should import the provided certificate list and
|
||||
// associate it with this policy. cert_data will point to a PEM
|
||||
// encoded certificate list of trust roots.
|
||||
//
|
||||
// set_ca_data should return true if the operation succeeded,
|
||||
// and false otherwise. After the first call to create_session for
|
||||
// a given policy, set_ca_data should immediately return false
|
||||
// if called.
|
||||
virtual bool set_ca_data(const uint8_t* ca_data, int ca_len) = 0;
|
||||
|
||||
// set_cert_data should import the provided certificate list and
|
||||
// associate it with this policy. cert_data will point to a PEM
|
||||
// encoded certificate list, ordered such that each certificate
|
||||
// certifies the one before it.
|
||||
//
|
||||
// cert_data may additionally contain key information, which must
|
||||
// be ignored.
|
||||
//
|
||||
// set_cert_data should return true if the operation succeeded,
|
||||
// and false otherwise. After the first call to create_session for
|
||||
// a given policy, set_cert_data should immediately return false
|
||||
// if called.
|
||||
virtual bool set_cert_data(const uint8_t* cert_data, int cert_len) = 0;
|
||||
|
||||
// set_key_data should import the provided private key and
|
||||
// associate it with this policy. key_data will point to a PEM
|
||||
// encoded key, which may be encrypted. If encrypted the password
|
||||
// argument should be specified, otherwise it may be NULL.
|
||||
//
|
||||
// key_data may additionally contain certificate information,
|
||||
// which must be ignored.
|
||||
//
|
||||
// set_key_data should return true if the operation succeeded, and
|
||||
// false otherwise. After the first call to create_session for a
|
||||
// given policy, set_key_data should immediately return false if
|
||||
// called.
|
||||
virtual bool set_key_data(const uint8_t* key_data, int key_len, const char* password) = 0;
|
||||
|
||||
// set_verify_peers should modify the validation rules for
|
||||
// verifying a peer during connection handshake. The format of
|
||||
// verify_peers is implementation specific.
|
||||
//
|
||||
// set_verify_peers should return true if the operation succeed,
|
||||
// and false otherwise. After the first call to create_session for
|
||||
// a given policy, set_verify_peers should immediately return
|
||||
// false if called.
|
||||
virtual bool set_verify_peers(int count, const uint8_t* verify_peers[], int verify_peers_len[]) = 0;
|
||||
|
||||
// create_session should return a new object that implements
|
||||
// ITLSSession, associated with this policy. After the first call
|
||||
// to create_session for a given policy, further calls to
|
||||
// ITLSPolicy::set_* will fail and return false.
|
||||
//
|
||||
// The newly created session should use send_func and recv_func to
|
||||
// send and receive data on the underlying transport, and must
|
||||
// provide send_ctx/recv_ctx to the callbacks.
|
||||
//
|
||||
// uid will be used to identify this session within trace events
|
||||
virtual ITLSSession* create_session(bool is_client, const char *servername, TLSSendCallbackFunc send_func, void* send_ctx, TLSRecvCallbackFunc recv_func, void* recv_ctx, void* uid) = 0;
|
||||
};
|
||||
|
||||
struct ITLSPlugin {
|
||||
virtual void addref() = 0;
|
||||
virtual void delref() = 0;
|
||||
|
||||
// create_policy should return a new object that implements
|
||||
// ITLSPolicy.
|
||||
virtual ITLSPolicy* create_policy() = 0;
|
||||
|
||||
static inline const char* get_plugin_type_name_and_version() { return "ITLSPlugin"; }
|
||||
};
|
||||
|
||||
#endif /* FDB_ITLSPLUGIN_H */
|
@ -1,539 +0,0 @@
|
||||
/*
|
||||
* TLSConnection.actor.cpp
|
||||
*
|
||||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
* Licensed 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 <memory>
|
||||
#include "flow/flow.h"
|
||||
#include "flow/network.h"
|
||||
#include "flow/Knobs.h"
|
||||
#include "fdbrpc/TLSConnection.h"
|
||||
#include "fdbrpc/ITLSPlugin.h"
|
||||
#include "fdbrpc/LoadPlugin.h"
|
||||
#include "fdbrpc/Platform.h"
|
||||
#include "fdbrpc/IAsyncFile.h"
|
||||
#include "flow/actorcompiler.h" // This must be the last #include.
|
||||
|
||||
// Name of specialized TLS Plugin
|
||||
const char* tlsPluginName = "fdb-libressl-plugin";
|
||||
|
||||
// Must not throw an exception from this function!
|
||||
static int send_func(void* ctx, const uint8_t* buf, int len) {
|
||||
TLSConnection* conn = (TLSConnection*)ctx;
|
||||
|
||||
try {
|
||||
SendBuffer sb;
|
||||
sb.bytes_sent = 0;
|
||||
sb.bytes_written = len;
|
||||
sb.data = buf;
|
||||
sb.next = 0;
|
||||
|
||||
int w = conn->conn->write( &sb );
|
||||
return w;
|
||||
} catch ( Error& e ) {
|
||||
TraceEvent("TLSConnectionSendError", conn->getDebugID()).suppressFor(1.0).detail("Peer", conn->getPeerAddress().toString()).error(e);
|
||||
return -1;
|
||||
} catch ( ... ) {
|
||||
TraceEvent("TLSConnectionSendError", conn->getDebugID()).suppressFor(1.0).detail("Peer", conn->getPeerAddress()).error( unknown_error() );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Must not throw an exception from this function!
|
||||
static int recv_func(void* ctx, uint8_t* buf, int len) {
|
||||
TLSConnection* conn = (TLSConnection*)ctx;
|
||||
|
||||
try {
|
||||
int r = conn->conn->read( buf, buf + len );
|
||||
return r;
|
||||
} catch ( Error& e ) {
|
||||
TraceEvent("TLSConnectionRecvError", conn->getDebugID()).suppressFor(1.0).detail("Peer", conn->getPeerAddress()).error(e);
|
||||
return -1;
|
||||
} catch ( ... ) {
|
||||
TraceEvent("TLSConnectionRecvError", conn->getDebugID()).suppressFor(1.0).detail("Peer", conn->getPeerAddress()).error( unknown_error() );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ACTOR static Future<Void> handshake( TLSConnection* self ) {
|
||||
state std::pair<IPAddress,uint16_t> peerIP = std::make_pair(self->conn->getPeerAddress().ip, self->is_client ? self->conn->getPeerAddress().port : static_cast<uint16_t>(0));
|
||||
if(!self->is_client) {
|
||||
auto iter(g_network->networkInfo.serverTLSConnectionThrottler.find(peerIP));
|
||||
if(iter != g_network->networkInfo.serverTLSConnectionThrottler.end()) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
loop {
|
||||
int r = self->session->handshake();
|
||||
if(BUGGIFY_WITH_PROB(0.001)) {
|
||||
r = ITLSSession::FAILED;
|
||||
}
|
||||
if ( r == ITLSSession::SUCCESS ) break;
|
||||
if ( r == ITLSSession::FAILED ) {
|
||||
TraceEvent("TLSConnectionHandshakeError", self->getDebugID()).suppressFor(1.0).detail("Peer", self->getPeerAddress());
|
||||
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 );
|
||||
wait( r == ITLSSession::WANT_WRITE ? self->conn->onWritable() : self->conn->onReadable() );
|
||||
}
|
||||
|
||||
TraceEvent("TLSConnectionHandshakeSuccessful", self->getDebugID()).suppressFor(1.0).detail("Peer", self->getPeerAddress());
|
||||
|
||||
return Void();
|
||||
}
|
||||
|
||||
TLSConnection::TLSConnection( Reference<IConnection> const& conn, Reference<ITLSPolicy> const& policy, bool is_client, std::string host) : conn(conn), write_wants(0), read_wants(0), uid(conn->getDebugID()), is_client(is_client) {
|
||||
const char * serverName = host.empty() ? NULL : host.c_str();
|
||||
session = Reference<ITLSSession>( policy->create_session(is_client, serverName, send_func, this, recv_func, this, (void*)&uid) );
|
||||
if ( !session ) {
|
||||
// If session is NULL, we're trusting policy->create_session
|
||||
// to have used its provided logging function to have logged
|
||||
// the error
|
||||
throw tls_error();
|
||||
}
|
||||
handshook = handshake(this);
|
||||
}
|
||||
|
||||
Future<Void> TLSConnection::onWritable() {
|
||||
if ( !handshook.isReady() )
|
||||
return handshook;
|
||||
return
|
||||
write_wants == ITLSSession::WANT_READ ? conn->onReadable() :
|
||||
write_wants == ITLSSession::WANT_WRITE ? conn->onWritable() :
|
||||
Void();
|
||||
}
|
||||
|
||||
Future<Void> TLSConnection::onReadable() {
|
||||
if ( !handshook.isReady() )
|
||||
return handshook;
|
||||
return
|
||||
read_wants == ITLSSession::WANT_READ ? conn->onReadable() :
|
||||
read_wants == ITLSSession::WANT_WRITE ? conn->onWritable() :
|
||||
Void();
|
||||
}
|
||||
|
||||
int TLSConnection::read( uint8_t* begin, uint8_t* end ) {
|
||||
if ( !handshook.isReady() ) return 0;
|
||||
handshook.get();
|
||||
|
||||
read_wants = 0;
|
||||
int r = session->read( begin, end - begin );
|
||||
if ( r > 0 )
|
||||
return r;
|
||||
|
||||
if ( r == ITLSSession::FAILED ) throw connection_failed();
|
||||
|
||||
ASSERT( r == ITLSSession::WANT_WRITE || r == ITLSSession::WANT_READ );
|
||||
|
||||
read_wants = r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int TLSConnection::write( SendBuffer const* buffer, int limit ) {
|
||||
ASSERT(limit > 0);
|
||||
|
||||
if ( !handshook.isReady() ) return 0;
|
||||
handshook.get();
|
||||
|
||||
write_wants = 0;
|
||||
int toSend = std::min(limit, buffer->bytes_written - buffer->bytes_sent);
|
||||
ASSERT(toSend);
|
||||
int w = session->write( buffer->data + buffer->bytes_sent, toSend );
|
||||
if ( w > 0 )
|
||||
return w;
|
||||
|
||||
if ( w == ITLSSession::FAILED ) throw connection_failed();
|
||||
|
||||
ASSERT( w == ITLSSession::WANT_WRITE || w == ITLSSession::WANT_READ );
|
||||
|
||||
write_wants = w;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ACTOR Future<Reference<IConnection>> wrap( Reference<ITLSPolicy> policy, bool is_client, Future<Reference<IConnection>> c, std::string 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() {
|
||||
return wrap( options->get_policy(TLSOptions::POLICY_VERIFY_PEERS), false, listener->accept(), "");
|
||||
}
|
||||
|
||||
TLSNetworkConnections::TLSNetworkConnections( Reference<TLSOptions> options ) : options(options) {
|
||||
network = INetworkConnections::net();
|
||||
g_network->setGlobal(INetwork::enumGlobal::enNetworkConnections, (flowGlobalType) this);
|
||||
}
|
||||
|
||||
ACTOR Future<Reference<IConnection>> waitAndFailConnection() {
|
||||
wait(delay(FLOW_KNOBS->CONNECTION_MONITOR_TIMEOUT));
|
||||
throw connection_failed();
|
||||
}
|
||||
|
||||
Future<Reference<IConnection>> TLSNetworkConnections::connect( NetworkAddress toAddr, std::string host) {
|
||||
if ( toAddr.isTLS() ) {
|
||||
NetworkAddress clearAddr( toAddr.ip, toAddr.port, toAddr.isPublic(), false );
|
||||
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.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);
|
||||
}
|
||||
}
|
||||
|
||||
TraceEvent("TLSConnectionConnecting").suppressFor(1.0).detail("ToAddr", toAddr);
|
||||
// For FDB<->FDB connections, we don't have hostnames and can't verify IP
|
||||
// addresses against certificates, so we have our own peer verifying logic
|
||||
// to use. For FDB<->external system connections, we can use the standard
|
||||
// hostname-based certificate verification logic.
|
||||
if (host.empty() || host == toAddr.ip.toString())
|
||||
return wrap(options->get_policy(TLSOptions::POLICY_VERIFY_PEERS), true, network->connect(clearAddr), std::string(""));
|
||||
else
|
||||
return wrap( options->get_policy(TLSOptions::POLICY_NO_VERIFY_PEERS), true, network->connect( clearAddr ), host );
|
||||
}
|
||||
return network->connect( toAddr );
|
||||
}
|
||||
|
||||
Future<std::vector<NetworkAddress>> TLSNetworkConnections::resolveTCPEndpoint( std::string host, std::string service) {
|
||||
return network->resolveTCPEndpoint( host, service );
|
||||
}
|
||||
|
||||
Reference<IListener> TLSNetworkConnections::listen( NetworkAddress localAddr ) {
|
||||
if ( localAddr.isTLS() ) {
|
||||
NetworkAddress clearAddr( localAddr.ip, localAddr.port, localAddr.isPublic(), false );
|
||||
TraceEvent("TLSConnectionListening").detail("OnAddr", localAddr);
|
||||
return Reference<IListener>(new TLSListener( options, network->listen( clearAddr ) ));
|
||||
}
|
||||
return network->listen( localAddr );
|
||||
}
|
||||
|
||||
// 5MB for loading files into memory
|
||||
#define CERT_FILE_MAX_SIZE (5 * 1024 * 1024)
|
||||
|
||||
void TLSOptions::set_cert_file( std::string const& cert_file ) {
|
||||
try {
|
||||
TraceEvent("TLSConnectionSettingCertFile").detail("CertFilePath", cert_file);
|
||||
policyInfo.cert_path = cert_file;
|
||||
set_cert_data( readFileBytes( cert_file, CERT_FILE_MAX_SIZE ) );
|
||||
} catch ( Error& e) {
|
||||
TraceEvent(SevError, "TLSOptionsSetCertFileError").detail("Filename", cert_file).error(e).GetLastError();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void TLSOptions::set_ca_file(std::string const& ca_file) {
|
||||
try {
|
||||
TraceEvent("TLSConnectionSettingCAFile").detail("CAPath", ca_file);
|
||||
policyInfo.ca_path = ca_file;
|
||||
set_ca_data(readFileBytes(ca_file, CERT_FILE_MAX_SIZE));
|
||||
}
|
||||
catch (Error& e) {
|
||||
TraceEvent(SevError, "TLSOptionsSetCertAError").detail("Filename", ca_file).error(e).GetLastError();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void TLSOptions::set_ca_data(std::string const& ca_data) {
|
||||
if (!policyVerifyPeersSet.get() || !policyVerifyPeersNotSet.get())
|
||||
init_plugin();
|
||||
|
||||
TraceEvent("TLSConnectionSettingCAData").detail("CADataSize", ca_data.size());
|
||||
policyInfo.ca_contents = Standalone<StringRef>(ca_data);
|
||||
if (!policyVerifyPeersSet.get()->set_ca_data((const uint8_t*)&ca_data[0], ca_data.size()))
|
||||
throw tls_error();
|
||||
if (!policyVerifyPeersNotSet.get()->set_ca_data((const uint8_t*)&ca_data[0], ca_data.size()))
|
||||
throw tls_error();
|
||||
|
||||
ca_set = true;
|
||||
}
|
||||
|
||||
void TLSOptions::set_cert_data( std::string const& cert_data ) {
|
||||
if (!policyVerifyPeersSet.get() || !policyVerifyPeersNotSet.get())
|
||||
init_plugin();
|
||||
|
||||
TraceEvent("TLSConnectionSettingCertData").detail("CertDataSize", cert_data.size());
|
||||
policyInfo.cert_contents = Standalone<StringRef>(cert_data);
|
||||
if ( !policyVerifyPeersSet.get()->set_cert_data( (const uint8_t*)&cert_data[0], cert_data.size() ) )
|
||||
throw tls_error();
|
||||
if (!policyVerifyPeersNotSet.get()->set_cert_data((const uint8_t*)&cert_data[0], cert_data.size()))
|
||||
throw tls_error();
|
||||
|
||||
certs_set = true;
|
||||
}
|
||||
|
||||
void TLSOptions::set_key_password(std::string const& password) {
|
||||
TraceEvent("TLSConnectionSettingPassword");
|
||||
policyInfo.keyPassword = password;
|
||||
}
|
||||
|
||||
void TLSOptions::set_key_file( std::string const& key_file ) {
|
||||
try {
|
||||
TraceEvent("TLSConnectionSettingKeyFile").detail("KeyFilePath", key_file);
|
||||
policyInfo.key_path = key_file;
|
||||
set_key_data( readFileBytes( key_file, CERT_FILE_MAX_SIZE ) );
|
||||
} catch ( Error& e) {
|
||||
TraceEvent(SevError, "TLSOptionsSetKeyFileError").detail("Filename", key_file).error(e).GetLastError();
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
void TLSOptions::set_key_data( std::string const& key_data ) {
|
||||
if (!policyVerifyPeersSet.get() || !policyVerifyPeersNotSet.get())
|
||||
init_plugin();
|
||||
const char *passphrase = policyInfo.keyPassword.empty() ? NULL : policyInfo.keyPassword.c_str();
|
||||
TraceEvent("TLSConnectionSettingKeyData").detail("KeyDataSize", key_data.size());
|
||||
policyInfo.key_contents = Standalone<StringRef>(key_data);
|
||||
if ( !policyVerifyPeersSet.get()->set_key_data( (const uint8_t*)&key_data[0], key_data.size(), passphrase) )
|
||||
throw tls_error();
|
||||
if (!policyVerifyPeersNotSet.get()->set_key_data((const uint8_t*)&key_data[0], key_data.size(), passphrase))
|
||||
throw tls_error();
|
||||
|
||||
key_set = true;
|
||||
}
|
||||
|
||||
void TLSOptions::set_verify_peers( std::vector<std::string> const& verify_peers ) {
|
||||
if (!policyVerifyPeersSet.get())
|
||||
init_plugin();
|
||||
{
|
||||
TraceEvent e("TLSConnectionSettingVerifyPeers");
|
||||
for (int i = 0; i < verify_peers.size(); i++)
|
||||
e.detail(std::string("Value" + std::to_string(i)).c_str(), verify_peers[i].c_str());
|
||||
}
|
||||
std::unique_ptr<const uint8_t *[]> verify_peers_arr(new const uint8_t*[verify_peers.size()]);
|
||||
std::unique_ptr<int[]> verify_peers_len(new int[verify_peers.size()]);
|
||||
for (int i = 0; i < verify_peers.size(); i++) {
|
||||
verify_peers_arr[i] = (const uint8_t *)&verify_peers[i][0];
|
||||
verify_peers_len[i] = verify_peers[i].size();
|
||||
}
|
||||
|
||||
if (!policyVerifyPeersSet.get()->set_verify_peers(verify_peers.size(), verify_peers_arr.get(), verify_peers_len.get()))
|
||||
throw tls_error();
|
||||
|
||||
policyInfo.verify_peers = verify_peers;
|
||||
verify_peers_set = true;
|
||||
}
|
||||
|
||||
ACTOR static Future<ErrorOr<Standalone<StringRef>>> readEntireFile( std::string filename ) {
|
||||
state Reference<IAsyncFile> file = wait(IAsyncFileSystem::filesystem()->open(filename, IAsyncFile::OPEN_READONLY | IAsyncFile::OPEN_UNCACHED, 0));
|
||||
state int64_t filesize = wait(file->size());
|
||||
state Standalone<StringRef> buf = makeString(filesize);
|
||||
int rc = wait(file->read(mutateString(buf), filesize, 0));
|
||||
if (rc != filesize) {
|
||||
// File modified during read, probably. The mtime should change, and thus we'll be called again.
|
||||
return tls_error();
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
ACTOR static Future<Void> watchFileForChanges( std::string filename, AsyncVar<Standalone<StringRef>> *contents_var ) {
|
||||
state std::time_t lastModTime = wait(IAsyncFileSystem::filesystem()->lastWriteTime(filename));
|
||||
loop {
|
||||
wait(delay(FLOW_KNOBS->TLS_CERT_REFRESH_DELAY_SECONDS));
|
||||
std::time_t modtime = wait(IAsyncFileSystem::filesystem()->lastWriteTime(filename));
|
||||
if (lastModTime != modtime) {
|
||||
lastModTime = modtime;
|
||||
ErrorOr<Standalone<StringRef>> contents = wait(readEntireFile(filename));
|
||||
if (contents.present()) {
|
||||
contents_var->set(contents.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ACTOR static Future<Void> reloadConfigurationOnChange( TLSOptions::PolicyInfo *pci, Reference<ITLSPlugin> plugin, AsyncVar<Reference<ITLSPolicy>> *realVerifyPeersPolicy, AsyncVar<Reference<ITLSPolicy>> *realNoVerifyPeersPolicy ) {
|
||||
if (FLOW_KNOBS->TLS_CERT_REFRESH_DELAY_SECONDS <= 0) {
|
||||
return Void();
|
||||
}
|
||||
loop {
|
||||
// Early in bootup, the filesystem might not be initialized yet. Wait until it is.
|
||||
if (IAsyncFileSystem::filesystem() != nullptr) {
|
||||
break;
|
||||
}
|
||||
wait(delay(1.0));
|
||||
}
|
||||
state int mismatches = 0;
|
||||
state AsyncVar<Standalone<StringRef>> ca_var;
|
||||
state AsyncVar<Standalone<StringRef>> key_var;
|
||||
state AsyncVar<Standalone<StringRef>> cert_var;
|
||||
state std::vector<Future<Void>> lifetimes;
|
||||
if (!pci->ca_path.empty()) lifetimes.push_back(watchFileForChanges(pci->ca_path, &ca_var));
|
||||
if (!pci->key_path.empty()) lifetimes.push_back(watchFileForChanges(pci->key_path, &key_var));
|
||||
if (!pci->cert_path.empty()) lifetimes.push_back(watchFileForChanges(pci->cert_path, &cert_var));
|
||||
loop {
|
||||
state Future<Void> ca_changed = ca_var.onChange();
|
||||
state Future<Void> key_changed = key_var.onChange();
|
||||
state Future<Void> cert_changed = cert_var.onChange();
|
||||
wait( ca_changed || key_changed || cert_changed );
|
||||
if (ca_changed.isReady()) {
|
||||
TraceEvent(SevInfo, "TLSRefreshCAChanged").detail("path", pci->ca_path).detail("length", ca_var.get().size());
|
||||
pci->ca_contents = ca_var.get();
|
||||
}
|
||||
if (key_changed.isReady()) {
|
||||
TraceEvent(SevInfo, "TLSRefreshKeyChanged").detail("path", pci->key_path).detail("length", key_var.get().size());
|
||||
pci->key_contents = key_var.get();
|
||||
}
|
||||
if (cert_changed.isReady()) {
|
||||
TraceEvent(SevInfo, "TLSRefreshCertChanged").detail("path", pci->cert_path).detail("length", cert_var.get().size());
|
||||
pci->cert_contents = cert_var.get();
|
||||
}
|
||||
bool rc = true;
|
||||
Reference<ITLSPolicy> verifypeers = Reference<ITLSPolicy>(plugin->create_policy());
|
||||
Reference<ITLSPolicy> noverifypeers = Reference<ITLSPolicy>(plugin->create_policy());
|
||||
loop {
|
||||
// Don't actually loop. We're just using loop/break as a `goto err`.
|
||||
// This loop always ends with an unconditional break.
|
||||
rc = verifypeers->set_ca_data(pci->ca_contents.begin(), pci->ca_contents.size());
|
||||
if (!rc) break;
|
||||
rc = verifypeers->set_key_data(pci->key_contents.begin(), pci->key_contents.size(), pci->keyPassword.c_str());
|
||||
if (!rc) break;
|
||||
rc = verifypeers->set_cert_data(pci->cert_contents.begin(), pci->cert_contents.size());
|
||||
if (!rc) break;
|
||||
{
|
||||
std::unique_ptr<const uint8_t *[]> verify_peers_arr(new const uint8_t*[pci->verify_peers.size()]);
|
||||
std::unique_ptr<int[]> verify_peers_len(new int[pci->verify_peers.size()]);
|
||||
for (int i = 0; i < pci->verify_peers.size(); i++) {
|
||||
verify_peers_arr[i] = (const uint8_t *)&pci->verify_peers[i][0];
|
||||
verify_peers_len[i] = pci->verify_peers[i].size();
|
||||
}
|
||||
rc = verifypeers->set_verify_peers(pci->verify_peers.size(), verify_peers_arr.get(), verify_peers_len.get());
|
||||
if (!rc) break;
|
||||
}
|
||||
rc = noverifypeers->set_ca_data(pci->ca_contents.begin(), pci->ca_contents.size());
|
||||
if (!rc) break;
|
||||
rc = noverifypeers->set_key_data(pci->key_contents.begin(), pci->key_contents.size(), pci->keyPassword.c_str());
|
||||
if (!rc) break;
|
||||
rc = noverifypeers->set_cert_data(pci->cert_contents.begin(), pci->cert_contents.size());
|
||||
if (!rc) break;
|
||||
break;
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
TraceEvent(SevInfo, "TLSCertificateRefreshSucceeded");
|
||||
realVerifyPeersPolicy->set(verifypeers);
|
||||
realNoVerifyPeersPolicy->set(noverifypeers);
|
||||
mismatches = 0;
|
||||
} else {
|
||||
// Some files didn't match up, they should in the future, and we'll retry then.
|
||||
mismatches++;
|
||||
TraceEvent(SevWarn, "TLSCertificateRefreshMismatch").detail("mismatches", mismatches);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char *defaultCertFileName = "fdb.pem";
|
||||
|
||||
Reference<ITLSPolicy> TLSOptions::get_policy(PolicyType type) {
|
||||
if ( !certs_set ) {
|
||||
if ( !platform::getEnvironmentVar( "FDB_TLS_CERTIFICATE_FILE", policyInfo.cert_path ) )
|
||||
policyInfo.cert_path = fileExists(defaultCertFileName) ? defaultCertFileName : joinPath(platform::getDefaultConfigPath(), defaultCertFileName);
|
||||
set_cert_file( policyInfo.cert_path );
|
||||
}
|
||||
if ( !key_set ) {
|
||||
if ( policyInfo.keyPassword.empty() )
|
||||
platform::getEnvironmentVar( "FDB_TLS_PASSWORD", policyInfo.keyPassword );
|
||||
if ( !platform::getEnvironmentVar( "FDB_TLS_KEY_FILE", policyInfo.key_path ) )
|
||||
policyInfo.key_path = fileExists(defaultCertFileName) ? defaultCertFileName : joinPath(platform::getDefaultConfigPath(), defaultCertFileName);
|
||||
set_key_file( policyInfo.key_path );
|
||||
}
|
||||
if( !verify_peers_set ) {
|
||||
std::string verify_peers;
|
||||
if (platform::getEnvironmentVar("FDB_TLS_VERIFY_PEERS", verify_peers))
|
||||
set_verify_peers({ verify_peers });
|
||||
else
|
||||
set_verify_peers({ std::string("Check.Valid=1")});
|
||||
}
|
||||
if (!ca_set) {
|
||||
if (platform::getEnvironmentVar("FDB_TLS_CA_FILE", policyInfo.ca_path))
|
||||
set_ca_file(policyInfo.ca_path);
|
||||
}
|
||||
|
||||
if (!configurationReloader.present()) {
|
||||
configurationReloader = reloadConfigurationOnChange(&policyInfo, plugin, &policyVerifyPeersSet, &policyVerifyPeersNotSet);
|
||||
}
|
||||
|
||||
Reference<ITLSPolicy> policy;
|
||||
switch (type) {
|
||||
case POLICY_VERIFY_PEERS:
|
||||
policy = policyVerifyPeersSet.get();
|
||||
break;
|
||||
case POLICY_NO_VERIFY_PEERS:
|
||||
policy = policyVerifyPeersNotSet.get();
|
||||
break;
|
||||
default:
|
||||
ASSERT_ABORT(0);
|
||||
}
|
||||
return policy;
|
||||
}
|
||||
|
||||
void TLSOptions::init_plugin() {
|
||||
|
||||
TraceEvent("TLSConnectionLoadingPlugin").detail("Plugin", tlsPluginName);
|
||||
|
||||
plugin = loadPlugin<ITLSPlugin>( tlsPluginName );
|
||||
|
||||
if ( !plugin ) {
|
||||
TraceEvent(SevError, "TLSConnectionPluginInitError").detail("Plugin", tlsPluginName).GetLastError();
|
||||
throw tls_error();
|
||||
}
|
||||
|
||||
policyVerifyPeersSet = AsyncVar<Reference<ITLSPolicy>>(Reference<ITLSPolicy>(plugin->create_policy()));
|
||||
if ( !policyVerifyPeersSet.get()) {
|
||||
// Hopefully create_policy logged something with the log func
|
||||
TraceEvent(SevError, "TLSConnectionCreatePolicyVerifyPeersSetError");
|
||||
throw tls_error();
|
||||
}
|
||||
|
||||
policyVerifyPeersNotSet = AsyncVar<Reference<ITLSPolicy>>(Reference<ITLSPolicy>(plugin->create_policy()));
|
||||
if (!policyVerifyPeersNotSet.get()) {
|
||||
// Hopefully create_policy logged something with the log func
|
||||
TraceEvent(SevError, "TLSConnectionCreatePolicyVerifyPeersNotSetError");
|
||||
throw tls_error();
|
||||
}
|
||||
}
|
||||
|
||||
bool TLSOptions::enabled() {
|
||||
return policyVerifyPeersSet.get().isValid() && policyVerifyPeersNotSet.get().isValid();
|
||||
}
|
@ -1,175 +0,0 @@
|
||||
/*
|
||||
* TLSConnection.h
|
||||
*
|
||||
* This source file is part of the FoundationDB open source project
|
||||
*
|
||||
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
||||
*
|
||||
* Licensed 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.
|
||||
*/
|
||||
|
||||
#ifndef FLOW_TLSCONNECTION_H
|
||||
#define FLOW_TLSCONNECTION_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "flow/Platform.h"
|
||||
|
||||
#include "fdbrpc/ITLSPlugin.h"
|
||||
|
||||
struct TLSConnection : IConnection, ReferenceCounted<TLSConnection> {
|
||||
Reference<IConnection> conn;
|
||||
Reference<ITLSSession> session;
|
||||
|
||||
Future<Void> handshook;
|
||||
|
||||
int write_wants, read_wants;
|
||||
|
||||
UID uid;
|
||||
bool is_client;
|
||||
|
||||
virtual void addref() { ReferenceCounted<TLSConnection>::addref(); }
|
||||
virtual void delref() { ReferenceCounted<TLSConnection>::delref(); }
|
||||
|
||||
TLSConnection( Reference<IConnection> const& conn, Reference<ITLSPolicy> const& policy, bool is_client, std::string host);
|
||||
~TLSConnection() {
|
||||
// Here for ordering to make sure we delref the ITLSSession
|
||||
// which has a pointer to this object
|
||||
session.clear();
|
||||
}
|
||||
|
||||
virtual void close() { conn->close(); }
|
||||
|
||||
virtual Future<Void> acceptHandshake() { return Void(); }
|
||||
virtual Future<Void> connectHandshake() { return Void(); }
|
||||
|
||||
virtual Future<Void> onWritable();
|
||||
|
||||
virtual Future<Void> onReadable();
|
||||
|
||||
virtual int read( uint8_t* begin, uint8_t* end );
|
||||
|
||||
virtual int write( SendBuffer const* buffer, int limit);
|
||||
|
||||
virtual NetworkAddress getPeerAddress() {
|
||||
NetworkAddress a = conn->getPeerAddress();
|
||||
return NetworkAddress(a.ip, a.port, a.isPublic(), true);
|
||||
}
|
||||
|
||||
virtual UID getDebugID() { return uid; }
|
||||
};
|
||||
|
||||
struct TLSOptions : ReferenceCounted<TLSOptions> {
|
||||
enum { OPT_TLS = 100000, OPT_TLS_PLUGIN, OPT_TLS_CERTIFICATES, OPT_TLS_KEY, OPT_TLS_VERIFY_PEERS, OPT_TLS_CA_FILE, OPT_TLS_PASSWORD };
|
||||
enum PolicyType { POLICY_VERIFY_PEERS = 1, POLICY_NO_VERIFY_PEERS };
|
||||
TLSOptions() : certs_set(false), key_set(false), verify_peers_set(false), ca_set(false) {
|
||||
#ifndef TLS_DISABLED
|
||||
init_plugin( );
|
||||
#endif
|
||||
}
|
||||
|
||||
void set_cert_file( std::string const& cert_file );
|
||||
void set_cert_data( std::string const& cert_data );
|
||||
void set_ca_file(std::string const& ca_file);
|
||||
void set_ca_data(std::string const& ca_data);
|
||||
// If there is a passphrase, this api should be called prior to setting key for the passphrase to be used
|
||||
void set_key_password( std::string const& password );
|
||||
void set_key_file( std::string const& key_file );
|
||||
void set_key_data( std::string const& key_data );
|
||||
void set_verify_peers( std::vector<std::string> const& verify_peers );
|
||||
|
||||
Reference<ITLSPolicy> get_policy(PolicyType type);
|
||||
bool enabled();
|
||||
|
||||
struct PolicyInfo {
|
||||
std::string ca_path;
|
||||
Standalone<StringRef> ca_contents;
|
||||
std::string key_path;
|
||||
std::string keyPassword;
|
||||
Standalone<StringRef> key_contents;
|
||||
std::string cert_path;
|
||||
Standalone<StringRef> cert_contents;
|
||||
std::vector<std::string> verify_peers;
|
||||
};
|
||||
|
||||
private:
|
||||
void init_plugin();
|
||||
|
||||
Reference<ITLSPlugin> plugin;
|
||||
PolicyInfo policyInfo;
|
||||
AsyncVar<Reference<ITLSPolicy>> policyVerifyPeersSet;
|
||||
AsyncVar<Reference<ITLSPolicy>> policyVerifyPeersNotSet;
|
||||
Optional<Future<Void>> configurationReloader;
|
||||
|
||||
bool certs_set, key_set, verify_peers_set, ca_set;
|
||||
};
|
||||
|
||||
struct TLSListener : IListener, ReferenceCounted<TLSListener> {
|
||||
Reference<IListener> listener;
|
||||
Reference<TLSOptions> options;
|
||||
|
||||
TLSListener( Reference<TLSOptions> options, Reference<IListener> listener ) : options(options), listener(listener) {}
|
||||
|
||||
virtual void addref() { ReferenceCounted<TLSListener>::addref(); }
|
||||
virtual void delref() { ReferenceCounted<TLSListener>::delref(); }
|
||||
|
||||
virtual Future<Reference<IConnection>> accept();
|
||||
|
||||
virtual NetworkAddress getListenAddress() { return listener->getListenAddress(); }
|
||||
};
|
||||
|
||||
struct TLSNetworkConnections : INetworkConnections {
|
||||
INetworkConnections *network;
|
||||
|
||||
explicit TLSNetworkConnections( Reference<TLSOptions> options );
|
||||
|
||||
virtual Future<Reference<IConnection>> connect( NetworkAddress toAddr, std::string host );
|
||||
virtual Future<std::vector<NetworkAddress>> resolveTCPEndpoint( std::string host, std::string service);
|
||||
|
||||
virtual Reference<IListener> listen( NetworkAddress localAddr );
|
||||
|
||||
private:
|
||||
Reference<TLSOptions> options;
|
||||
};
|
||||
|
||||
#define TLS_PLUGIN_FLAG "--tls_plugin"
|
||||
#define TLS_CERTIFICATE_FILE_FLAG "--tls_certificate_file"
|
||||
#define TLS_KEY_FILE_FLAG "--tls_key_file"
|
||||
#define TLS_VERIFY_PEERS_FLAG "--tls_verify_peers"
|
||||
#define TLS_CA_FILE_FLAG "--tls_ca_file"
|
||||
#define TLS_PASSWORD_FLAG "--tls_password"
|
||||
|
||||
#define TLS_OPTION_FLAGS \
|
||||
{ TLSOptions::OPT_TLS_PLUGIN, TLS_PLUGIN_FLAG, SO_REQ_SEP }, \
|
||||
{ TLSOptions::OPT_TLS_CERTIFICATES, TLS_CERTIFICATE_FILE_FLAG, SO_REQ_SEP }, \
|
||||
{ TLSOptions::OPT_TLS_KEY, TLS_KEY_FILE_FLAG, SO_REQ_SEP }, \
|
||||
{ TLSOptions::OPT_TLS_VERIFY_PEERS, TLS_VERIFY_PEERS_FLAG, SO_REQ_SEP }, \
|
||||
{ TLSOptions::OPT_TLS_PASSWORD, TLS_PASSWORD_FLAG, SO_REQ_SEP }, \
|
||||
{ TLSOptions::OPT_TLS_CA_FILE, TLS_CA_FILE_FLAG, SO_REQ_SEP },
|
||||
|
||||
#define TLS_HELP \
|
||||
" " TLS_CERTIFICATE_FILE_FLAG " CERTFILE\n" \
|
||||
" The path of a file containing the TLS certificate and CA\n" \
|
||||
" chain.\n" \
|
||||
" " TLS_CA_FILE_FLAG " CERTAUTHFILE\n" \
|
||||
" The path of a file containing the CA certificates chain.\n" \
|
||||
" " TLS_KEY_FILE_FLAG " KEYFILE\n" \
|
||||
" The path of a file containing the private key corresponding\n" \
|
||||
" to the TLS certificate.\n" \
|
||||
" " TLS_PASSWORD_FLAG " PASSCODE\n" \
|
||||
" The passphrase of encrypted private key\n" \
|
||||
" " TLS_VERIFY_PEERS_FLAG " CONSTRAINTS\n" \
|
||||
" The constraints by which to validate TLS peers. The contents\n" \
|
||||
" and format of CONSTRAINTS are plugin-specific.\n"
|
||||
|
||||
#endif /* FLOW_TLSCONNECTION_H */
|
@ -35,7 +35,6 @@
|
||||
<ClCompile Include="ReplicationTypes.cpp" />
|
||||
<ClCompile Include="ReplicationPolicy.cpp" />
|
||||
<ClCompile Include="sim_validation.cpp" />
|
||||
<ActorCompiler Include="TLSConnection.actor.cpp" />
|
||||
<ClCompile Include="TraceFileIO.cpp" />
|
||||
<ClCompile Include="zlib\gzwrite.c" />
|
||||
<ClCompile Include="zlib\gzclose.c" />
|
||||
@ -91,7 +90,6 @@
|
||||
<ClInclude Include="Platform.h" />
|
||||
<ClInclude Include="fdbrpc.h" />
|
||||
<ClInclude Include="FlowTransport.h" />
|
||||
<ClInclude Include="ITLSPlugin.h" />
|
||||
<ClInclude Include="libcoroutine\Base.h" />
|
||||
<ClInclude Include="libcoroutine\Common.h" />
|
||||
<ClInclude Include="libcoroutine\Coro.h" />
|
||||
@ -110,7 +108,6 @@
|
||||
<ClInclude Include="sim_validation.h" />
|
||||
<ClInclude Include="Smoother.h" />
|
||||
<ClInclude Include="TimedRequest.h" />
|
||||
<ClInclude Include="TLSConnection.h" />
|
||||
<ClInclude Include="TraceFileIO.h" />
|
||||
<ClInclude Include="zlib\zlib.h" />
|
||||
<ClInclude Include="zlib\deflate.h" />
|
||||
|
@ -10,7 +10,6 @@
|
||||
<ActorCompiler Include="AsyncFileCached.actor.cpp" />
|
||||
<ActorCompiler Include="AsyncFileNonDurable.actor.h" />
|
||||
<ActorCompiler Include="AsyncFileNonDurable.actor.cpp" />
|
||||
<ActorCompiler Include="TLSConnection.actor.cpp" />
|
||||
<ActorCompiler Include="dsltest.actor.cpp" />
|
||||
<ActorCompiler Include="FlowTests.actor.cpp" />
|
||||
<ActorCompiler Include="genericactors.actor.cpp" />
|
||||
@ -129,7 +128,6 @@
|
||||
<ClInclude Include="zlib\inftrees.h">
|
||||
<Filter>zlib</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="ITLSPlugin.h" />
|
||||
<ClInclude Include="FailureMonitor.h" />
|
||||
<ClInclude Include="FlowTransport.h" />
|
||||
<ClInclude Include="IAsyncFile.h" />
|
||||
@ -144,7 +142,6 @@
|
||||
<ClInclude Include="RangeMap.h" />
|
||||
<ClInclude Include="Smoother.h" />
|
||||
<ClInclude Include="TraceFileIO.h" />
|
||||
<ClInclude Include="TLSConnection.h" />
|
||||
<ClInclude Include="IRateControl.h" />
|
||||
<ClInclude Include="Replication.h" />
|
||||
<ClInclude Include="ReplicationTypes.h" />
|
||||
|
@ -1590,10 +1590,10 @@ public:
|
||||
machines.erase(machineId);
|
||||
}
|
||||
|
||||
Sim2() : time(0.0), taskCount(0), yielded(false), yield_limit(0), currentTaskID(TaskPriority::Zero), sslContext(boost::asio::ssl::context(boost::asio::ssl::context::tlsv12)) {
|
||||
Sim2() : time(0.0), taskCount(0), yielded(false), yield_limit(0), currentTaskID(TaskPriority::Zero) {
|
||||
// Not letting currentProcess be NULL eliminates some annoying special cases
|
||||
currentProcess = new ProcessInfo("NoMachine", LocalityData(Optional<Standalone<StringRef>>(), StringRef(), StringRef(), StringRef()), ProcessClass(), {NetworkAddress()}, this, "", "");
|
||||
g_network = net2 = newNet2(&sslContext, false, true);
|
||||
g_network = net2 = newNet2(false, true);
|
||||
Net2FileSystem::newFileSystem();
|
||||
check_yield(TaskPriority::Zero);
|
||||
}
|
||||
@ -1692,7 +1692,6 @@ public:
|
||||
|
||||
//Sim2Net network;
|
||||
INetwork *net2;
|
||||
boost::asio::ssl::context sslContext;
|
||||
|
||||
//Map from machine IP -> machine disk space info
|
||||
std::map<IPAddress, SimDiskSpace> diskSpaceMap;
|
||||
|
@ -18,8 +18,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "fdbrpc/TLSConnection.h"
|
||||
|
||||
#ifndef FDBSERVER_SIMULATEDCLUSTER_H
|
||||
#define FDBSERVER_SIMULATEDCLUSTER_H
|
||||
#pragma once
|
||||
|
@ -52,7 +52,6 @@
|
||||
#include "fdbserver/workloads/workloads.actor.h"
|
||||
#include <time.h>
|
||||
#include "fdbserver/Status.h"
|
||||
#include "fdbrpc/TLSConnection.h"
|
||||
#include "fdbrpc/Net2FileSystem.h"
|
||||
#include "fdbrpc/Platform.h"
|
||||
#include "fdbrpc/AsyncFileCached.actor.h"
|
||||
@ -964,7 +963,6 @@ int main(int argc, char* argv[]) {
|
||||
int minTesterCount = 1;
|
||||
bool testOnServers = false;
|
||||
|
||||
boost::asio::ssl::context sslContext(boost::asio::ssl::context::tlsv12);
|
||||
Reference<TLSPolicy> tlsPolicy = Reference<TLSPolicy>(new TLSPolicy(TLSPolicy::Is::SERVER));
|
||||
TLSParams tlsParams;
|
||||
std::vector<std::string> tlsVerifyPeers;
|
||||
@ -1335,22 +1333,22 @@ int main(int argc, char* argv[]) {
|
||||
whitelistBinPaths = args.OptionArg();
|
||||
break;
|
||||
#ifndef TLS_DISABLED
|
||||
case TLSOptions::OPT_TLS_PLUGIN:
|
||||
case TLSParams::OPT_TLS_PLUGIN:
|
||||
args.OptionArg();
|
||||
break;
|
||||
case TLSOptions::OPT_TLS_CERTIFICATES:
|
||||
case TLSParams::OPT_TLS_CERTIFICATES:
|
||||
tlsParams.tlsCertPath = args.OptionArg();
|
||||
break;
|
||||
case TLSOptions::OPT_TLS_PASSWORD:
|
||||
case TLSParams::OPT_TLS_PASSWORD:
|
||||
tlsParams.tlsPassword = args.OptionArg();
|
||||
break;
|
||||
case TLSOptions::OPT_TLS_CA_FILE:
|
||||
case TLSParams::OPT_TLS_CA_FILE:
|
||||
tlsParams.tlsCAPath = args.OptionArg();
|
||||
break;
|
||||
case TLSOptions::OPT_TLS_KEY:
|
||||
case TLSParams::OPT_TLS_KEY:
|
||||
tlsParams.tlsKeyPath = args.OptionArg();
|
||||
break;
|
||||
case TLSOptions::OPT_TLS_VERIFY_PEERS:
|
||||
case TLSParams::OPT_TLS_VERIFY_PEERS:
|
||||
tlsVerifyPeers.push_back(args.OptionArg());
|
||||
break;
|
||||
#endif
|
||||
@ -1560,7 +1558,7 @@ int main(int argc, char* argv[]) {
|
||||
tlsPolicy->set_verify_peers( tlsVerifyPeers );
|
||||
}
|
||||
#endif
|
||||
g_network = newNet2(&sslContext, useThreadPool, true, tlsPolicy, tlsParams);
|
||||
g_network = newNet2(useThreadPool, true, tlsPolicy, tlsParams);
|
||||
FlowTransport::createInstance(false, 1);
|
||||
|
||||
const bool expectsPublicAddress = (role == FDBD || role == NetworkTestServer || role == Restore);
|
||||
|
@ -113,7 +113,7 @@ thread_local INetwork* thread_network = 0;
|
||||
class Net2 sealed : public INetwork, public INetworkConnections {
|
||||
|
||||
public:
|
||||
Net2(bool useThreadPool, bool useMetrics, boost::asio::ssl::context* sslContext, const TLSParams& tlsParams);
|
||||
Net2(bool useThreadPool, bool useMetrics, Reference<TLSPolicy> policy, const TLSParams& tlsParams);
|
||||
void run();
|
||||
void initMetrics();
|
||||
|
||||
@ -156,7 +156,7 @@ public:
|
||||
//private:
|
||||
|
||||
ASIOReactor reactor;
|
||||
boost::asio::ssl::context* sslContext;
|
||||
boost::asio::ssl::context sslContext;
|
||||
std::string tlsPassword;
|
||||
|
||||
std::string get_password() const {
|
||||
@ -832,7 +832,11 @@ struct PromiseTask : public Task, public FastAllocated<PromiseTask> {
|
||||
// TODO: Move to a headerfile and delete all the copies of this.
|
||||
#define CERT_FILE_MAX_SIZE (5 * 1024 * 1024)
|
||||
|
||||
Net2::Net2(bool useThreadPool, bool useMetrics, boost::asio::ssl::context* sslContext, const TLSParams& tlsParams)
|
||||
bool insecurely_always_accept(bool _1, boost::asio::ssl::verify_context& _2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Net2::Net2(bool useThreadPool, bool useMetrics, Reference<TLSPolicy> policy, const TLSParams& tlsParams)
|
||||
: useThreadPool(useThreadPool),
|
||||
network(this),
|
||||
reactor(this),
|
||||
@ -842,33 +846,42 @@ Net2::Net2(bool useThreadPool, bool useMetrics, boost::asio::ssl::context* sslCo
|
||||
tsc_begin(0), tsc_end(0), taskBegin(0), currentTaskID(TaskPriority::DefaultYield),
|
||||
lastMinTaskID(TaskPriority::Zero),
|
||||
numYields(0),
|
||||
sslContext(sslContext),
|
||||
tlsPassword(tlsParams.tlsPassword)
|
||||
tlsPassword(tlsParams.tlsPassword),
|
||||
sslContext(boost::asio::ssl::context(boost::asio::ssl::context::tlsv12))
|
||||
|
||||
{
|
||||
TraceEvent("Net2Starting");
|
||||
|
||||
if(sslContext) {
|
||||
sslContext->set_password_callback(std::bind(&Net2::get_password, this));
|
||||
sslContext.set_options(boost::asio::ssl::context::default_workarounds);
|
||||
sslContext.set_verify_mode(boost::asio::ssl::context::verify_peer | boost::asio::ssl::verify_fail_if_no_peer_cert);
|
||||
if (policy) {
|
||||
sslContext.set_verify_callback([policy](bool preverified, boost::asio::ssl::verify_context& ctx) {
|
||||
return policy->verify_peer(preverified, ctx.native_handle());
|
||||
});
|
||||
} else {
|
||||
sslContext.set_verify_callback(boost::bind(&insecurely_always_accept, _1, _2));
|
||||
}
|
||||
|
||||
if (tlsParams.tlsCertPath.size() ) {
|
||||
sslContext->use_certificate_chain_file(tlsParams.tlsCertPath);
|
||||
}
|
||||
if (tlsParams.tlsCertBytes.size() ) {
|
||||
sslContext->use_certificate(boost::asio::buffer(tlsParams.tlsCertBytes.data(), tlsParams.tlsCertBytes.size()), boost::asio::ssl::context::pem);
|
||||
}
|
||||
if (tlsParams.tlsCAPath.size()) {
|
||||
std::string cert = readFileBytes(tlsParams.tlsCAPath, CERT_FILE_MAX_SIZE);
|
||||
sslContext->add_certificate_authority(boost::asio::buffer(cert.data(), cert.size()));
|
||||
}
|
||||
if (tlsParams.tlsCABytes.size()) {
|
||||
sslContext->add_certificate_authority(boost::asio::buffer(tlsParams.tlsCABytes.data(), tlsParams.tlsCABytes.size()));
|
||||
}
|
||||
if (tlsParams.tlsKeyPath.size()) {
|
||||
sslContext->use_private_key_file(tlsParams.tlsKeyPath, boost::asio::ssl::context::pem);
|
||||
}
|
||||
if (tlsParams.tlsKeyBytes.size()) {
|
||||
sslContext->use_private_key(boost::asio::buffer(tlsParams.tlsKeyBytes.data(), tlsParams.tlsKeyBytes.size()), boost::asio::ssl::context::pem);
|
||||
}
|
||||
sslContext.set_password_callback(std::bind(&Net2::get_password, this));
|
||||
|
||||
if (tlsParams.tlsCertPath.size() ) {
|
||||
sslContext.use_certificate_chain_file(tlsParams.tlsCertPath);
|
||||
}
|
||||
if (tlsParams.tlsCertBytes.size() ) {
|
||||
sslContext.use_certificate(boost::asio::buffer(tlsParams.tlsCertBytes.data(), tlsParams.tlsCertBytes.size()), boost::asio::ssl::context::pem);
|
||||
}
|
||||
if (tlsParams.tlsCAPath.size()) {
|
||||
std::string cert = readFileBytes(tlsParams.tlsCAPath, CERT_FILE_MAX_SIZE);
|
||||
sslContext.add_certificate_authority(boost::asio::buffer(cert.data(), cert.size()));
|
||||
}
|
||||
if (tlsParams.tlsCABytes.size()) {
|
||||
sslContext.add_certificate_authority(boost::asio::buffer(tlsParams.tlsCABytes.data(), tlsParams.tlsCABytes.size()));
|
||||
}
|
||||
if (tlsParams.tlsKeyPath.size()) {
|
||||
sslContext.use_private_key_file(tlsParams.tlsKeyPath, boost::asio::ssl::context::pem);
|
||||
}
|
||||
if (tlsParams.tlsKeyBytes.size()) {
|
||||
sslContext.use_private_key(boost::asio::buffer(tlsParams.tlsKeyBytes.data(), tlsParams.tlsKeyBytes.size()), boost::asio::ssl::context::pem);
|
||||
}
|
||||
|
||||
// Set the global members
|
||||
@ -1248,7 +1261,7 @@ THREAD_HANDLE Net2::startThread( THREAD_FUNC_RETURN (*func) (void*), void *arg )
|
||||
|
||||
Future< Reference<IConnection> > Net2::connect( NetworkAddress toAddr, std::string host ) {
|
||||
if ( toAddr.isTLS() ) {
|
||||
return SSLConnection::connect(&this->reactor.ios, this->sslContext, toAddr);
|
||||
return SSLConnection::connect(&this->reactor.ios, &this->sslContext, toAddr);
|
||||
}
|
||||
|
||||
return Connection::connect(&this->reactor.ios, toAddr);
|
||||
@ -1325,7 +1338,7 @@ bool Net2::isAddressOnThisHost( NetworkAddress const& addr ) {
|
||||
Reference<IListener> Net2::listen( NetworkAddress localAddr ) {
|
||||
try {
|
||||
if ( localAddr.isTLS() ) {
|
||||
return Reference<IListener>(new SSLListener( reactor.ios, this->sslContext, localAddr ));
|
||||
return Reference<IListener>(new SSLListener( reactor.ios, &this->sslContext, localAddr ));
|
||||
}
|
||||
return Reference<IListener>( new Listener( reactor.ios, localAddr ) );
|
||||
} catch (boost::system::system_error const& e) {
|
||||
@ -1421,22 +1434,9 @@ void ASIOReactor::wake() {
|
||||
|
||||
} // namespace net2
|
||||
|
||||
bool insecurely_always_accept(bool _1, boost::asio::ssl::verify_context& _2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
INetwork* newNet2(boost::asio::ssl::context* sslContext, bool useThreadPool, bool useMetrics, Reference<TLSPolicy> policy, const TLSParams& tlsParams) {
|
||||
INetwork* newNet2(bool useThreadPool, bool useMetrics, Reference<TLSPolicy> policy, const TLSParams& tlsParams) {
|
||||
try {
|
||||
sslContext->set_options(boost::asio::ssl::context::default_workarounds);
|
||||
sslContext->set_verify_mode(boost::asio::ssl::context::verify_peer | boost::asio::ssl::verify_fail_if_no_peer_cert);
|
||||
if (policy) {
|
||||
sslContext->set_verify_callback([policy](bool preverified, boost::asio::ssl::verify_context& ctx) {
|
||||
return policy->verify_peer(preverified, ctx.native_handle());
|
||||
});
|
||||
} else {
|
||||
sslContext->set_verify_callback(boost::bind(&insecurely_always_accept, _1, _2));
|
||||
}
|
||||
N2::g_net2 = new N2::Net2(useThreadPool, useMetrics, sslContext, tlsParams);
|
||||
N2::g_net2 = new N2::Net2(useThreadPool, useMetrics, policy, tlsParams);
|
||||
}
|
||||
catch(boost::system::system_error e) {
|
||||
TraceEvent("Net2InitError").detail("Message", e.what());
|
||||
|
@ -30,6 +30,8 @@
|
||||
#include "flow/FastRef.h"
|
||||
|
||||
struct TLSParams {
|
||||
enum { OPT_TLS = 100000, OPT_TLS_PLUGIN, OPT_TLS_CERTIFICATES, OPT_TLS_KEY, OPT_TLS_VERIFY_PEERS, OPT_TLS_CA_FILE, OPT_TLS_PASSWORD };
|
||||
|
||||
std::string tlsCertPath, tlsKeyPath, tlsCAPath, tlsPassword;
|
||||
std::string tlsCertBytes, tlsKeyBytes, tlsCABytes;
|
||||
};
|
||||
@ -105,4 +107,34 @@ public:
|
||||
bool is_client;
|
||||
};
|
||||
|
||||
#define TLS_PLUGIN_FLAG "--tls_plugin"
|
||||
#define TLS_CERTIFICATE_FILE_FLAG "--tls_certificate_file"
|
||||
#define TLS_KEY_FILE_FLAG "--tls_key_file"
|
||||
#define TLS_VERIFY_PEERS_FLAG "--tls_verify_peers"
|
||||
#define TLS_CA_FILE_FLAG "--tls_ca_file"
|
||||
#define TLS_PASSWORD_FLAG "--tls_password"
|
||||
|
||||
#define TLS_OPTION_FLAGS \
|
||||
{ TLSParams::OPT_TLS_PLUGIN, TLS_PLUGIN_FLAG, SO_REQ_SEP }, \
|
||||
{ TLSParams::OPT_TLS_CERTIFICATES, TLS_CERTIFICATE_FILE_FLAG, SO_REQ_SEP }, \
|
||||
{ TLSParams::OPT_TLS_KEY, TLS_KEY_FILE_FLAG, SO_REQ_SEP }, \
|
||||
{ TLSParams::OPT_TLS_VERIFY_PEERS, TLS_VERIFY_PEERS_FLAG, SO_REQ_SEP }, \
|
||||
{ TLSParams::OPT_TLS_PASSWORD, TLS_PASSWORD_FLAG, SO_REQ_SEP }, \
|
||||
{ TLSParams::OPT_TLS_CA_FILE, TLS_CA_FILE_FLAG, SO_REQ_SEP },
|
||||
|
||||
#define TLS_HELP \
|
||||
" " TLS_CERTIFICATE_FILE_FLAG " CERTFILE\n" \
|
||||
" The path of a file containing the TLS certificate and CA\n" \
|
||||
" chain.\n" \
|
||||
" " TLS_CA_FILE_FLAG " CERTAUTHFILE\n" \
|
||||
" The path of a file containing the CA certificates chain.\n" \
|
||||
" " TLS_KEY_FILE_FLAG " KEYFILE\n" \
|
||||
" The path of a file containing the private key corresponding\n" \
|
||||
" to the TLS certificate.\n" \
|
||||
" " TLS_PASSWORD_FLAG " PASSCODE\n" \
|
||||
" The passphrase of encrypted private key\n" \
|
||||
" " TLS_VERIFY_PEERS_FLAG " CONSTRAINTS\n" \
|
||||
" The constraints by which to validate TLS peers. The contents\n" \
|
||||
" and format of CONSTRAINTS are plugin-specific.\n"
|
||||
|
||||
#endif
|
||||
|
@ -406,7 +406,7 @@ typedef NetworkAddressList (*NetworkAddressesFuncPtr)();
|
||||
|
||||
class INetwork;
|
||||
extern INetwork* g_network;
|
||||
extern INetwork* newNet2(boost::asio::ssl::context* sslContext, bool useThreadPool = false, bool useMetrics = false, Reference<TLSPolicy> policy = Reference<TLSPolicy>(), const TLSParams& tlsParams = TLSParams());
|
||||
extern INetwork* newNet2(bool useThreadPool = false, bool useMetrics = false, Reference<TLSPolicy> policy = Reference<TLSPolicy>(), const TLSParams& tlsParams = TLSParams());
|
||||
|
||||
class INetwork {
|
||||
public:
|
||||
|
Loading…
x
Reference in New Issue
Block a user