merged lt_tex fix from RC_0_16

This commit is contained in:
Arvid Norberg 2014-01-26 01:17:58 +00:00
parent 43bc1954fa
commit ce2805a258
8 changed files with 89 additions and 12 deletions

View File

@ -39,6 +39,7 @@
* fix uTP edge case where udp socket buffer fills up
* fix nagle implementation in uTP
* make lt_tex more robust against bugs and malicious behavior
* HTTP chunked encoding fix
* expose file_granularity flag to python bindings
* fix DHT memory error

View File

@ -53,6 +53,8 @@ namespace libtorrent
// it will be encoded
TORRENT_EXTRA_EXPORT std::string maybe_url_encode(std::string const& url);
// returns true if the given string (not null terminated) contains
// characters that would need to be escaped if used in a URL
TORRENT_EXTRA_EXPORT bool need_encoding(char const* str, int len);
// encodes a string using the base64 scheme

View File

@ -50,6 +50,7 @@ POSSIBILITY OF SUCH DAMAGE.
namespace libtorrent
{
// returns protocol, auth, hostname, port, path
TORRENT_EXTRA_EXPORT boost::tuple<std::string, std::string
, std::string, int, std::string>
parse_url_components(std::string url, error_code& ec);

View File

@ -741,7 +741,11 @@ namespace libtorrent
{ return m_trackers; }
void replace_trackers(std::vector<announce_entry> const& urls);
void add_tracker(announce_entry const& url);
// returns true if the tracker was added, and false if it was already
// in the tracker list (in which case the source was added to the
// entry in the list)
bool add_tracker(announce_entry const& url);
torrent_handle get_handle();

View File

@ -57,6 +57,8 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/extensions.hpp"
#include "libtorrent/extensions/ut_metadata.hpp"
#include "libtorrent/alert_types.hpp"
#include "libtorrent/escape_string.hpp"
#include "libtorrent/parse_url.hpp"
#ifdef TORRENT_STATS
#include "libtorrent/aux_/session_impl.hpp"
#endif
@ -78,6 +80,7 @@ namespace libtorrent { namespace
: m_torrent(t)
, m_updates(0)
, m_2_minutes(110)
, m_num_trackers(0)
{
m_old_trackers = t.trackers();
update_list_hash();
@ -133,6 +136,9 @@ namespace libtorrent { namespace
std::vector<announce_entry> const& trackers() const { return m_old_trackers; }
void increment_tracker_counter() { m_num_trackers++; }
int num_tex_trackers() const { return m_num_trackers; }
private:
torrent& m_torrent;
std::vector<announce_entry> m_old_trackers;
@ -140,6 +146,7 @@ namespace libtorrent { namespace
int m_2_minutes;
std::vector<char> m_lt_trackers_msg;
sha1_hash m_list_hash;
int m_num_trackers;
};
@ -203,12 +210,6 @@ namespace libtorrent { namespace
lazy_entry const* added = msg.dict_find_list("added");
#ifdef TORRENT_VERBOSE_LOGGING
std::stringstream log_line;
log_line << time_now_string() << " <== LT_TEX [ "
"added: ";
#endif
// invalid tex message
if (added == 0)
{
@ -218,14 +219,66 @@ namespace libtorrent { namespace
return true;
}
#ifdef TORRENT_VERBOSE_LOGGING
std::stringstream log_line;
#endif
if (m_tp.num_tex_trackers() >= 50)
{
#ifdef TORRENT_VERBOSE_LOGGING
log_line << time_now_string() << " <== LT_TEX [ "
"we already have " << m_tp.num_tex_trackers() << " trackers "
"from tex, don't add any more";
(*m_pc.m_logger) << log_line.str();
#endif
return true;
}
#ifdef TORRENT_VERBOSE_LOGGING
log_line << time_now_string() << " <== LT_TEX [ "
"added: ";
#endif
for (int i = 0; i < added->list_size(); ++i)
{
announce_entry e(added->list_string_value_at(i));
if (e.url.empty()) continue;
e.fail_limit = 3;
// ignore urls with binary data in them
if (need_encoding(e.url.c_str(), e.url.size())) continue;
// ignore invalid URLs
error_code ec;
std::string protocol;
std::string auth;
std::string hostname;
int port;
std::string path;
boost::tie(protocol, auth, hostname, port, path)
= parse_url_components(e.url, ec);
if (ec) continue;
// ignore unknown protocols
if (protocol != "udp" && protocol != "http" && protocol != "https")
continue;
// ignore invalid ports
if (port == 0)
continue;
if (m_tp.num_tex_trackers() >= 50)
{
#ifdef TORRENT_VERBOSE_LOGGING
log_line << "**reached-limit** ";
#endif
break;
}
e.fail_limit = 1;
e.send_stats = false;
e.source = announce_entry::source_tex;
m_torrent.add_tracker(e);
if (m_torrent.add_tracker(e))
m_tp.increment_tracker_counter();
#ifdef TORRENT_VERBOSE_LOGGING
log_line << e.url << " ";
#endif

View File

@ -112,6 +112,12 @@ namespace libtorrent
{
hostname.assign(start, port_pos);
++port_pos;
for (std::string::iterator i = port_pos; i < end; ++i)
{
if (is_digit(*i)) continue;
ec = errors::invalid_port;
goto exit;
}
port = std::atoi(std::string(port_pos, end).c_str());
}
else

View File

@ -1221,7 +1221,10 @@ ret:
return -1;
}
if (m_allocate_files && (op.mode & file::rw_mask) != file::read_only)
// if the file has priority 0, don't allocate it
int file_index = files().file_index(*file_iter);
if (m_allocate_files && (op.mode & file::rw_mask) != file::read_only
&& (m_file_priority.size() < file_index || m_file_priority[file_index] > 0))
{
TORRENT_ASSERT(m_file_created.size() == files().num_files());
if (m_file_created[file_index] == false)
@ -1420,6 +1423,12 @@ ret:
bool lock_files = m_settings ? settings().lock_files : false;
if (lock_files) mode |= file::lock_file;
if (!m_allocate_files) mode |= file::sparse;
// files with priority 0 should always be sparse
int file_index = fe - files().begin();
if (m_file_priority.size() > file_index && m_file_priority[file_index] == 0)
mode |= file::sparse;
if (m_settings && settings().no_atime_storage) mode |= file::no_atime;
return m_pool.open_file(const_cast<default_storage*>(this), m_save_path, file_index, files(), mode, ec);

View File

@ -4268,14 +4268,14 @@ namespace libtorrent
}
}
void torrent::add_tracker(announce_entry const& url)
bool torrent::add_tracker(announce_entry const& url)
{
std::vector<announce_entry>::iterator k = std::find_if(m_trackers.begin()
, m_trackers.end(), boost::bind(&announce_entry::url, _1) == url.url);
if (k != m_trackers.end())
{
k->source |= url.source;
return;
return false;
}
k = std::upper_bound(m_trackers.begin(), m_trackers.end(), url
, boost::bind(&announce_entry::tier, _1) < boost::bind(&announce_entry::tier, _2));
@ -4283,6 +4283,7 @@ namespace libtorrent
k = m_trackers.insert(k, url);
if (k->source == 0) k->source = announce_entry::source_client;
if (!m_trackers.empty()) announce_with_tracker();
return true;
}
bool torrent::choke_peer(peer_connection& c)