From 8cc17a4524d4494f39e87535c49e117f027e8db2 Mon Sep 17 00:00:00 2001 From: arvidn Date: Thu, 23 Mar 2017 19:35:46 -0400 Subject: [PATCH] optimize access to ssl_cert. specifically the case where there is none, avoid pessimisation of the common case --- include/libtorrent/announce_entry.hpp | 3 ++- include/libtorrent/torrent.hpp | 2 +- include/libtorrent/torrent_info.hpp | 8 ++++++-- src/announce_entry.cpp | 4 ++-- src/torrent.cpp | 6 +++--- src/torrent_info.cpp | 13 ++++++++++--- 6 files changed, 24 insertions(+), 12 deletions(-) diff --git a/include/libtorrent/announce_entry.hpp b/include/libtorrent/announce_entry.hpp index 6411e6c20..6fb3bbf08 100644 --- a/include/libtorrent/announce_entry.hpp +++ b/include/libtorrent/announce_entry.hpp @@ -36,6 +36,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/config.hpp" #include "libtorrent/time.hpp" #include "libtorrent/error_code.hpp" +#include "libtorrent/string_view.hpp" #include #include @@ -47,7 +48,7 @@ namespace libtorrent struct TORRENT_EXPORT announce_entry { // constructs a tracker announce entry with ``u`` as the URL. - explicit announce_entry(std::string u); + explicit announce_entry(string_view u); announce_entry(); ~announce_entry(); announce_entry(announce_entry const&) = default; diff --git a/include/libtorrent/torrent.hpp b/include/libtorrent/torrent.hpp index baf557ded..9c2fcbc37 100644 --- a/include/libtorrent/torrent.hpp +++ b/include/libtorrent/torrent.hpp @@ -1202,7 +1202,7 @@ namespace libtorrent bool verify_peer_cert(bool preverified, boost::asio::ssl::verify_context& ctx); - void init_ssl(std::string const& cert); + void init_ssl(string_view cert); #endif void setup_peer_class(); diff --git a/include/libtorrent/torrent_info.hpp b/include/libtorrent/torrent_info.hpp index e8039e5c8..ec2321e50 100644 --- a/include/libtorrent/torrent_info.hpp +++ b/include/libtorrent/torrent_info.hpp @@ -400,7 +400,7 @@ namespace libtorrent // Returns the SSL root certificate for the torrent, if it is an SSL // torrent. Otherwise returns an empty string. The certificate is // the the public certificate in x509 format. - std::string ssl_cert() const; + string_view ssl_cert() const; // returns true if this torrent_info object has a torrent loaded. // This is primarily used to determine if a magnet link has had its @@ -643,7 +643,11 @@ namespace libtorrent // domain in its hostname. This means the DHT and LSD // features are disabled for this torrent (unless the // settings allows mixing i2p peers with regular peers) - i2p = 4 + i2p = 4, + + // this flag is set if we found an ssl-cert field in the info + // dictionary + ssl_torrent = 8, }; // any combination of values from flags_t enum diff --git a/src/announce_entry.cpp b/src/announce_entry.cpp index 54bff6227..7e18138e6 100644 --- a/src/announce_entry.cpp +++ b/src/announce_entry.cpp @@ -46,8 +46,8 @@ namespace libtorrent minutes32 constexpr tracker_retry_delay_max{60}; } - announce_entry::announce_entry(std::string u) - : url(std::move(u)) + announce_entry::announce_entry(string_view u) + : url(u.to_string()) , fails(0) , updating(false) , source(0) diff --git a/src/torrent.cpp b/src/torrent.cpp index 0ba630c36..d4a2ad56b 100644 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -1468,7 +1468,7 @@ namespace libtorrent #endif } - void torrent::init_ssl(std::string const& cert) + void torrent::init_ssl(string_view cert) { using boost::asio::ssl::context; @@ -1537,7 +1537,7 @@ namespace libtorrent // wrap the PEM certificate in a BIO, for openssl to read BIO* bp = BIO_new_mem_buf( - const_cast(static_cast(cert.c_str())) + const_cast(static_cast(cert.data())) , int(cert.size())); // parse the certificate into OpenSSL's internal @@ -1646,7 +1646,7 @@ namespace libtorrent if (int(m_file_priority.size()) > m_torrent_file->num_files()) m_file_priority.resize(m_torrent_file->num_files()); - std::string cert = m_torrent_file->ssl_cert(); + auto cert = m_torrent_file->ssl_cert(); if (!cert.empty()) { m_ssl_torrent = true; diff --git a/src/torrent_info.cpp b/src/torrent_info.cpp index c77f7fed4..73f50b2d8 100644 --- a/src/torrent_info.cpp +++ b/src/torrent_info.cpp @@ -1017,18 +1017,22 @@ namespace libtorrent swap(m_flags, ti.m_flags); } - std::string torrent_info::ssl_cert() const + string_view torrent_info::ssl_cert() const { + if ((m_flags & ssl_torrent) == 0) return ""; + // this is parsed lazily if (!m_info_dict) { error_code ec; bdecode(m_info_section.get(), m_info_section.get() + m_info_section_size, m_info_dict, ec); + TORRENT_ASSERT(!ec); if (ec) return ""; } + TORRENT_ASSERT(m_info_dict.type() == bdecode_node::dict_t); if (m_info_dict.type() != bdecode_node::dict_t) return ""; - return m_info_dict.dict_find_string_value("ssl-cert").to_string(); + return m_info_dict.dict_find_string_value("ssl-cert"); } bool torrent_info::parse_info_section(bdecode_node const& info @@ -1207,6 +1211,9 @@ namespace libtorrent } #endif // TORRENT_DISABLE_MUTABLE_TORRENTS + if (info.dict_find_string("ssl-cert")) + m_flags |= ssl_torrent; + // now, commit the files structure we just parsed out // into the torrent_info object. m_files.swap(files); @@ -1411,7 +1418,7 @@ namespace libtorrent if (m_urls.empty()) { - announce_entry e(torrent_file.dict_find_string_value("announce").to_string()); + announce_entry e(torrent_file.dict_find_string_value("announce")); e.fail_limit = 0; e.source = announce_entry::source_torrent; e.trim();