merged RC_1_1 into master

This commit is contained in:
arvidn 2016-09-22 13:48:12 -07:00
commit 70199041f7
11 changed files with 71 additions and 113 deletions

View File

@ -36,6 +36,10 @@
* resume data no longer has timestamps of files * resume data no longer has timestamps of files
* require C++11 to build libtorrent * require C++11 to build libtorrent
* remove file size limit in torrent_info filename constructor
* fix tail-padding for last file in create_torrent
* don't send user-agent in metadata http downloads or UPnP requests when
in anonymous mode
* fix internal resolve links lookup for mutable torrents * fix internal resolve links lookup for mutable torrents
* hint DHT bootstrap nodes of actual bootstrap request * hint DHT bootstrap nodes of actual bootstrap request
@ -162,6 +166,16 @@
* added support for asynchronous disk I/O * added support for asynchronous disk I/O
* almost completely changed the storage interface (for custom storage) * almost completely changed the storage interface (for custom storage)
* added support for hashing pieces in multiple threads * added support for hashing pieces in multiple threads
* fix padfile issue
* fix PMTUd bug
* update puff to fix gzip crash
1.0.10 release
* fixed inverted priority of incoming piece suggestions
* fixed crash on invalid input in http_parser
* added a new "preformatted" type to bencode entry variant type
* fix division by zero in super-seeding logic * fix division by zero in super-seeding logic
1.0.9 release 1.0.9 release

View File

@ -44,6 +44,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <functional> #include <functional>
#include <cstdio> #include <cstdio>
#include <sstream> #include <sstream>
#include <fstream>
#ifdef TORRENT_WINDOWS #ifdef TORRENT_WINDOWS
#include <direct.h> // for _getcwd #include <direct.h> // for _getcwd
@ -52,65 +53,18 @@ POSSIBILITY OF SUCH DAMAGE.
using namespace libtorrent; using namespace libtorrent;
using namespace std::placeholders; using namespace std::placeholders;
int load_file(std::string const& filename, std::vector<char>& v, libtorrent::error_code& ec, int limit = 8000000) std::vector<char> load_file(std::string const& filename)
{ {
ec.clear(); std::vector<char> ret;
FILE* f = std::fopen(filename.c_str(), "rb"); std::fstream in;
if (f == nullptr) in.exceptions(std::ifstream::failbit);
{ in.open(filename.c_str(), std::ios_base::in | std::ios_base::binary);
ec.assign(errno, boost::system::system_category()); in.seekg(0, std::ios_base::end);
return -1; size_t const size = in.tellg();
} in.seekg(0, std::ios_base::beg);
ret.resize(size);
int r = fseek(f, 0, SEEK_END); in.read(ret.data(), ret.size());
if (r != 0) return ret;
{
ec.assign(errno, boost::system::system_category());
std::fclose(f);
return -1;
}
long s = ftell(f);
if (s < 0)
{
ec.assign(errno, boost::system::system_category());
std::fclose(f);
return -1;
}
if (s > limit)
{
std::fclose(f);
return -2;
}
r = fseek(f, 0, SEEK_SET);
if (r != 0)
{
ec.assign(errno, boost::system::system_category());
std::fclose(f);
return -1;
}
v.resize(s);
if (s == 0)
{
std::fclose(f);
return 0;
}
r = int(fread(&v[0], 1, v.size(), f));
if (r < 0)
{
ec.assign(errno, boost::system::system_category());
std::fclose(f);
return -1;
}
std::fclose(f);
if (r != s) return -3;
return 0;
} }
std::string branch_path(std::string const& f) std::string branch_path(std::string const& f)
@ -394,51 +348,31 @@ int main(int argc, char* argv[])
if (!root_cert.empty()) if (!root_cert.empty())
{ {
std::vector<char> pem; std::vector<char> pem = load_file(root_cert);
load_file(root_cert, pem, ec, 10000);
if (ec)
{
std::fprintf(stderr, "failed to load root certificate for tracker: %s\n", ec.message().c_str());
}
else
{
t.set_root_cert(std::string(&pem[0], pem.size())); t.set_root_cert(std::string(&pem[0], pem.size()));
} }
}
// create the torrent and print it to stdout // create the torrent and print it to stdout
std::vector<char> torrent; std::vector<char> torrent;
bencode(back_inserter(torrent), t.generate()); bencode(back_inserter(torrent), t.generate());
FILE* output = stdout;
if (!outfile.empty()) if (!outfile.empty())
output = std::fopen(outfile.c_str(), "wb+");
if (output == nullptr)
{ {
std::fprintf(stderr, "failed to open file \"%s\": (%d) %s\n" std::fstream out;
, outfile.c_str(), errno, std::strerror(errno)); out.exceptions(std::ifstream::failbit);
return 1; out.open(outfile.c_str(), std::ios_base::out | std::ios_base::binary);
out.write(&torrent[0], torrent.size());
}
else
{
fwrite(&torrent[0], 1, torrent.size(), stdout);
} }
fwrite(&torrent[0], 1, torrent.size(), output);
if (output != stdout)
std::fclose(output);
if (!merklefile.empty()) if (!merklefile.empty())
{ {
output = std::fopen(merklefile.c_str(), "wb+"); std::fstream merkle;
if (output == nullptr) merkle.exceptions(std::ifstream::failbit);
{ merkle.open(merklefile.c_str(), std::ios_base::out | std::ios_base::binary);
std::fprintf(stderr, "failed to open file \"%s\": (%d) %s\n" merkle.write(reinterpret_cast<char const*>(&t.merkle_tree()[0]), t.merkle_tree().size() * 20);
, merklefile.c_str(), errno, std::strerror(errno));
return 1;
}
int ret = int(fwrite(&t.merkle_tree()[0], 20, t.merkle_tree().size(), output));
if (ret != int(t.merkle_tree().size()))
{
std::fprintf(stderr, "failed to write %s: (%d) %s\n"
, merklefile.c_str(), errno, std::strerror(errno));
}
std::fclose(output);
} }
#ifndef BOOST_NO_EXCEPTIONS #ifndef BOOST_NO_EXCEPTIONS

View File

@ -51,15 +51,10 @@ int main(int argc, char* argv[])
settings_pack sett; settings_pack sett;
sett.set_str(settings_pack::listen_interfaces, "0.0.0.0:6881"); sett.set_str(settings_pack::listen_interfaces, "0.0.0.0:6881");
lt::session s(sett); lt::session s(sett);
error_code ec;
if (ec)
{
std::fprintf(stderr, "failed to open listen socket: %s\n", ec.message().c_str());
return 1;
}
add_torrent_params p; add_torrent_params p;
p.save_path = "./"; p.save_path = "./";
p.ti = std::make_shared<torrent_info>(std::string(argv[1]), std::ref(ec), 0); p.ti = std::make_shared<torrent_info>(std::string(argv[1]), std::ref(ec), 0);
error_code ec;
if (ec) if (ec)
{ {
std::fprintf(stderr, "%s\n", ec.message().c_str()); std::fprintf(stderr, "%s\n", ec.message().c_str());

View File

@ -128,6 +128,8 @@ struct TORRENT_EXTRA_EXPORT upnp final
, bool ignore_nonrouters); , bool ignore_nonrouters);
~upnp(); ~upnp();
void set_user_agent(std::string const& v) { m_user_agent = v; }
void start(); void start();
// Attempts to add a port mapping for the specified protocol. Valid protocols are // Attempts to add a port mapping for the specified protocol. Valid protocols are
@ -325,7 +327,7 @@ private:
std::vector<global_mapping_t> m_mappings; std::vector<global_mapping_t> m_mappings;
std::string const& m_user_agent; std::string m_user_agent;
// the set of devices we've found // the set of devices we've found
std::set<rootdevice> m_devices; std::set<rootdevice> m_devices;

View File

@ -6246,8 +6246,15 @@ namespace aux {
void session_impl::update_anonymous_mode() void session_impl::update_anonymous_mode()
{ {
if (!m_settings.get_bool(settings_pack::anonymous_mode)) return; if (!m_settings.get_bool(settings_pack::anonymous_mode))
{
if (m_upnp)
m_upnp->set_user_agent(m_settings.get_str(settings_pack::user_agent));
return;
}
if (m_upnp)
m_upnp->set_user_agent("");
m_settings.set_str(settings_pack::user_agent, ""); m_settings.set_str(settings_pack::user_agent, "");
url_random(m_peer_id.data(), m_peer_id.data() + 20); url_random(m_peer_id.data(), m_peer_id.data() + 20);
} }
@ -6512,7 +6519,8 @@ namespace aux {
// the upnp constructor may fail and call the callbacks // the upnp constructor may fail and call the callbacks
m_upnp = std::make_shared<upnp>(m_io_service m_upnp = std::make_shared<upnp>(m_io_service
, m_settings.get_str(settings_pack::user_agent) , m_settings.get_bool(settings_pack::anonymous_mode)
? "" : m_settings.get_str(settings_pack::user_agent)
, *this , *this
, m_settings.get_bool(settings_pack::upnp_ignore_nonrouters)); , m_settings.get_bool(settings_pack::upnp_ignore_nonrouters));
m_upnp->start(); m_upnp->start();

View File

@ -754,7 +754,9 @@ namespace libtorrent
)); ));
aux::proxy_settings ps = m_ses.proxy(); aux::proxy_settings ps = m_ses.proxy();
conn->get(m_url, seconds(30), 0, &ps conn->get(m_url, seconds(30), 0, &ps
, 5, settings().get_str(settings_pack::user_agent)); , 5
, settings().get_bool(settings_pack::anonymous_mode)
? "" : settings().get_str(settings_pack::user_agent));
set_state(torrent_status::downloading_metadata); set_state(torrent_status::downloading_metadata);
} }
#endif #endif
@ -7412,8 +7414,7 @@ namespace libtorrent
else if (m_state == torrent_status::downloading_metadata else if (m_state == torrent_status::downloading_metadata
|| m_state == torrent_status::downloading || m_state == torrent_status::downloading
|| m_state == torrent_status::finished || m_state == torrent_status::finished
|| m_state == torrent_status::seeding || m_state == torrent_status::seeding)
|| m_state == torrent_status::downloading)
{ {
// torrents that are started (not paused) and // torrents that are started (not paused) and
// inactive are not part of any list. They will not be touched because // inactive are not part of any list. They will not be touched because

View File

@ -606,18 +606,13 @@ namespace libtorrent
} }
int load_file(std::string const& filename, std::vector<char>& v int load_file(std::string const& filename, std::vector<char>& v
, error_code& ec, int limit = 8000000) , error_code& ec)
{ {
ec.clear(); ec.clear();
file f; file f;
if (!f.open(filename, file::read_only, ec)) return -1; if (!f.open(filename, file::read_only, ec)) return -1;
std::int64_t s = f.get_size(ec); std::int64_t s = f.get_size(ec);
if (ec) return -1; if (ec) return -1;
if (s > limit)
{
ec = errors::metadata_too_large;
return -2;
}
v.resize(std::size_t(s)); v.resize(std::size_t(s));
if (s == 0) return 0; if (s == 0) return 0;
file::iovec_t b = {&v[0], size_t(s) }; file::iovec_t b = {&v[0], size_t(s) };

View File

@ -635,7 +635,6 @@ namespace libtorrent
return true; return true;
} }
std::vector<peer_entry> peer_list;
resp.peers4.reserve(num_peers); resp.peers4.reserve(num_peers);
for (int i = 0; i < num_peers; ++i) for (int i = 0; i < num_peers; ++i)
{ {

View File

@ -1813,6 +1813,7 @@ bool utp_socket_impl::send_pkt(int const flags)
int const effective_mtu = mtu_probe ? m_mtu : m_mtu_floor; int const effective_mtu = mtu_probe ? m_mtu : m_mtu_floor;
int payload_size = (std::min)(m_write_buffer_size int payload_size = (std::min)(m_write_buffer_size
, effective_mtu - header_size); , effective_mtu - header_size);
TORRENT_ASSERT(payload_size >= 0);
// if we have one MSS worth of data, make sure it fits in our // if we have one MSS worth of data, make sure it fits in our
// congestion window and the advertised receive window from // congestion window and the advertised receive window from
@ -1915,6 +1916,7 @@ bool utp_socket_impl::send_pkt(int const flags)
#if TORRENT_USE_ASSERTS #if TORRENT_USE_ASSERTS
p->num_fast_resend = 0; p->num_fast_resend = 0;
#endif #endif
p->mtu_probe = false;
p->need_resend = false; p->need_resend = false;
ptr = p->buf; ptr = p->buf;
h = reinterpret_cast<utp_header*>(ptr); h = reinterpret_cast<utp_header*>(ptr);

View File

@ -124,7 +124,8 @@ namespace libtorrent
{ {
request += "Host: "; request += "Host: ";
request += m_host; request += m_host;
if (m_first_request || m_settings.get_bool(settings_pack::always_send_user_agent)) { if ((m_first_request || m_settings.get_bool(settings_pack::always_send_user_agent))
&& !m_settings.get_bool(settings_pack::anonymous_mode)) {
request += "\r\nUser-Agent: "; request += "\r\nUser-Agent: ";
request += m_settings.get_str(settings_pack::user_agent); request += m_settings.get_str(settings_pack::user_agent);
} }

View File

@ -982,9 +982,16 @@ void web_peer_connection::incoming_payload(char const* buf, int len)
, "piece: %d start: %d len: %d" , "piece: %d start: %d len: %d"
, front_request.piece, front_request.start, front_request.length); , front_request.piece, front_request.start, front_request.length);
#endif #endif
// Make a copy of the request and pop it off the queue before calling
// incoming_piece because that may lead to a call to disconnect()
// which will clear the request queue and invalidate any references
// to the request
peer_request const front_request_copy = front_request;
m_requests.pop_front(); m_requests.pop_front();
incoming_piece(front_request, &m_piece[0]); incoming_piece(front_request_copy, &m_piece[0]);
m_piece.clear(); m_piece.clear();
} }
} }