optimize access to ssl_cert. specifically the case where there is none, avoid pessimisation of the common case

This commit is contained in:
arvidn 2017-03-23 19:35:46 -04:00 committed by Arvid Norberg
parent 488c1a2dcf
commit 8cc17a4524
6 changed files with 24 additions and 12 deletions

View File

@ -36,6 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/config.hpp" #include "libtorrent/config.hpp"
#include "libtorrent/time.hpp" #include "libtorrent/time.hpp"
#include "libtorrent/error_code.hpp" #include "libtorrent/error_code.hpp"
#include "libtorrent/string_view.hpp"
#include <string> #include <string>
#include <cstdint> #include <cstdint>
@ -47,7 +48,7 @@ namespace libtorrent
struct TORRENT_EXPORT announce_entry struct TORRENT_EXPORT announce_entry
{ {
// constructs a tracker announce entry with ``u`` as the URL. // 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();
announce_entry(announce_entry const&) = default; announce_entry(announce_entry const&) = default;

View File

@ -1202,7 +1202,7 @@ namespace libtorrent
bool verify_peer_cert(bool preverified, boost::asio::ssl::verify_context& ctx); 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 #endif
void setup_peer_class(); void setup_peer_class();

View File

@ -400,7 +400,7 @@ namespace libtorrent
// Returns the SSL root certificate for the torrent, if it is an SSL // Returns the SSL root certificate for the torrent, if it is an SSL
// torrent. Otherwise returns an empty string. The certificate is // torrent. Otherwise returns an empty string. The certificate is
// the the public certificate in x509 format. // 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. // returns true if this torrent_info object has a torrent loaded.
// This is primarily used to determine if a magnet link has had its // 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 // domain in its hostname. This means the DHT and LSD
// features are disabled for this torrent (unless the // features are disabled for this torrent (unless the
// settings allows mixing i2p peers with regular peers) // 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 // any combination of values from flags_t enum

View File

@ -46,8 +46,8 @@ namespace libtorrent
minutes32 constexpr tracker_retry_delay_max{60}; minutes32 constexpr tracker_retry_delay_max{60};
} }
announce_entry::announce_entry(std::string u) announce_entry::announce_entry(string_view u)
: url(std::move(u)) : url(u.to_string())
, fails(0) , fails(0)
, updating(false) , updating(false)
, source(0) , source(0)

View File

@ -1468,7 +1468,7 @@ namespace libtorrent
#endif #endif
} }
void torrent::init_ssl(std::string const& cert) void torrent::init_ssl(string_view cert)
{ {
using boost::asio::ssl::context; using boost::asio::ssl::context;
@ -1537,7 +1537,7 @@ namespace libtorrent
// wrap the PEM certificate in a BIO, for openssl to read // wrap the PEM certificate in a BIO, for openssl to read
BIO* bp = BIO_new_mem_buf( BIO* bp = BIO_new_mem_buf(
const_cast<void*>(static_cast<void const*>(cert.c_str())) const_cast<void*>(static_cast<void const*>(cert.data()))
, int(cert.size())); , int(cert.size()));
// parse the certificate into OpenSSL's internal // parse the certificate into OpenSSL's internal
@ -1646,7 +1646,7 @@ namespace libtorrent
if (int(m_file_priority.size()) > m_torrent_file->num_files()) if (int(m_file_priority.size()) > m_torrent_file->num_files())
m_file_priority.resize(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()) if (!cert.empty())
{ {
m_ssl_torrent = true; m_ssl_torrent = true;

View File

@ -1017,18 +1017,22 @@ namespace libtorrent
swap(m_flags, ti.m_flags); 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 // this is parsed lazily
if (!m_info_dict) if (!m_info_dict)
{ {
error_code ec; error_code ec;
bdecode(m_info_section.get(), m_info_section.get() bdecode(m_info_section.get(), m_info_section.get()
+ m_info_section_size, m_info_dict, ec); + m_info_section_size, m_info_dict, ec);
TORRENT_ASSERT(!ec);
if (ec) return ""; if (ec) return "";
} }
TORRENT_ASSERT(m_info_dict.type() == bdecode_node::dict_t);
if (m_info_dict.type() != bdecode_node::dict_t) return ""; 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 bool torrent_info::parse_info_section(bdecode_node const& info
@ -1207,6 +1211,9 @@ namespace libtorrent
} }
#endif // TORRENT_DISABLE_MUTABLE_TORRENTS #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 // now, commit the files structure we just parsed out
// into the torrent_info object. // into the torrent_info object.
m_files.swap(files); m_files.swap(files);
@ -1411,7 +1418,7 @@ namespace libtorrent
if (m_urls.empty()) 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.fail_limit = 0;
e.source = announce_entry::source_torrent; e.source = announce_entry::source_torrent;
e.trim(); e.trim();