forked from premiere/premiere-libtorrent
merged RC_1_1 into master
This commit is contained in:
commit
70199041f7
14
ChangeLog
14
ChangeLog
|
@ -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
|
||||||
|
|
|
@ -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);
|
t.set_root_cert(std::string(&pem[0], pem.size()));
|
||||||
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()));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) };
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue