aboutsummaryrefslogtreecommitdiff
path: root/contrib/epee/src
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/epee/src')
-rw-r--r--contrib/epee/src/CMakeLists.txt4
-rw-r--r--contrib/epee/src/connection_basic.cpp48
-rw-r--r--contrib/epee/src/hex.cpp65
-rw-r--r--contrib/epee/src/http_auth.cpp2
-rw-r--r--contrib/epee/src/memwipe.c2
-rw-r--r--contrib/epee/src/net_ssl.cpp324
-rw-r--r--contrib/epee/src/network_throttle-detail.cpp8
-rw-r--r--contrib/epee/src/network_throttle.cpp2
-rw-r--r--contrib/epee/src/wipeable_string.cpp2
9 files changed, 436 insertions, 21 deletions
diff --git a/contrib/epee/src/CMakeLists.txt b/contrib/epee/src/CMakeLists.txt
index cea50c9dd..0787a9d08 100644
--- a/contrib/epee/src/CMakeLists.txt
+++ b/contrib/epee/src/CMakeLists.txt
@@ -1,4 +1,4 @@
-# Copyright (c) 2014-2018, The Monero Project
+# Copyright (c) 2014-2019, The Monero Project
#
# All rights reserved.
#
@@ -27,7 +27,7 @@
# THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
add_library(epee STATIC hex.cpp http_auth.cpp mlog.cpp net_utils_base.cpp string_tools.cpp wipeable_string.cpp memwipe.c
- connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp)
+ connection_basic.cpp network_throttle.cpp network_throttle-detail.cpp mlocker.cpp buffer.cpp net_ssl.cpp)
if (USE_READLINE AND GNU_READLINE_FOUND)
add_library(epee_readline STATIC readline_buffer.cpp)
endif()
diff --git a/contrib/epee/src/connection_basic.cpp b/contrib/epee/src/connection_basic.cpp
index f5f9b59fe..83db171d8 100644
--- a/contrib/epee/src/connection_basic.cpp
+++ b/contrib/epee/src/connection_basic.cpp
@@ -2,7 +2,7 @@
/// @author rfree (current maintainer in monero.cc project)
/// @brief base for connection, contains e.g. the ratelimit hooks
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
@@ -48,7 +48,7 @@
#include "net/network_throttle-detail.hpp"
#undef MONERO_DEFAULT_LOG_CATEGORY
-#define MONERO_DEFAULT_LOG_CATEGORY "net.p2p"
+#define MONERO_DEFAULT_LOG_CATEGORY "net.conn"
// ################################################################################################
// local (TU local) headers
@@ -113,14 +113,41 @@ connection_basic_pimpl::connection_basic_pimpl(const std::string &name) : m_thro
int connection_basic_pimpl::m_default_tos;
// methods:
-connection_basic::connection_basic(boost::asio::ip::tcp::socket&& socket, boost::shared_ptr<socket_stats> stats)
+connection_basic::connection_basic(boost::asio::ip::tcp::socket&& sock, boost::shared_ptr<socket_stats> stats, ssl_support_t ssl_support, ssl_context_t &ssl_context)
:
m_stats(std::move(stats)),
mI( new connection_basic_pimpl("peer") ),
- strand_(socket.get_io_service()),
- socket_(std::move(socket)),
+ strand_(sock.get_io_service()),
+ socket_(sock.get_io_service(), ssl_context.context),
+ m_want_close_connection(false),
+ m_was_shutdown(false),
+ m_ssl_support(ssl_support),
+ m_ssl_context(ssl_context)
+{
+ // add nullptr checks if removed
+ CHECK_AND_ASSERT_THROW_MES(bool(m_stats), "stats shared_ptr cannot be null");
+
+ socket_.next_layer() = std::move(sock);
+
+ ++(m_stats->sock_count); // increase the global counter
+ mI->m_peer_number = m_stats->sock_number.fetch_add(1); // use, and increase the generated number
+
+ std::string remote_addr_str = "?";
+ try { boost::system::error_code e; remote_addr_str = socket().remote_endpoint(e).address().to_string(); } catch(...){} ;
+
+ _note("Spawned connection #"<<mI->m_peer_number<<" to " << remote_addr_str << " currently we have sockets count:" << m_stats->sock_count);
+}
+
+connection_basic::connection_basic(boost::asio::io_service &io_service, boost::shared_ptr<socket_stats> stats, ssl_support_t ssl_support, ssl_context_t &ssl_context)
+ :
+ m_stats(std::move(stats)),
+ mI( new connection_basic_pimpl("peer") ),
+ strand_(io_service),
+ socket_(io_service, ssl_context.context),
m_want_close_connection(false),
- m_was_shutdown(false)
+ m_was_shutdown(false),
+ m_ssl_support(ssl_support),
+ m_ssl_context(ssl_context)
{
// add nullptr checks if removed
CHECK_AND_ASSERT_THROW_MES(bool(m_stats), "stats shared_ptr cannot be null");
@@ -129,17 +156,18 @@ connection_basic::connection_basic(boost::asio::ip::tcp::socket&& socket, boost:
mI->m_peer_number = m_stats->sock_number.fetch_add(1); // use, and increase the generated number
std::string remote_addr_str = "?";
- try { boost::system::error_code e; remote_addr_str = socket_.remote_endpoint(e).address().to_string(); } catch(...){} ;
+ try { boost::system::error_code e; remote_addr_str = socket().remote_endpoint(e).address().to_string(); } catch(...){} ;
- _note("Spawned connection p2p#"<<mI->m_peer_number<<" to " << remote_addr_str << " currently we have sockets count:" << m_stats->sock_count);
+ _note("Spawned connection #"<<mI->m_peer_number<<" to " << remote_addr_str << " currently we have sockets count:" << m_stats->sock_count);
}
connection_basic::~connection_basic() noexcept(false) {
--(m_stats->sock_count);
std::string remote_addr_str = "?";
- try { boost::system::error_code e; remote_addr_str = socket_.remote_endpoint(e).address().to_string(); } catch(...){} ;
- _note("Destructing connection p2p#"<<mI->m_peer_number << " to " << remote_addr_str);
+ try { boost::system::error_code e; remote_addr_str = socket().remote_endpoint(e).address().to_string(); } catch(...){} ;
+ _note("Destructing connection #"<<mI->m_peer_number << " to " << remote_addr_str);
+try { throw 0; } catch(...){}
}
void connection_basic::set_rate_up_limit(uint64_t limit) {
diff --git a/contrib/epee/src/hex.cpp b/contrib/epee/src/hex.cpp
index 5c8acc8be..558983f7e 100644
--- a/contrib/epee/src/hex.cpp
+++ b/contrib/epee/src/hex.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017-2018, The Monero Project
+// Copyright (c) 2017-2019, The Monero Project
//
// All rights reserved.
//
@@ -83,4 +83,67 @@ namespace epee
{
return write_hex(out, src);
}
+
+ std::vector<uint8_t> from_hex::vector(boost::string_ref src)
+ {
+ // should we include a specific character
+ auto include = [](char input) {
+ // we ignore spaces and colons
+ return !std::isspace(input) && input != ':';
+ };
+
+ // the number of relevant characters to decode
+ auto count = std::count_if(src.begin(), src.end(), include);
+
+ // this must be a multiple of two, otherwise we have a truncated input
+ if (count % 2) {
+ throw std::length_error{ "Invalid hexadecimal input length" };
+ }
+
+ std::vector<uint8_t> result;
+ result.reserve(count / 2);
+
+ // the data to work with (std::string is always null-terminated)
+ auto data = src.data();
+
+ // convert a single hex character to an unsigned integer
+ auto char_to_int = [](const char *input) {
+ switch (std::tolower(*input)) {
+ case '0': return 0;
+ case '1': return 1;
+ case '2': return 2;
+ case '3': return 3;
+ case '4': return 4;
+ case '5': return 5;
+ case '6': return 6;
+ case '7': return 7;
+ case '8': return 8;
+ case '9': return 9;
+ case 'a': return 10;
+ case 'b': return 11;
+ case 'c': return 12;
+ case 'd': return 13;
+ case 'e': return 14;
+ case 'f': return 15;
+ default: throw std::range_error{ "Invalid hexadecimal input" };
+ }
+ };
+
+ // keep going until we reach the end
+ while (data[0] != '\0') {
+ // skip unwanted characters
+ if (!include(data[0])) {
+ ++data;
+ continue;
+ }
+
+ // convert two matching characters to int
+ auto high = char_to_int(data++);
+ auto low = char_to_int(data++);
+
+ result.push_back(high << 4 | low);
+ }
+
+ return result;
+ }
}
diff --git a/contrib/epee/src/http_auth.cpp b/contrib/epee/src/http_auth.cpp
index dc968d971..289069daa 100644
--- a/contrib/epee/src/http_auth.cpp
+++ b/contrib/epee/src/http_auth.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/contrib/epee/src/memwipe.c b/contrib/epee/src/memwipe.c
index c2a26c392..ad1ef510d 100644
--- a/contrib/epee/src/memwipe.c
+++ b/contrib/epee/src/memwipe.c
@@ -1,4 +1,4 @@
-// Copyright (c) 2017-2018, The Monero Project
+// Copyright (c) 2017-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/contrib/epee/src/net_ssl.cpp b/contrib/epee/src/net_ssl.cpp
new file mode 100644
index 000000000..eb0b0ad65
--- /dev/null
+++ b/contrib/epee/src/net_ssl.cpp
@@ -0,0 +1,324 @@
+// Copyright (c) 2018, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include <string.h>
+#include <boost/asio/ssl.hpp>
+#include <openssl/ssl.h>
+#include <openssl/pem.h>
+#include "misc_log_ex.h"
+#include "net/net_ssl.h"
+
+#undef MONERO_DEFAULT_LOG_CATEGORY
+#define MONERO_DEFAULT_LOG_CATEGORY "net.ssl"
+
+// openssl genrsa -out /tmp/KEY 4096
+// openssl req -new -key /tmp/KEY -out /tmp/REQ
+// openssl x509 -req -days 999999 -sha256 -in /tmp/REQ -signkey /tmp/KEY -out /tmp/CERT
+
+namespace
+{
+ struct openssl_bio_free
+ {
+ void operator()(BIO* ptr) const noexcept
+ {
+ if (ptr)
+ BIO_free(ptr);
+ }
+ };
+ using openssl_bio = std::unique_ptr<BIO, openssl_bio_free>;
+
+ struct openssl_pkey_free
+ {
+ void operator()(EVP_PKEY* ptr) const noexcept
+ {
+ if (ptr)
+ EVP_PKEY_free(ptr);
+ }
+ };
+ using openssl_pkey = std::unique_ptr<EVP_PKEY, openssl_pkey_free>;
+
+}
+
+namespace epee
+{
+namespace net_utils
+{
+
+// https://stackoverflow.com/questions/256405/programmatically-create-x509-certificate-using-openssl
+bool create_ssl_certificate(EVP_PKEY *&pkey, X509 *&cert)
+{
+ MGINFO("Generating SSL certificate");
+ pkey = EVP_PKEY_new();
+ if (!pkey)
+ {
+ MERROR("Failed to create new private key");
+ return false;
+ }
+
+ openssl_pkey pkey_deleter{pkey};
+ RSA *rsa = RSA_generate_key(4096, RSA_F4, NULL, NULL);
+ if (!rsa)
+ {
+ MERROR("Error generating RSA private key");
+ return false;
+ }
+ if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) // The RSA will be automatically freed when the EVP_PKEY structure is freed.
+ {
+ MERROR("Error assigning RSA private key");
+ RSA_free(rsa);
+ return false;
+ }
+
+ cert = X509_new();
+ if (!cert)
+ {
+ MERROR("Failed to create new X509 certificate");
+ return false;
+ }
+ ASN1_INTEGER_set(X509_get_serialNumber(cert), 1);
+ X509_gmtime_adj(X509_get_notBefore(cert), 0);
+ X509_gmtime_adj(X509_get_notAfter(cert), 3600 * 24 * 182); // half a year
+ if (!X509_set_pubkey(cert, pkey))
+ {
+ MERROR("Error setting pubkey on certificate");
+ X509_free(cert);
+ return false;
+ }
+ X509_NAME *name = X509_get_subject_name(cert);
+ X509_set_issuer_name(cert, name);
+
+ if (X509_sign(cert, pkey, EVP_sha256()) == 0)
+ {
+ MERROR("Error signing certificate");
+ X509_free(cert);
+ return false;
+ }
+ (void)pkey_deleter.release();
+ return true;
+}
+
+ssl_context_t create_ssl_context(const std::pair<std::string, std::string> &private_key_and_certificate_path, std::list<std::string> allowed_certificates, std::vector<std::vector<uint8_t>> allowed_fingerprints, bool allow_any_cert)
+{
+ ssl_context_t ssl_context{boost::asio::ssl::context(boost::asio::ssl::context::tlsv12), std::move(allowed_certificates), std::move(allowed_fingerprints)};
+
+ // only allow tls v1.2 and up
+ ssl_context.context.set_options(boost::asio::ssl::context::default_workarounds);
+ ssl_context.context.set_options(boost::asio::ssl::context::no_sslv2);
+ ssl_context.context.set_options(boost::asio::ssl::context::no_sslv3);
+ ssl_context.context.set_options(boost::asio::ssl::context::no_tlsv1);
+ ssl_context.context.set_options(boost::asio::ssl::context::no_tlsv1_1);
+
+ // only allow a select handful of tls v1.3 and v1.2 ciphers to be used
+ SSL_CTX_set_cipher_list(ssl_context.context.native_handle(), "ECDHE-ECDSA-CHACHA20-POLY1305-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-CHACHA20-POLY1305");
+
+ // set options on the SSL context for added security
+ SSL_CTX *ctx = ssl_context.context.native_handle();
+ CHECK_AND_ASSERT_THROW_MES(ctx, "Failed to get SSL context");
+ SSL_CTX_clear_options(ctx, SSL_OP_LEGACY_SERVER_CONNECT); // SSL_CTX_SET_OPTIONS(3)
+ SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF); // https://stackoverflow.com/questions/22378442
+#ifdef SSL_OP_NO_TICKET
+ SSL_CTX_set_options(ctx, SSL_OP_NO_TICKET); // https://stackoverflow.com/questions/22378442
+#endif
+#ifdef SSL_OP_NO_RENEGOTIATION
+ SSL_CTX_set_options(ctx, SSL_OP_NO_RENEGOTIATION);
+#endif
+#ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
+ SSL_CTX_set_options(ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
+#endif
+#ifdef SSL_OP_NO_COMPRESSION
+ SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION);
+#endif
+ ssl_context.context.set_default_verify_paths();
+
+ CHECK_AND_ASSERT_THROW_MES(private_key_and_certificate_path.first.empty() == private_key_and_certificate_path.second.empty(), "private key and certificate must be either both given or both empty");
+ if (private_key_and_certificate_path.second.empty())
+ {
+ EVP_PKEY *pkey;
+ X509 *cert;
+ CHECK_AND_ASSERT_THROW_MES(create_ssl_certificate(pkey, cert), "Failed to create certificate");
+ CHECK_AND_ASSERT_THROW_MES(SSL_CTX_use_certificate(ctx, cert), "Failed to use generated certificate");
+ // don't free the cert, the CTX owns it now
+ CHECK_AND_ASSERT_THROW_MES(SSL_CTX_use_PrivateKey(ctx, pkey), "Failed to use generated private key");
+ EVP_PKEY_free(pkey);
+ }
+ else
+ {
+ ssl_context.context.use_private_key_file(private_key_and_certificate_path.first, boost::asio::ssl::context::pem);
+ ssl_context.context.use_certificate_file(private_key_and_certificate_path.second, boost::asio::ssl::context::pem);
+ }
+ ssl_context.allow_any_cert = allow_any_cert;
+
+ return ssl_context;
+}
+
+void use_ssl_certificate(ssl_context_t &ssl_context, const std::pair<std::string, std::string> &private_key_and_certificate_path)
+{
+ ssl_context.context.use_private_key_file(private_key_and_certificate_path.first, boost::asio::ssl::context::pem);
+ ssl_context.context.use_certificate_file(private_key_and_certificate_path.second, boost::asio::ssl::context::pem);
+}
+
+bool is_ssl(const unsigned char *data, size_t len)
+{
+ if (len < get_ssl_magic_size())
+ return false;
+
+ // https://security.stackexchange.com/questions/34780/checking-client-hello-for-https-classification
+ MDEBUG("SSL detection buffer, " << len << " bytes: "
+ << (unsigned)(unsigned char)data[0] << " " << (unsigned)(unsigned char)data[1] << " "
+ << (unsigned)(unsigned char)data[2] << " " << (unsigned)(unsigned char)data[3] << " "
+ << (unsigned)(unsigned char)data[4] << " " << (unsigned)(unsigned char)data[5] << " "
+ << (unsigned)(unsigned char)data[6] << " " << (unsigned)(unsigned char)data[7] << " "
+ << (unsigned)(unsigned char)data[8]);
+ if (data[0] == 0x16) // record
+ if (data[1] == 3) // major version
+ if (data[5] == 1) // ClientHello
+ if (data[6] == 0 && data[3]*256 + data[4] == data[7]*256 + data[8] + 4) // length check
+ return true;
+ return false;
+}
+
+bool is_certificate_allowed(boost::asio::ssl::verify_context &ctx, const ssl_context_t &ssl_context)
+{
+ X509_STORE_CTX *sctx = ctx.native_handle();
+ if (!sctx)
+ {
+ MERROR("Error getting verify_context handle");
+ return false;
+ }
+ X509 *cert =X509_STORE_CTX_get_current_cert(sctx);
+ if (!cert)
+ {
+ MERROR("No certificate found in verify_context");
+ return false;
+ }
+
+ // can we check the certificate against a list of fingerprints?
+ if (!ssl_context.allowed_fingerprints.empty()) {
+ // buffer for the certificate digest and the size of the result
+ std::vector<uint8_t> digest(EVP_MAX_MD_SIZE);
+ unsigned int size{ 0 };
+
+ // create the digest from the certificate
+ if (!X509_digest(cert, EVP_sha1(), digest.data(), &size)) {
+ MERROR("Failed to create certificate fingerprint");
+ return false;
+ }
+
+ // strip unnecessary bytes from the digest
+ digest.resize(size);
+
+ // is the certificate fingerprint inside the list of allowed fingerprints?
+ if (std::find(ssl_context.allowed_fingerprints.begin(), ssl_context.allowed_fingerprints.end(), digest) != ssl_context.allowed_fingerprints.end())
+ return true;
+ }
+
+ if (!ssl_context.allowed_certificates.empty()) {
+ BIO *bio_cert = BIO_new(BIO_s_mem());
+ bool success = PEM_write_bio_X509(bio_cert, cert);
+ if (!success)
+ {
+ BIO_free(bio_cert);
+ MERROR("Failed to print certificate");
+ return false;
+ }
+ BUF_MEM *buf = NULL;
+ BIO_get_mem_ptr(bio_cert, &buf);
+ if (!buf || !buf->data || !buf->length)
+ {
+ BIO_free(bio_cert);
+ MERROR("Failed to write certificate: " << ERR_get_error());
+ return false;
+ }
+ std::string certificate(std::string(buf->data, buf->length));
+ BIO_free(bio_cert);
+ if (std::find(ssl_context.allowed_certificates.begin(), ssl_context.allowed_certificates.end(), certificate) != ssl_context.allowed_certificates.end())
+ return true;
+ }
+
+ // if either checklist is non-empty we must have failed it
+ return ssl_context.allowed_fingerprints.empty() && ssl_context.allowed_certificates.empty();
+}
+
+bool ssl_handshake(boost::asio::ssl::stream<boost::asio::ip::tcp::socket> &socket, boost::asio::ssl::stream_base::handshake_type type, const epee::net_utils::ssl_context_t &ssl_context)
+{
+ bool verified = false;
+ socket.next_layer().set_option(boost::asio::ip::tcp::no_delay(true));
+ socket.set_verify_mode(boost::asio::ssl::verify_peer);
+ socket.set_verify_callback([&](bool preverified, boost::asio::ssl::verify_context &ctx)
+ {
+ if (!preverified)
+ {
+ const int err = X509_STORE_CTX_get_error(ctx.native_handle());
+ const int depth = X509_STORE_CTX_get_error_depth(ctx.native_handle());
+ if (err != X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT || depth != 0)
+ {
+ MERROR("Invalid SSL certificate, error " << err << " at depth " << depth << ", connection dropped");
+ return false;
+ }
+ }
+ if (!ssl_context.allow_any_cert && !is_certificate_allowed(ctx, ssl_context))
+ {
+ MERROR("Certificate is not in the allowed list, connection droppped");
+ return false;
+ }
+ verified = true;
+ return true;
+ });
+
+ boost::system::error_code ec;
+ socket.handshake(type, ec);
+ if (ec)
+ {
+ MERROR("handshake failed, connection dropped: " << ec.message());
+ return false;
+ }
+ if (!ssl_context.allow_any_cert && !verified)
+ {
+ MERROR("Peer did not provide a certificate in the allowed list, connection dropped");
+ return false;
+ }
+ MDEBUG("SSL handshake success");
+ return true;
+}
+
+bool ssl_support_from_string(ssl_support_t &ssl, boost::string_ref s)
+{
+ if (s == "enabled")
+ ssl = epee::net_utils::ssl_support_t::e_ssl_support_enabled;
+ else if (s == "disabled")
+ ssl = epee::net_utils::ssl_support_t::e_ssl_support_disabled;
+ else if (s == "autodetect")
+ ssl = epee::net_utils::ssl_support_t::e_ssl_support_autodetect;
+ else
+ return false;
+ return true;
+}
+
+} // namespace
+} // namespace
+
diff --git a/contrib/epee/src/network_throttle-detail.cpp b/contrib/epee/src/network_throttle-detail.cpp
index d2e776df0..f89e7aec0 100644
--- a/contrib/epee/src/network_throttle-detail.cpp
+++ b/contrib/epee/src/network_throttle-detail.cpp
@@ -2,7 +2,7 @@
/// @author rfree (current maintainer in monero.cc project)
/// @brief implementaion for throttling of connection (count and rate-limit speed etc)
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
@@ -135,6 +135,7 @@ network_throttle::network_throttle(const std::string &nameshort, const std::stri
m_slot_size = 1.0; // hard coded in few places
m_target_speed = 16 * 1024; // other defaults are probably defined in the command-line parsing code when this class is used e.g. as main global throttle
m_last_sample_time = 0;
+ m_history.resize(m_window_size);
}
void network_throttle::set_name(const std::string &name)
@@ -168,8 +169,7 @@ void network_throttle::tick()
{
_dbg3("Moving counter buffer by 1 second " << last_sample_time_slot << " < " << current_sample_time_slot << " (last time " << m_last_sample_time<<")");
// rotate buffer
- for (size_t i=m_history.size()-1; i>=1; --i) m_history[i] = m_history[i-1];
- m_history[0] = packet_info();
+ m_history.push_front(packet_info());
if (! m_any_packet_yet)
{
m_last_sample_time = time_now;
@@ -191,7 +191,7 @@ void network_throttle::_handle_trafic_exact(size_t packet_size, size_t orginal_s
calculate_times_struct cts ; calculate_times(packet_size, cts , false, -1);
calculate_times_struct cts2; calculate_times(packet_size, cts2, false, 5);
- m_history[0].m_size += packet_size;
+ m_history.front().m_size += packet_size;
std::ostringstream oss; oss << "["; for (auto sample: m_history) oss << sample.m_size << " "; oss << "]" << std::ends;
std::string history_str = oss.str();
diff --git a/contrib/epee/src/network_throttle.cpp b/contrib/epee/src/network_throttle.cpp
index 167738855..f4f0b2c46 100644
--- a/contrib/epee/src/network_throttle.cpp
+++ b/contrib/epee/src/network_throttle.cpp
@@ -26,7 +26,7 @@ Throttling work by:
*/
-// Copyright (c) 2014-2018, The Monero Project
+// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
diff --git a/contrib/epee/src/wipeable_string.cpp b/contrib/epee/src/wipeable_string.cpp
index 69f92e106..3a6ee5dac 100644
--- a/contrib/epee/src/wipeable_string.cpp
+++ b/contrib/epee/src/wipeable_string.cpp
@@ -1,4 +1,4 @@
-// Copyright (c) 2017-2018, The Monero Project
+// Copyright (c) 2017-2019, The Monero Project
//
// All rights reserved.
//