merged RC_1_1 into master

This commit is contained in:
arvidn 2016-08-21 16:28:49 -04:00
commit 74fc0fae9d
49 changed files with 633 additions and 342 deletions

View File

@ -32,6 +32,9 @@
1.1.1 release
* update puff.c for gzip inflation
* add dht_bootstrap_node a setting in settings_pack (and add default)
* make pad-file and symlink support conform to BEP47
* fix piece picker bug that could result in division by zero
* fix value of current_tracker when all tracker failed
* deprecate lt_trackers extension

View File

@ -26,7 +26,7 @@ class test_create_torrent(unittest.TestCase):
class test_torrent_handle(unittest.TestCase):
def test_torrent_handle(self):
ses = lt.session({'alert_mask': lt.alert.category_t.all_categories})
ses = lt.session({'alert_mask': lt.alert.category_t.all_categories, 'enable_dht': False})
ti = lt.torrent_info('url_seed_multi.torrent');
h = ses.add_torrent({'ti': ti, 'save_path': os.getcwd()})
@ -92,7 +92,7 @@ class test_torrent_info(unittest.TestCase):
# the file_strage object is only iterable for backwards compatibility
if not hasattr(lt, 'version'): return
ses = lt.session({'alert_mask': lt.alert.category_t.all_categories})
ses = lt.session({'alert_mask': lt.alert.category_t.all_categories, 'enable_dht': False})
ti = lt.torrent_info('url_seed_multi.torrent');
files = ti.files()
@ -109,7 +109,7 @@ class test_alerts(unittest.TestCase):
def test_alert(self):
ses = lt.session({'alert_mask': lt.alert.category_t.all_categories})
ses = lt.session({'alert_mask': lt.alert.category_t.all_categories, 'enable_dht': False})
ti = lt.torrent_info('base.torrent');
h = ses.add_torrent({'ti': ti, 'save_path': os.getcwd()})
st = h.status()
@ -134,7 +134,7 @@ class test_alerts(unittest.TestCase):
self.assertEqual(st.save_path, os.getcwd())
def test_pop_alerts(self):
ses = lt.session({'alert_mask': lt.alert.category_t.all_categories})
ses = lt.session({'alert_mask': lt.alert.category_t.all_categories, 'enable_dht': False})
ses.async_add_torrent({"ti": lt.torrent_info("base.torrent"), "save_path": "."})
# this will cause an error (because of duplicate torrents) and the
@ -176,7 +176,7 @@ class test_sha1hash(unittest.TestCase):
class test_session(unittest.TestCase):
def test_post_session_stats(self):
s = lt.session({'alert_mask': lt.alert.category_t.stats_notification})
s = lt.session({'alert_mask': lt.alert.category_t.stats_notification, 'enable_dht': False})
s.post_session_stats()
a = s.wait_for_alert(1000)
self.assertTrue(isinstance(a, lt.session_stats_alert))
@ -187,7 +187,7 @@ class test_session(unittest.TestCase):
# this detects whether libtorrent was built with deprecated APIs
if hasattr(lt, 'version'):
s = lt.session({})
s = lt.session({'enable_dht': False})
sett = lt.session_settings()
sett.num_want = 10;
s.set_settings(sett)
@ -196,7 +196,7 @@ class test_session(unittest.TestCase):
def test_apply_settings(self):
s = lt.session({})
s = lt.session({'enable_dht': False})
s.apply_settings({'num_want': 66, 'user_agent': 'test123'})
self.assertEqual(s.get_settings()['num_want'], 66)
self.assertEqual(s.get_settings()['user_agent'], 'test123')

View File

@ -696,6 +696,7 @@ namespace libtorrent
void update_dht();
void update_count_slow();
void update_peer_fingerprint();
void update_dht_bootstrap_nodes();
void update_socket_buffer_size();
void update_dht_announce_interval();

View File

@ -110,7 +110,7 @@ namespace bdecode_errors
{
// Not an error
no_error = 0,
// expected string in bencoded string
// expected digit in bencoded string
expected_digit,
// expected colon in bencoded string
expected_colon,

View File

@ -25,9 +25,7 @@
/*
* See puff.c for purpose and usage.
*/
#include <cstdint>
int puff(unsigned char *dest, /* pointer to destination pointer */
std::uint32_t *destlen, /* amount of output space */
const unsigned char *source, /* pointer to source data pointer */
std::uint32_t *sourcelen); /* amount of input available */
unsigned long *destlen, /* amount of output space */
const unsigned char *source, /* pointer to source data pointer */
unsigned long *sourcelen); /* amount of input available */

View File

@ -328,7 +328,7 @@ namespace libtorrent
// session_proxy();
// ~session_proxy()
// };
session_proxy abort() { return session_proxy(m_io_service, m_thread, m_impl); }
session_proxy abort();
private:

View File

@ -213,6 +213,15 @@ namespace libtorrent
// used as the peer-id
peer_fingerprint,
// This is a comma-separated list of IP port-pairs. They will be added
// to the DHT node (if it's enabled) as back-up nodes in case we don't
// know of any. This setting will contain one or more bootstrap nodes
// by default.
//
// Changing these after the DHT has been started may not have any
// effect until the DHT is restarted.
dht_bootstrap_nodes,
max_string_setting_internal
};

View File

@ -79,6 +79,12 @@ namespace libtorrent
TORRENT_EXTRA_EXPORT std::string print_listen_interfaces(
std::vector<listen_interface_t> const& in);
// this parses the string that's used as the liste_interfaces setting.
// it is a comma-separated list of IP or device names with ports. For
// example: "eth0:6881,eth1:6881" or "127.0.0.1:6881"
TORRENT_EXTRA_EXPORT void parse_comma_separated_string_port(
std::string const& in, std::vector<std::pair<std::string, int> >& out);
// this parses the string that's used as the outgoing_interfaces setting.
// it is a comma separated list of IPs and device names. For example:
// "eth0, eth1, 127.0.0.1"

View File

@ -40,6 +40,7 @@ alias libtorrent-sims :
[ run test_super_seeding.cpp ]
[ run test_utp.cpp ]
[ run test_dht.cpp ]
[ run test_dht_bootstrap.cpp ]
[ run test_dht_storage.cpp ]
[ run test_pe_crypto.cpp ]
[ run test_metadata_extension.cpp ]

View File

@ -45,6 +45,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/sha1_hash.hpp"
#include "libtorrent/torrent_info.hpp"
#include "libtorrent/io.hpp"
#include "libtorrent/bdecode.hpp"
using namespace sim;
@ -282,6 +283,56 @@ inline void add_fake_peers(lt::torrent_handle& h, int const n = 5)
}
}
struct fake_node
{
fake_node(simulation& sim, char const* ip, int port = 6881)
: m_ios(sim, asio::ip::address::from_string(ip))
, m_socket(m_ios)
, m_tripped(false)
{
boost::system::error_code ec;
m_socket.open(asio::ip::udp::v4(), ec);
TEST_CHECK(!ec);
m_socket.bind(asio::ip::udp::endpoint(asio::ip::address_v4::any(), port), ec);
TEST_CHECK(!ec);
fprintf(stderr, "fake_node::async_read_some\n");
m_socket.async_receive(boost::asio::buffer(m_in_buffer)
, [&] (boost::system::error_code const& ec, size_t bytes_transferred)
{
fprintf(stderr, "fake_node::async_read_some callback. ec: %s transferred: %d\n"
, ec.message().c_str(), int(bytes_transferred));
if (ec) return;
lt::bdecode_node n;
boost::system::error_code err;
int const ret = bdecode(m_in_buffer, m_in_buffer + bytes_transferred
, n, err, nullptr, 10, 200);
TEST_EQUAL(ret, 0);
// TODO: ideally we would validate the DHT message
m_tripped = true;
});
}
void close()
{
m_socket.close();
}
bool tripped() const { return m_tripped; }
private:
char m_in_buffer[300];
asio::io_service m_ios;
asio::ip::udp::socket m_socket;
bool m_tripped;
std::vector<char> m_send_buffer;
};
template<unsigned long N>
void check_accepted(std::array<fake_peer*, N>& test_peers
, std::array<bool, N> expected)

View File

@ -69,7 +69,6 @@ void run_test(Setup const& setup, Test const& test)
test(*ses);
// shut down
ses->set_alert_notify([]{});
zombie = ses->abort();
ses.reset();
});

View File

@ -0,0 +1,97 @@
/*
Copyright (c) 2016, Arvid Norberg
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the distribution.
* Neither the name of the author nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.hpp"
#include "simulator/simulator.hpp"
#include "utils.hpp"
#include "fake_peer.hpp" // for fake_node
#include "libtorrent/time.hpp"
#include "settings.hpp"
#include "libtorrent/deadline_timer.hpp"
#include "setup_transfer.hpp" // for addr()
namespace lt = libtorrent;
using namespace sim;
struct sim_config : sim::default_config
{
chrono::high_resolution_clock::duration hostname_lookup(
asio::ip::address const& requestor
, std::string hostname
, std::vector<asio::ip::address>& result
, boost::system::error_code& ec)
{
if (hostname == "dht.libtorrent.org")
{
result.push_back(addr("10.0.0.10"));
return lt::duration_cast<chrono::high_resolution_clock::duration>(chrono::milliseconds(100));
}
return default_config::hostname_lookup(requestor, hostname, result, ec);
}
};
TORRENT_TEST(dht_bootstrap)
{
using sim::asio::ip::address_v4;
sim_config network_cfg;
sim::simulation sim{network_cfg};
std::vector<lt::session_proxy> zombies;
fake_node node(sim, "10.0.0.10", 25401);
lt::settings_pack pack;
// we use 0 threads (disk I/O operations will be performed in the network
// thread) to be simulator friendly.
pack.set_int(lt::settings_pack::aio_threads, 0);
pack.set_bool(lt::settings_pack::enable_lsd, false);
pack.set_bool(lt::settings_pack::enable_upnp, false);
pack.set_bool(lt::settings_pack::enable_natpmp, false);
pack.set_bool(lt::settings_pack::enable_dht, true);
sim::asio::io_service ios(sim, addr("10.0.0.1"));
boost::shared_ptr<lt::session> ses = boost::make_shared<lt::session>(pack, ios);
lt::deadline_timer timer(ios);
timer.expires_from_now(lt::seconds(10));
timer.async_wait([&](lt::error_code const& ec) {
zombies.push_back(ses->abort());
node.close();
ses.reset();
});
print_alerts(*ses);
sim.run();
TEST_EQUAL(node.tripped(), true);
}

View File

@ -79,7 +79,6 @@ void run_fake_peer_test(
sim::timer t(sim, lt::seconds(1)
, [&](boost::system::error_code const&)
{
ses->set_alert_notify([]{});
// shut down
zombie = ses->abort();

View File

@ -89,7 +89,6 @@ void run_test(Setup const& setup
{
test(*ses, test_peers);
ses->set_alert_notify([]{});
// shut down
zombie = ses->abort();

View File

@ -150,7 +150,6 @@ TORRENT_TEST(optimistic_unchoke)
{
p->abort();
}
ses->set_alert_notify([]{});
proxy = ses->abort();
ses.reset();
});

View File

@ -94,7 +94,6 @@ void run_test(Setup const& setup
{
std::fprintf(stderr, "shutting down\n");
// shut down
ses->set_alert_notify([] {});
zombie = ses->abort();
ses.reset();
});

View File

@ -354,7 +354,6 @@ TORRENT_TEST(ipv6_support)
, [&ses,&zombie](boost::system::error_code const&)
{
zombie = ses->abort();
ses->set_alert_notify([]{});
ses.reset();
});
@ -429,7 +428,6 @@ void tracker_test(Setup setup, Announce a, Test1 test1, Test2 test2
, [&ses,&zombie](boost::system::error_code const&)
{
zombie = ses->abort();
ses->set_alert_notify([]{});
ses.reset();
});

View File

@ -152,7 +152,6 @@ void run_test(
int idx = 0;
for (auto& s : ses)
{
s->set_alert_notify([]{});
zombie[idx++] = s->abort();
s.reset();
}

View File

@ -105,7 +105,6 @@ void run_test(Setup const& setup
{
fprintf(stderr, "shutting down\n");
// shut down
ses->set_alert_notify([] {});
zombie = ses->abort();
ses.reset();
});

View File

@ -544,7 +544,7 @@ namespace libtorrent
{
if (m_include_mtime) info["mtime"] = m_files.mtime(0);
info["length"] = m_files.file_size(0);
int flags = m_files.file_flags(0);
int const flags = m_files.file_flags(0);
if (flags & (file_storage::flag_pad_file
| file_storage::flag_hidden
| file_storage::flag_executable

View File

@ -47,8 +47,10 @@ POSSIBILITY OF SUCH DAMAGE.
#if defined(TORRENT_WINDOWS) || defined(TORRENT_OS2)
#define TORRENT_SEPARATOR '\\'
#define TORRENT_SEPARATOR_STR "\\"
#else
#define TORRENT_SEPARATOR '/'
#define TORRENT_SEPARATOR_STR "/"
#endif
using namespace std::placeholders;
@ -561,10 +563,10 @@ namespace libtorrent
, symlink_path);
}
void file_storage::add_file_borrow(char const* filename, int filename_len
, std::string const& path, std::int64_t file_size
, std::uint32_t file_flags, char const* filehash
, std::int64_t mtime, string_view symlink_path)
void file_storage::add_file_borrow(char const* filename, int const filename_len
, std::string const& path, std::int64_t const file_size
, std::uint32_t const file_flags, char const* filehash
, std::int64_t const mtime, string_view symlink_path)
{
TORRENT_ASSERT_PRECOND(file_size >= 0);
if (!has_parent_path(path))
@ -599,10 +601,10 @@ namespace libtorrent
e.size = file_size;
e.offset = m_total_size;
e.pad_file = file_flags & file_storage::flag_pad_file;
e.hidden_attribute = file_flags & file_storage::flag_hidden;
e.executable_attribute = file_flags & file_storage::flag_executable;
e.symlink_attribute = file_flags & file_storage::flag_symlink;
e.pad_file = (file_flags & file_storage::flag_pad_file) != 0;
e.hidden_attribute = (file_flags & file_storage::flag_hidden) != 0;
e.executable_attribute = (file_flags & file_storage::flag_executable) != 0;
e.symlink_attribute = (file_flags & file_storage::flag_symlink) != 0;
if (filehash)
{
@ -988,8 +990,8 @@ namespace libtorrent
if (best_match != i)
{
int index = best_match - m_files.begin();
int cur_index = i - m_files.begin();
int const index = best_match - m_files.begin();
int const cur_index = i - m_files.begin();
reorder_file(index, cur_index);
i = m_files.begin() + cur_index;
}
@ -1002,8 +1004,8 @@ namespace libtorrent
// not piece-aligned and the file size exceeds the
// limit, and it's not a padding file itself.
// so add a padding file in front of it
int pad_size = alignment - (off % alignment);
int const pad_size = alignment - (off % alignment);
// find the largest file that fits in pad_size
std::vector<internal_file_entry>::iterator best_match = m_files.end();
@ -1088,7 +1090,8 @@ namespace libtorrent
e.size = size;
e.offset = offset;
char name[30];
std::snprintf(name, sizeof(name), ".____padding_file/%d", pad_file_counter);
std::snprintf(name, sizeof(name), ".pad" TORRENT_SEPARATOR_STR "%d"
, pad_file_counter);
std::string path = combine_path(m_name, name);
e.set_name(path.c_str());
e.pad_file = true;

View File

@ -212,9 +212,9 @@ namespace libtorrent
// start off with 4 kilobytes and grow
// if needed
std::uint32_t destlen = 4096;
unsigned long destlen = 4096;
int ret = 0;
std::uint32_t srclen = size - header_len;
unsigned long srclen = size - header_len;
in += header_len;
do

View File

@ -1,8 +1,8 @@
/*
* puff.c
* Copyright (C) 2002, 2003 Mark Adler
* Copyright (C) 2002-2013 Mark Adler
* For conditions of distribution and use, see copyright notice in puff.h
* version 1.7, 3 Mar 2003
* version 2.3, 21 Jan 2013
*
* puff.c is a simple inflate written to be an unambiguous way to specify the
* deflate format. It is not written for speed but rather simplicity. As a
@ -49,9 +49,9 @@
* - Fix fixed codes table error
* - Provide a scanning mode for determining size of
* uncompressed data
* 1.3 20 Mar 2002 - Go back to lengths for puff() parameters [Jean-loup]
* 1.3 20 Mar 2002 - Go back to lengths for puff() parameters [Gailly]
* - Add a puff.h file for the interface
* - Add braces in puff() for else do [Jean-loup]
* - Add braces in puff() for else do [Gailly]
* - Use indexes instead of pointers for readability
* 1.4 31 Mar 2002 - Simplify construct() code set check
* - Fix some comments
@ -60,26 +60,33 @@
* 1.6 7 Aug 2002 - Minor format changes
* 1.7 3 Mar 2003 - Added test code for distribution
* - Added zlib-like license
* 1.8 9 Jan 2004 - Added some comments on no distance codes case
* 1.9 21 Feb 2008 - Fix bug on 16-bit integer architectures [Pohland]
* - Catch missing end-of-block symbol error
* 2.0 25 Jul 2008 - Add #define to permit distance too far back
* - Add option in TEST code for puff to write the data
* - Add option in TEST code to skip input bytes
* - Allow TEST code to read from piped stdin
* 2.1 4 Apr 2010 - Avoid variable initialization for happier compilers
* - Avoid unsigned comparisons for even happier compilers
* 2.2 25 Apr 2010 - Fix bug in variable initializations [Oberhumer]
* - Add const where appropriate [Oberhumer]
* - Split if's and ?'s for coverage testing
* - Break out test code to separate file
* - Move NIL to puff.h
* - Allow incomplete code only if single code length is 1
* - Add full code coverage test to Makefile
* 2.3 21 Jan 2013 - Check for invalid code length codes in dynamic blocks
*/
/*
note by Arvid Norberg.
This file was turned into a .cpp file in order to
be able to take advantage of boost's cstdint.hpp file
All "short" has been replaced with std::int16_t
and all "long" with std::int32_t according to the
type width assuptions in the comment above.
*/
// this whole file is just preserved and warnings are suppressed
#include "libtorrent/aux_/disable_warnings_push.hpp"
#include <csetjmp> /* for setjmp(), longjmp(), and jmp_buf */
#include <cstdint> /* for types with size guarantees */
#include "libtorrent/puff.hpp" /* prototype for puff() */
#include <setjmp.h> /* for setjmp(), longjmp(), and jmp_buf */
#include <string.h> /* for NULL */
#include "puff.hpp" /* prototype for puff() */
#define local static /* for local function definitions */
#define NIL ((unsigned char *)0) /* for no output option */
/*
* Maximums for allocations and loops. It is not useful to change these --
@ -95,13 +102,13 @@ type width assuptions in the comment above.
struct state {
/* output state */
unsigned char *out; /* output buffer */
std::uint32_t outlen; /* available space at out */
std::uint32_t outcnt; /* bytes written to out so far */
unsigned long outlen; /* available space at out */
unsigned long outcnt; /* bytes written to out so far */
/* input state */
const unsigned char *in; /* input buffer */
std::uint32_t inlen; /* available input at in */
std::uint32_t incnt; /* bytes read so far */
const unsigned char *in; /* input buffer */
unsigned long inlen; /* available input at in */
unsigned long incnt; /* bytes read so far */
int bitbuf; /* bit buffer */
int bitcnt; /* number of bits in bit buffer */
@ -122,22 +129,23 @@ struct state {
*/
local int bits(struct state *s, int need)
{
std::int32_t val; /* bit accumulator (can use up to 20 bits) */
long val; /* bit accumulator (can use up to 20 bits) */
/* load at least need bits into val */
val = s->bitbuf;
while (s->bitcnt < need) {
if (s->incnt == s->inlen) longjmp(s->env, 1); /* out of input */
val |= (std::int32_t)(s->in[s->incnt++]) << s->bitcnt; /* load eight bits */
if (s->incnt == s->inlen)
longjmp(s->env, 1); /* out of input */
val |= long(s->in[s->incnt++]) << s->bitcnt; /* load eight bits */
s->bitcnt += 8;
}
/* drop need bits and update buffer, always zero to seven bits left */
s->bitbuf = (int)(val >> need);
s->bitbuf = int(val >> need);
s->bitcnt -= need;
/* return need bits, zeroing the bits above that */
return (int)(val & ((1L << need) - 1));
return int(val & ((1L << need) - 1));
}
/*
@ -166,7 +174,8 @@ local int stored(struct state *s)
s->bitcnt = 0;
/* get length and check against its one's complement */
if (s->incnt + 4 > s->inlen) return 2; /* not enough input */
if (s->incnt + 4 > s->inlen)
return 2; /* not enough input */
len = s->in[s->incnt++];
len |= s->in[s->incnt++] << 8;
if (s->in[s->incnt++] != (~len & 0xff) ||
@ -174,8 +183,9 @@ local int stored(struct state *s)
return -2; /* didn't match complement! */
/* copy len bytes from in to out */
if (s->incnt + len > s->inlen) return 2; /* not enough input */
if (s->out != NIL) {
if (s->incnt + len > s->inlen)
return 2; /* not enough input */
if (s->out != NULL) {
if (s->outcnt + len > s->outlen)
return 1; /* not enough output space */
while (len--)
@ -198,15 +208,15 @@ local int stored(struct state *s)
* seen in the function decode() below.
*/
struct huffman {
std::int16_t *count; /* number of symbols of each length */
std::int16_t *symbol; /* canonically ordered symbols */
short *count; /* number of symbols of each length */
short *symbol; /* canonically ordered symbols */
};
/*
* Decode a code from the stream s using huffman table h. Return the symbol or
* a negative value if there is an error. If all of the lengths are zero, i.e.
* an empty code, or if the code is incomplete and an invalid code is received,
* then -9 is returned after reading MAXBITS bits.
* then -10 is returned after reading MAXBITS bits.
*
* Format notes:
*
@ -226,7 +236,7 @@ struct huffman {
* in the deflate format. See the format notes for fixed() and dynamic().
*/
#ifdef SLOW
local int decode(struct state *s, struct huffman *h)
local int decode(struct state *s, const struct huffman *h)
{
int len; /* current number of bits in code */
int code; /* len bits being decoded */
@ -238,14 +248,14 @@ local int decode(struct state *s, struct huffman *h)
for (len = 1; len <= MAXBITS; len++) {
code |= bits(s, 1); /* get next bit */
count = h->count[len];
if (code < first + count) /* if length len, return symbol */
if (code - count < first) /* if length len, return symbol */
return h->symbol[index + (code - first)];
index += count; /* else update for next length */
first += count;
first <<= 1;
code <<= 1;
}
return -9; /* ran out of codes */
return -10; /* ran out of codes */
}
/*
@ -254,7 +264,7 @@ local int decode(struct state *s, struct huffman *h)
* a few percent larger.
*/
#else /* !SLOW */
local int decode(struct state *s, struct huffman *h)
local int decode(struct state *s, const struct huffman *h)
{
int len; /* current number of bits in code */
int code; /* len bits being decoded */
@ -263,7 +273,7 @@ local int decode(struct state *s, struct huffman *h)
int index; /* index of first code of length len in symbol table */
int bitbuf; /* bits from stream */
int left; /* bits left in next or left to process */
std::int16_t *next; /* next number of codes */
short *next; /* next number of codes */
bitbuf = s->bitbuf;
left = s->bitcnt;
@ -275,7 +285,7 @@ local int decode(struct state *s, struct huffman *h)
code |= bitbuf & 1;
bitbuf >>= 1;
count = *next++;
if (code < first + count) { /* if length len, return symbol */
if (code - count < first) { /* if length len, return symbol */
s->bitbuf = bitbuf;
s->bitcnt = (s->bitcnt - len) & 7;
return h->symbol[index + (code - first)];
@ -287,12 +297,15 @@ local int decode(struct state *s, struct huffman *h)
len++;
}
left = (MAXBITS+1) - len;
if (left == 0) break;
if (s->incnt == s->inlen) longjmp(s->env, 1); /* out of input */
if (left == 0)
break;
if (s->incnt == s->inlen)
longjmp(s->env, 1); /* out of input */
bitbuf = s->in[s->incnt++];
if (left > 8) left = 8;
if (left > 8)
left = 8;
}
return -9; /* ran out of codes */
return -10; /* ran out of codes */
}
#endif /* SLOW */
@ -328,12 +341,12 @@ local int decode(struct state *s, struct huffman *h)
* - Within a given code length, the symbols are kept in ascending order for
* the code bits definition.
*/
local int construct(struct huffman *h, std::int16_t *length, int n)
local int construct(struct huffman *h, const short *length, int n)
{
int symbol; /* current symbol when stepping through length[] */
int len; /* current length when stepping through h->count[] */
int left; /* number of possible codes left of current length */
std::int16_t offs[MAXBITS+1]; /* offsets in symbol table for each length */
short offs[MAXBITS+1]; /* offsets in symbol table for each length */
/* count number of codes of each length */
for (len = 0; len <= MAXBITS; len++)
@ -348,7 +361,8 @@ local int construct(struct huffman *h, std::int16_t *length, int n)
for (len = 1; len <= MAXBITS; len++) {
left <<= 1; /* one more bit, double codes left */
left -= h->count[len]; /* deduct count from possible codes */
if (left < 0) return left; /* over-subscribed--return negative */
if (left < 0)
return left; /* over-subscribed--return negative */
} /* left > 0 means incomplete */
/* generate offsets into symbol table for each length for sorting */
@ -424,23 +438,23 @@ local int construct(struct huffman *h, std::int16_t *length, int n)
* defined to do the wrong thing in this case.
*/
local int codes(struct state *s,
struct huffman *lencode,
struct huffman *distcode)
const struct huffman *lencode,
const struct huffman *distcode)
{
int symbol; /* decoded symbol */
int len; /* length for copy */
unsigned dist; /* distance for copy */
static const std::int16_t lens[29] = { /* Size base for length codes 257..285 */
static const short lens[29] = { /* Size base for length codes 257..285 */
3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258};
static const std::int16_t lext[29] = { /* Extra bits for length codes 257..285 */
static const short lext[29] = { /* Extra bits for length codes 257..285 */
0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
static const std::int16_t dists[30] = { /* Offset base for distance codes 0..29 */
static const short dists[30] = { /* Offset base for distance codes 0..29 */
1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
8193, 12289, 16385, 24577};
static const std::int16_t dext[30] = { /* Extra bits for distance codes 0..29 */
static const short dext[30] = { /* Extra bits for distance codes 0..29 */
0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
12, 12, 13, 13};
@ -448,11 +462,13 @@ local int codes(struct state *s,
/* decode literals and length/distance pairs */
do {
symbol = decode(s, lencode);
if (symbol < 0) return symbol; /* invalid symbol */
if (symbol < 0)
return symbol; /* invalid symbol */
if (symbol < 256) { /* literal: symbol is the byte */
/* write out the literal */
if (s->out != NIL) {
if (s->outcnt == s->outlen) return 1;
if (s->out != NULL) {
if (s->outcnt == s->outlen)
return 1;
s->out[s->outcnt] = symbol;
}
s->outcnt++;
@ -460,21 +476,31 @@ local int codes(struct state *s,
else if (symbol > 256) { /* length */
/* get and compute length */
symbol -= 257;
if (symbol >= 29) return -9; /* invalid fixed code */
if (symbol >= 29)
return -10; /* invalid fixed code */
len = lens[symbol] + bits(s, lext[symbol]);
/* get and check distance */
symbol = decode(s, distcode);
if (symbol < 0) return symbol; /* invalid symbol */
if (symbol < 0)
return symbol; /* invalid symbol */
dist = dists[symbol] + bits(s, dext[symbol]);
#ifndef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
if (dist > s->outcnt)
return -10; /* distance too far back */
return -11; /* distance too far back */
#endif
/* copy length bytes from distance bytes back */
if (s->out != NIL) {
if (s->outcnt + len > s->outlen) return 1;
if (s->out != NULL) {
if (s->outcnt + len > s->outlen)
return 1;
while (len--) {
s->out[s->outcnt] = s->out[s->outcnt - dist];
s->out[s->outcnt] =
#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
dist > s->outcnt ?
0 :
#endif
s->out[s->outcnt - dist];
s->outcnt++;
}
}
@ -514,15 +540,20 @@ local int codes(struct state *s,
local int fixed(struct state *s)
{
static int virgin = 1;
static std::int16_t lencnt[MAXBITS+1], lensym[FIXLCODES];
static std::int16_t distcnt[MAXBITS+1], distsym[MAXDCODES];
static struct huffman lencode = {lencnt, lensym};
static struct huffman distcode = {distcnt, distsym};
static short lencnt[MAXBITS+1], lensym[FIXLCODES];
static short distcnt[MAXBITS+1], distsym[MAXDCODES];
static struct huffman lencode, distcode;
/* build fixed huffman tables if first call (may not be thread safe) */
if (virgin) {
int symbol;
std::int16_t lengths[FIXLCODES];
short lengths[FIXLCODES];
/* construct lencode and distcode */
lencode.count = lencnt;
lencode.symbol = lensym;
distcode.count = distcnt;
distcode.symbol = distsym;
/* literal/length table */
for (symbol = 0; symbol < 144; symbol++)
@ -590,6 +621,9 @@ local int fixed(struct state *s)
* block is fewer bits), but it is allowed by the format. So incomplete
* literal/length codes of one symbol should also be permitted.
*
* - If there are only literal codes and no lengths, then there are no distance
* codes. This is represented by one distance code with zero bits.
*
* - The list of up to 286 length/literal lengths and up to 30 distance lengths
* are themselves compressed using Huffman codes and run-length encoding. In
* the list of code lengths, a 0 symbol means no code, a 1..15 symbol means
@ -637,14 +671,19 @@ local int dynamic(struct state *s)
int nlen, ndist, ncode; /* number of lengths in descriptor */
int index; /* index of lengths[] */
int err; /* construct() return value */
std::int16_t lengths[MAXCODES]; /* descriptor code lengths */
std::int16_t lencnt[MAXBITS+1], lensym[MAXLCODES]; /* lencode memory */
std::int16_t distcnt[MAXBITS+1], distsym[MAXDCODES]; /* distcode memory */
struct huffman lencode = {lencnt, lensym}; /* length code */
struct huffman distcode = {distcnt, distsym}; /* distance code */
static const std::int16_t order[19] = /* permutation of code length codes */
short lengths[MAXCODES]; /* descriptor code lengths */
short lencnt[MAXBITS+1], lensym[MAXLCODES]; /* lencode memory */
short distcnt[MAXBITS+1], distsym[MAXDCODES]; /* distcode memory */
struct huffman lencode, distcode; /* length and distance codes */
static const short order[19] = /* permutation of code length codes */
{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
/* construct lencode and distcode */
lencode.count = lencnt;
lencode.symbol = lensym;
distcode.count = distcnt;
distcode.symbol = distsym;
/* get number of lengths in each table, check lengths */
nlen = bits(s, 5) + 257;
ndist = bits(s, 5) + 1;
@ -660,7 +699,8 @@ local int dynamic(struct state *s)
/* build huffman table for code lengths codes (use lencode temporarily) */
err = construct(&lencode, lengths, 19);
if (err != 0) return -4; /* require complete code set here */
if (err != 0) /* require complete code set here */
return -4;
/* read length/literal and distance code length tables */
index = 0;
@ -668,13 +708,16 @@ local int dynamic(struct state *s)
int symbol; /* decoded value */
symbol = decode(s, &lencode);
if (symbol < 0)
return symbol; /* invalid symbol */
if (symbol < 16) /* length in 0..15 */
lengths[index++] = symbol;
else { /* repeat instruction */
int len = 0; /* last length to repeat */
/* assume repeating zeros */
if (symbol == 16) { /* repeat last length 3..6 times */
if (index == 0) return -5; /* no last length! */
if (index == 0)
return -5; /* no last length! */
len = lengths[index - 1]; /* last length */
symbol = 3 + bits(s, 2);
}
@ -689,15 +732,19 @@ local int dynamic(struct state *s)
}
}
/* check for end-of-block code -- there better be one! */
if (lengths[256] == 0)
return -9;
/* build huffman table for literal/length codes */
err = construct(&lencode, lengths, nlen);
if (err < 0 || (err > 0 && nlen - lencode.count[0] != 1))
return -7; /* only allow incomplete codes if just one code */
if (err && (err < 0 || nlen != lencode.count[0] + lencode.count[1]))
return -7; /* incomplete code ok only for single length 1 code */
/* build huffman table for distance codes */
err = construct(&distcode, lengths + nlen, ndist);
if (err < 0 || (err > 0 && ndist - distcode.count[0] != 1))
return -8; /* only allow incomplete codes if just one code */
if (err && (err < 0 || ndist != distcode.count[0] + distcode.count[1]))
return -8; /* incomplete code ok only for single length 1 code */
/* decode data until end-of-block code */
return codes(s, &lencode, &distcode);
@ -733,8 +780,9 @@ local int dynamic(struct state *s)
* -6: dynamic block code description: repeat more than specified lengths
* -7: dynamic block code description: invalid literal/length code lengths
* -8: dynamic block code description: invalid distance code lengths
* -9: invalid literal/length or distance code in fixed or dynamic block
* -10: distance is too far back in fixed or dynamic block
* -9: dynamic block code description: missing end-of-block code
* -10: invalid literal/length or distance code in fixed or dynamic block
* -11: distance is too far back in fixed or dynamic block
*
* Format notes:
*
@ -747,11 +795,12 @@ local int dynamic(struct state *s)
* expected values to check.
*/
int puff(unsigned char *dest, /* pointer to destination pointer */
std::uint32_t *destlen, /* amount of output space */
const unsigned char *source, /* pointer to source data pointer */
std::uint32_t *sourcelen) /* amount of input available */
unsigned long *destlen, /* amount of output space */
const unsigned char *source, /* pointer to source data pointer */
unsigned long *sourcelen) /* amount of input available */
{
struct state s; /* input/output state */
int last, type; /* block information */
int err; /* return value */
/* initialize output state */
@ -771,15 +820,18 @@ int puff(unsigned char *dest, /* pointer to destination pointer */
err = 2; /* then skip do-loop, return error */
else {
/* process blocks until last block or error */
int last = 0;
do {
last = bits(&s, 1); /* one if last block */
int type = bits(&s, 2); /* block type 0..3 */
err = type == 0 ? stored(&s) :
(type == 1 ? fixed(&s) :
(type == 2 ? dynamic(&s) :
-1)); /* type == 3, invalid */
if (err != 0) break; /* return with error */
last = bits(&s, 1); /* one if last block */
type = bits(&s, 2); /* block type 0..3 */
err = type == 0 ?
stored(&s) :
(type == 1 ?
fixed(&s) :
(type == 2 ?
dynamic(&s) :
-1)); /* type == 3, invalid */
if (err != 0)
break; /* return with error */
} while (!last);
}
@ -790,60 +842,3 @@ int puff(unsigned char *dest, /* pointer to destination pointer */
}
return err;
}
#ifdef TEST
/* Example of how to use puff() */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
local unsigned char *yank(char *name, std::uint32_t *len)
{
std::uint32_t size;
unsigned char *buf;
FILE *in;
struct stat s;
*len = 0;
if (stat(name, &s)) return nullptr;
if ((s.st_mode & S_IFMT) != S_IFREG) return nullptr;
size = (std::uint32_t)(s.st_size);
if (size == 0 || (off_t)size != s.st_size) return nullptr;
in = fopen(name, "r");
if (in == nullptr) return nullptr;
buf = malloc(size);
if (buf != nullptr && fread(buf, 1, size, in) != size) {
free(buf);
buf = nullptr;
}
fclose(in);
*len = size;
return buf;
}
int main(int argc, char **argv)
{
int ret;
unsigned char *source;
std::uint32_t len, sourcelen, destlen;
if (argc < 2) return 2;
source = yank(argv[1], &len);
if (source == nullptr) return 2;
sourcelen = len;
ret = puff(NIL, &destlen, source, &sourcelen);
if (ret)
std::printf("puff() failed with return code %d\n", ret);
else {
std::printf("puff() succeeded uncompressing %lu bytes\n", destlen);
if (sourcelen < len) std::printf("%lu compressed bytes unused\n",
len - sourcelen);
}
free(source);
return ret;
}
#endif
#include "libtorrent/aux_/disable_warnings_pop.hpp"

View File

@ -378,6 +378,14 @@ namespace libtorrent
m_thread->join();
}
session_proxy session::abort()
{
// stop calling the alert notify function now, to avoid it thinking the
// session is still alive
m_impl->alerts().set_notify_function(std::function<void()>());
return session_proxy(m_io_service, m_thread, m_impl);
}
#ifndef TORRENT_NO_DEPRECATE
session_settings::session_settings(std::string const& user_agent_)
{

View File

@ -556,6 +556,7 @@ namespace aux {
update_lsd();
update_dht();
update_peer_fingerprint();
update_dht_bootstrap_nodes();
#ifndef TORRENT_DISABLE_DHT
update_dht_announce_interval();
#endif
@ -839,6 +840,10 @@ namespace aux {
session_log(" *** ABORT CALLED ***");
#endif
// at this point we cannot call the notify function anymore, since the
// session will become invalid.
m_alerts.set_notify_function(std::function<void()>());
// this will cancel requests that are not critical for shutting down
// cleanly. i.e. essentially tracker hostname lookups that we're not
// about to send event=stopped to
@ -5240,6 +5245,20 @@ namespace aux {
}
}
void session_impl::update_dht_bootstrap_nodes()
{
#ifndef TORRENT_DISABLE_DHT
std::string const& node_list = m_settings.get_str(settings_pack::dht_bootstrap_nodes);
std::vector<std::pair<std::string, int> > nodes;
parse_comma_separated_string_port(node_list, nodes);
for (int i = 0; i < nodes.size(); ++i)
{
add_dht_router(nodes[i]);
}
#endif
}
void session_impl::update_count_slow()
{
error_code ec;

View File

@ -139,7 +139,8 @@ namespace libtorrent
SET_NOPREV(proxy_username, "", &session_impl::update_proxy),
SET_NOPREV(proxy_password, "", &session_impl::update_proxy),
SET_NOPREV(i2p_hostname, "", &session_impl::update_i2p_bridge),
SET_NOPREV(peer_fingerprint, "-LT1200-", &session_impl::update_peer_fingerprint)
SET_NOPREV(peer_fingerprint, "-LT1200-", &session_impl::update_peer_fingerprint),
SET_NOPREV(dht_bootstrap_nodes, "dht.libtorrent.org:25401", &session_impl::update_dht_bootstrap_nodes)
};
bool_setting_entry_t bool_settings[settings_pack::num_bool_settings] =

View File

@ -295,6 +295,51 @@ namespace libtorrent
}
}
// this parses the string that's used as the listen_interfaces setting.
// it is a comma-separated list of IP or device names with ports. For
// example: "eth0:6881,eth1:6881" or "127.0.0.1:6881"
void parse_comma_separated_string_port(std::string const& in
, std::vector<std::pair<std::string, int> >& out)
{
out.clear();
std::string::size_type start = 0;
std::string::size_type end = 0;
while (start < in.size())
{
// skip leading spaces
while (start < in.size()
&& is_space(in[start]))
++start;
end = in.find_first_of(',', start);
if (end == std::string::npos) end = in.size();
std::string::size_type colon = in.find_last_of(':', end);
if (colon != std::string::npos && colon > start)
{
int port = atoi(in.substr(colon + 1, end - colon - 1).c_str());
// skip trailing spaces
std::string::size_type soft_end = colon;
while (soft_end > start
&& is_space(in[soft_end-1]))
--soft_end;
// in case this is an IPv6 address, strip off the square brackets
// to make it more easily parseable into an ip::address
if (in[start] == '[') ++start;
if (soft_end > start && in[soft_end-1] == ']') --soft_end;
out.push_back(std::make_pair(in.substr(start, soft_end - start), port));
}
start = end + 1;
}
}
void parse_comma_separated_string(std::string const& in, std::vector<std::string>& out)
{
out.clear();

View File

@ -375,6 +375,46 @@ namespace libtorrent
namespace {
boost::uint32_t get_file_attributes(bdecode_node const& dict)
{
boost::uint32_t file_flags = 0;
bdecode_node attr = dict.dict_find_string("attr");
if (attr)
{
for (int i = 0; i < attr.string_length(); ++i)
{
switch (attr.string_ptr()[i])
{
case 'l': file_flags |= file_storage::flag_symlink; break;
case 'x': file_flags |= file_storage::flag_executable; break;
case 'h': file_flags |= file_storage::flag_hidden; break;
case 'p': file_flags |= file_storage::flag_pad_file; break;
}
}
}
return file_flags;
}
// iterates an array of strings and returns the sum of the lengths of all
// strings + one additional character per entry (to account for the presumed
// forward- or backslash to seaprate directory entries)
int path_length(bdecode_node const& p, error_code& ec)
{
int ret = 0;
int const len = p.list_size();
for (int i = 0; i < len; ++i)
{
bdecode_node e = p.list_at(i);
if (e.type() != bdecode_node::string_t)
{
ec = errors::torrent_invalid_name;
return -1;
}
ret += e.string_length();
}
return ret + len;
}
// 'top_level' is extracting the file for a single-file torrent. The
// distinction is that the filename is found in "name" rather than
// "path"
@ -382,17 +422,24 @@ namespace libtorrent
// torrent, in which case it's empty.
bool extract_single_file(bdecode_node const& dict, file_storage& files
, std::string const& root_dir, ptrdiff_t info_ptr_diff, bool top_level
, error_code& ec)
, int& pad_file_cnt, error_code& ec)
{
if (dict.type() != bdecode_node::dict_t) return false;
std::int64_t file_size = dict.dict_find_int_value("length", -1);
if (file_size < 0)
boost::uint32_t file_flags = get_file_attributes(dict);
// symlinks have an implied "size" of zero. i.e. they use up 0 bytes of
// the torrent payload space
boost::int64_t const file_size = (file_flags & file_storage::flag_symlink)
? 0
: dict.dict_find_int_value("length", -1);
if (file_size < 0 )
{
ec = errors::torrent_invalid_length;
return false;
}
std::int64_t mtime = dict.dict_find_int_value("mtime", 0);
boost::int64_t const mtime = dict.dict_find_int_value("mtime", 0);
std::string path = root_dir;
std::string path_element;
@ -419,71 +466,62 @@ namespace libtorrent
{
bdecode_node p = dict.dict_find_list("path.utf-8");
if (!p) p = dict.dict_find_list("path");
if (!p || p.list_size() == 0)
if (p && p.list_size() > 0)
{
int const preallocate = path.size() + path_length(p, ec);
if (ec) return false;
path.reserve(preallocate);
for (int i = 0, end(p.list_size()); i < end; ++i)
{
bdecode_node e = p.list_at(i);
if (i == end - 1)
{
filename = e.string_ptr() + info_ptr_diff;
filename_len = e.string_length();
}
sanitize_append_path_element(path, e.string_value());
}
}
else if (file_flags & file_storage::flag_pad_file)
{
// pad files don't need a path element, we'll just store them
// under the .pad directory
char cnt[10];
snprintf(cnt, sizeof(cnt), "%d", pad_file_cnt);
path = combine_path(".pad", cnt);
++pad_file_cnt;
}
else
{
ec = errors::torrent_missing_name;
return false;
}
int preallocate = int(path.size());
for (int i = 0, end(p.list_size()); i < end; ++i)
{
bdecode_node e = p.list_at(i);
if (e.type() != bdecode_node::string_t)
{
ec = errors::torrent_missing_name;
return false;
}
preallocate += e.string_length() + 1;
}
path.reserve(preallocate);
for (int i = 0, end(p.list_size()); i < end; ++i)
{
bdecode_node e = p.list_at(i);
if (i == end - 1)
{
filename = e.string_ptr() + info_ptr_diff;
filename_len = e.string_length();
}
sanitize_append_path_element(path, e.string_value());
}
}
// bitcomet pad file
std::uint32_t file_flags = 0;
if (path.find("_____padding_file_") != std::string::npos)
file_flags = file_storage::flag_pad_file;
bdecode_node attr = dict.dict_find_string("attr");
if (attr)
{
for (int i = 0; i < attr.string_length(); ++i)
{
switch (attr.string_ptr()[i])
{
case 'l': file_flags |= file_storage::flag_symlink; file_size = 0; break;
case 'x': file_flags |= file_storage::flag_executable; break;
case 'h': file_flags |= file_storage::flag_hidden; break;
case 'p': file_flags |= file_storage::flag_pad_file; break;
}
}
}
bdecode_node fh = dict.dict_find_string("sha1");
char const* filehash = nullptr;
if (fh && fh.string_length() == 20)
filehash = fh.string_ptr() + info_ptr_diff;
std::string symlink_path;
bdecode_node s_p = dict.dict_find("symlink path");
if (s_p && s_p.type() == bdecode_node::list_t
&& (file_flags & file_storage::flag_symlink))
if (file_flags & file_storage::flag_symlink)
{
for (int i = 0, end(s_p.list_size()); i < end; ++i)
if (bdecode_node s_p = dict.dict_find_list("symlink path"))
{
auto pe = s_p.list_at(i).string_value();
append_path(symlink_path, pe);
int const preallocate = path_length(s_p, ec);
if (ec) return false;
symlink_path.reserve(preallocate);
for (int i = 0, end(s_p.list_size()); i < end; ++i)
{
auto pe = s_p.list_at(i).string_value();
sanitize_append_path_element(symlink_path, pe);
}
}
}
else
@ -557,10 +595,12 @@ namespace libtorrent
}
target.reserve(list.list_size());
// this is the counter used to name pad files
int pad_file_cnt = 0;
for (int i = 0, end(list.list_size()); i < end; ++i)
{
if (!extract_single_file(list.list_at(i), target, root_dir
, info_ptr_diff, false, ec))
, info_ptr_diff, false, pad_file_cnt, ec))
return false;
}
return true;
@ -1095,7 +1135,9 @@ namespace libtorrent
{
// if there's no list of files, there has to be a length
// field.
if (!extract_single_file(info, files, "", info_ptr_diff, true, ec))
// this is the counter used to name pad files
int pad_file_cnt = 0;
if (!extract_single_file(info, files, "", info_ptr_diff, true, pad_file_cnt, ec))
return false;
m_flags &= ~multifile;

View File

@ -113,7 +113,6 @@ test-suite libtorrent :
test_sliding_average.cpp
test_socket_io.cpp
# test_random.cpp
test_gzip.cpp
test_part_file.cpp
test_peer_list.cpp
test_torrent_info.cpp
@ -155,6 +154,7 @@ test-suite libtorrent :
[ run test_bitfield.cpp ]
[ run test_crc32.cpp ]
[ run test_ffs.cpp ]
[ run test_gzip.cpp ]
[ run test_receive_buffer.cpp ]
[ run test_alert_manager.cpp ]
[ run test_magnet.cpp ]
@ -225,6 +225,7 @@ alias win-tests :
test_resume
test_tracker
test_checking
test_gzip
test_piece_picker
test_ffs
test_session_params

View File

@ -75,6 +75,7 @@ EXTRA_DIST = Jamfile \
test_torrents/invalid_pieces.torrent \
test_torrents/invalid_root_hash.torrent \
test_torrents/invalid_root_hash2.torrent \
test_torrents/invalid_symlink.torrent \
test_torrents/long_name.torrent \
test_torrents/missing_path_list.torrent \
test_torrents/missing_piece_len.torrent \
@ -84,6 +85,7 @@ EXTRA_DIST = Jamfile \
test_torrents/no_creation_date.torrent \
test_torrents/no_name.torrent \
test_torrents/pad_file.torrent \
test_torrents/pad_file_no_path.torrent \
test_torrents/parent_path.torrent \
test_torrents/root_hash.torrent \
test_torrents/sample.torrent \
@ -93,6 +95,7 @@ EXTRA_DIST = Jamfile \
test_torrents/slash_path3.torrent \
test_torrents/string.torrent \
test_torrents/symlink1.torrent \
test_torrents/symlink_zero_size.torrent \
test_torrents/unaligned_pieces.torrent \
test_torrents/unordered.torrent \
test_torrents/url_list.torrent \
@ -112,6 +115,7 @@ EXTRA_DIST = Jamfile \
mutable_test_torrents/test3.torrent \
mutable_test_torrents/test3_pad_files.torrent \
zeroes.gz \
corrupt.gz \
utf8_test.txt \
web_server.py \
socks.py \

BIN
test/corrupt.gz Normal file

Binary file not shown.

View File

@ -49,6 +49,7 @@ libtorrent::settings_pack settings()
pack.set_bool(settings_pack::enable_natpmp, false);
pack.set_bool(settings_pack::enable_upnp, false);
pack.set_bool(settings_pack::enable_dht, false);
pack.set_str(settings_pack::dht_bootstrap_nodes, "");
pack.set_bool(settings_pack::prefer_rc4, false);
pack.set_int(settings_pack::in_enc_policy, settings_pack::pe_disabled);

View File

@ -209,6 +209,7 @@ TORRENT_TEST(set_custom)
g_storage_constructor_invoked = false;
settings_pack p;
p.set_bool(settings_pack::enable_dht, false);
p.set_str(settings_pack::dht_bootstrap_nodes, "");
lt::session ses(p);
TEST_EQUAL(g_storage_constructor_invoked, false);
@ -217,6 +218,7 @@ TORRENT_TEST(set_custom)
ses.set_dht_storage(dht_custom_storage_constructor);
p.set_bool(settings_pack::enable_dht, true);
p.set_str(settings_pack::dht_bootstrap_nodes, "");
ses.apply_settings(p); // async with dispatch
TEST_CHECK(ses.is_dht_running());
TEST_EQUAL(g_storage_constructor_invoked, true);
@ -227,6 +229,7 @@ TORRENT_TEST(default_set_custom)
g_storage_constructor_invoked = false;
settings_pack p;
p.set_bool(settings_pack::enable_dht, true);
p.set_str(settings_pack::dht_bootstrap_nodes, "");
lt::session ses(p);
TEST_CHECK(ses.is_dht_running());

View File

@ -95,6 +95,7 @@ TORRENT_TEST(direct_dht_request)
sp.set_bool(settings_pack::enable_lsd, false);
sp.set_bool(settings_pack::enable_natpmp, false);
sp.set_bool(settings_pack::enable_upnp, false);
sp.set_str(settings_pack::dht_bootstrap_nodes, "");
sp.set_int(settings_pack::max_retry_port_bind, 800);
sp.set_str(settings_pack::listen_interfaces, "127.0.0.1:42434");
lt::session responder(sp, 0);
@ -117,6 +118,7 @@ TORRENT_TEST(direct_dht_request)
bdecode_node response = ra->response();
TEST_EQUAL(ra->addr.address(), address::from_string("127.0.0.1"));
TEST_EQUAL(ra->addr.port(), responder.listen_port());
TEST_EQUAL(response.type(), bdecode_node::dict_t);
TEST_EQUAL(response.dict_find_dict("r").dict_find_int_value("good"), 1);
TEST_EQUAL(ra->userdata, (void*)12345);
}

View File

@ -38,7 +38,7 @@ POSSIBILITY OF SUCH DAMAGE.
using namespace libtorrent;
TORRENT_TEST(gzip)
TORRENT_TEST(zeroes)
{
std::vector<char> zipped;
error_code ec;
@ -59,3 +59,19 @@ TORRENT_TEST(gzip)
TEST_EQUAL(inflated[i], 0);
}
TORRENT_TEST(corrupt)
{
std::vector<char> zipped;
error_code ec;
load_file(combine_path("..", "corrupt.gz"), zipped, ec, 1000000);
if (ec) fprintf(stderr, "failed to open file: (%d) %s\n", ec.value()
, ec.message().c_str());
TEST_CHECK(!ec);
std::vector<char> inflated;
inflate_gzip(&zipped[0], zipped.size(), inflated, 1000000, ec);
// we expect this to fail
TEST_CHECK(ec);
}

View File

@ -35,6 +35,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <utility>
#include "test.hpp"
#include "settings.hpp"
#include "libtorrent/socket_io.hpp"
#include "libtorrent/session.hpp"
@ -90,7 +91,7 @@ void test_rules_invariant(std::vector<ip_range<T> > const& r, ip_filter const& f
TORRENT_TEST(session_get_ip_filter)
{
using namespace libtorrent;
session ses;
session ses(settings());
ip_filter const& ipf = ses.get_ip_filter();
#if TORRENT_USE_IPV6
TEST_EQUAL(std::get<0>(ipf.export_filter()).size(), 1);

View File

@ -39,13 +39,14 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/torrent_info.hpp" // for announce_entry
#include "libtorrent/announce_entry.hpp"
#include "libtorrent/hex.hpp" // to_hex
#include "settings.hpp"
using namespace libtorrent;
namespace lt = libtorrent;
void test_remove_url(std::string url)
{
lt::session s;
lt::session s(settings());
add_torrent_params p;
p.flags &= ~add_torrent_params::flag_paused;
p.flags &= ~add_torrent_params::flag_auto_managed;
@ -79,7 +80,7 @@ TORRENT_TEST(magnet)
session_proxy p2;
// test session state load/restore
settings_pack pack;
settings_pack pack = settings();
pack.set_str(settings_pack::user_agent, "test");
pack.set_int(settings_pack::tracker_receive_timeout, 1234);
pack.set_int(settings_pack::file_pool_size, 543);
@ -181,7 +182,7 @@ TORRENT_TEST(magnet)
TEST_EQUAL(aux::to_hex(ih), "cdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcdcd");
p1 = s->abort();
s.reset(new lt::session());
s.reset(new lt::session(settings()));
std::vector<char> buf;
bencode(std::back_inserter(buf), session_state);

View File

@ -44,6 +44,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "test.hpp"
#include "setup_transfer.hpp"
#include "settings.hpp"
#include <fstream>
#include <iostream>
@ -386,7 +387,7 @@ done:
TORRENT_TEST(priority)
{
using namespace libtorrent;
settings_pack p;
settings_pack p = settings();
test_transfer(p);
cleanup();
}
@ -405,7 +406,7 @@ TORRENT_TEST(priority_deprecated)
// yet
TORRENT_TEST(no_metadata_file_prio)
{
settings_pack pack;
settings_pack pack = settings();
lt::session ses(pack);
add_torrent_params addp;
@ -425,7 +426,7 @@ TORRENT_TEST(no_metadata_file_prio)
TORRENT_TEST(no_metadata_piece_prio)
{
settings_pack pack;
settings_pack pack = settings();
lt::session ses(pack);
add_torrent_params addp;

View File

@ -36,6 +36,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "peer_server.hpp"
#include "udp_tracker.hpp"
#include "test_utils.hpp"
#include "settings.hpp"
#include "libtorrent/alert.hpp"
#include "libtorrent/random.hpp"
@ -101,7 +102,7 @@ session_proxy test_proxy(settings_pack::proxy_type_t proxy_type, int flags)
& ~alert::progress_notification
& ~alert::stats_notification;
settings_pack sett;
settings_pack sett = settings();
sett.set_int(settings_pack::stop_tracker_timeout, 2);
sett.set_int(settings_pack::tracker_completion_timeout, 2);
sett.set_int(settings_pack::tracker_receive_timeout, 2);

View File

@ -43,6 +43,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "test.hpp"
#include "settings.hpp"
#include "setup_transfer.hpp"
#include "settings.hpp"
using namespace libtorrent;
namespace lt = libtorrent;
@ -199,8 +200,7 @@ void default_tests(torrent_status const& s)
void test_piece_priorities(bool test_deprecated = false)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
std::shared_ptr<torrent_info> ti = generate_torrent();
add_torrent_params p;
p.ti = ti;
@ -276,7 +276,7 @@ TORRENT_TEST(piece_priorities)
#ifndef TORRENT_NO_DEPRECATE
TORRENT_TEST(file_priorities_default_deprecated)
{
lt::session ses;
lt::session ses(settings());
std::vector<int> file_priorities = test_resume_flags(ses, 0, "", "", true).file_priorities();
TEST_EQUAL(file_priorities.size(), 3);
@ -288,7 +288,7 @@ TORRENT_TEST(file_priorities_default_deprecated)
TORRENT_TEST(file_priorities_resume_seed_mode_deprecated)
{
// in share mode file priorities should always be 0
lt::session ses;
lt::session ses(settings());
std::vector<int> file_priorities = test_resume_flags(ses,
add_torrent_params::flag_share_mode, "", "123", true).file_priorities();
@ -301,7 +301,7 @@ TORRENT_TEST(file_priorities_resume_seed_mode_deprecated)
TORRENT_TEST(file_priorities_seed_mode_deprecated)
{
// in share mode file priorities should always be 0
lt::session ses;
lt::session ses(settings());
std::vector<int> file_priorities = test_resume_flags(ses,
add_torrent_params::flag_share_mode, "123", "", true).file_priorities();
@ -313,8 +313,7 @@ TORRENT_TEST(file_priorities_seed_mode_deprecated)
TORRENT_TEST(resume_save_load_deprecated)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
torrent_handle h = test_resume_flags(ses, 0, "123", "", true);
h.save_resume_data();
@ -340,8 +339,7 @@ TORRENT_TEST(resume_save_load_deprecated)
TORRENT_TEST(resume_save_load_resume_deprecated)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
torrent_handle h = test_resume_flags(ses, 0, "", "123", true);
h.save_resume_data();
@ -370,8 +368,7 @@ TORRENT_TEST(file_priorities_resume_override_deprecated)
// make sure that an empty file_priorities vector in add_torrent_params won't
// override the resume data file priorities, even when override resume data
// flag is set.
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
std::vector<int> file_priorities = test_resume_flags(ses,
add_torrent_params::flag_override_resume_data, "", "123", true).file_priorities();
@ -383,8 +380,7 @@ TORRENT_TEST(file_priorities_resume_override_deprecated)
TORRENT_TEST(file_priorities_resume_deprecated)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
std::vector<int> file_priorities = test_resume_flags(ses, 0, "", "123", true).file_priorities();
TEST_EQUAL(file_priorities.size(), 3);
@ -395,8 +391,7 @@ TORRENT_TEST(file_priorities_resume_deprecated)
TORRENT_TEST(file_priorities1_deprecated)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
std::vector<int> file_priorities = test_resume_flags(ses, 0, "010", "", true).file_priorities();
TEST_EQUAL(file_priorities.size(), 3);
@ -409,8 +404,7 @@ TORRENT_TEST(file_priorities1_deprecated)
TORRENT_TEST(file_priorities2_deprecated)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
std::vector<int> file_priorities = test_resume_flags(ses, 0, "123", "", true).file_priorities();
TEST_EQUAL(file_priorities.size(), 3);
@ -421,8 +415,7 @@ TORRENT_TEST(file_priorities2_deprecated)
TORRENT_TEST(file_priorities3_deprecated)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
std::vector<int> file_priorities = test_resume_flags(ses, 0, "4321", "", true).file_priorities();
TEST_EQUAL(file_priorities.size(), 3);
@ -433,8 +426,7 @@ TORRENT_TEST(file_priorities3_deprecated)
TORRENT_TEST(plain_deprecated)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
torrent_status s = test_resume_flags(ses, 0, "", "", true).status();
default_tests(s);
@ -457,8 +449,7 @@ TORRENT_TEST(plain_deprecated)
TORRENT_TEST(use_resume_save_path_deprecated)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
torrent_status s = test_resume_flags(ses, add_torrent_params::flag_use_resume_save_path, "", "", true).status();
default_tests(s);
#ifdef TORRENT_WINDOWS
@ -480,8 +471,7 @@ TORRENT_TEST(use_resume_save_path_deprecated)
TORRENT_TEST(override_resume_data_deprecated)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
torrent_status s = test_resume_flags(ses
, add_torrent_params::flag_override_resume_data
| add_torrent_params::flag_paused, "", "", true).status();
@ -506,8 +496,7 @@ TORRENT_TEST(override_resume_data_deprecated)
TORRENT_TEST(seed_mode_deprecated)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
torrent_status s = test_resume_flags(ses, add_torrent_params::flag_override_resume_data
| add_torrent_params::flag_seed_mode, "", "", true).status();
default_tests(s);
@ -530,8 +519,7 @@ TORRENT_TEST(seed_mode_deprecated)
TORRENT_TEST(upload_mode_deprecated)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
torrent_status s = test_resume_flags(ses, add_torrent_params::flag_upload_mode, "", "", true).status();
default_tests(s);
#ifdef TORRENT_WINDOWS
@ -553,8 +541,7 @@ TORRENT_TEST(upload_mode_deprecated)
TORRENT_TEST(share_mode_deprecated)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
torrent_status s = test_resume_flags(ses
, add_torrent_params::flag_override_resume_data
| add_torrent_params::flag_share_mode, "", "", true).status();
@ -578,8 +565,7 @@ TORRENT_TEST(share_mode_deprecated)
TORRENT_TEST(auto_managed_deprecated)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
// resume data overrides the auto-managed flag
torrent_status s = test_resume_flags(ses, add_torrent_params::flag_auto_managed, "", "", true).status();
default_tests(s);
@ -602,8 +588,7 @@ TORRENT_TEST(auto_managed_deprecated)
TORRENT_TEST(paused_deprecated)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
// resume data overrides the paused flag
torrent_status s = test_resume_flags(ses, add_torrent_params::flag_paused, "", "", true).status();
default_tests(s);
@ -632,8 +617,7 @@ TORRENT_TEST(url_seed_resume_data_deprecated)
{
// merge url seeds with resume data
std::fprintf(stderr, "flags: merge_resume_http_seeds\n");
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
torrent_handle h = test_resume_flags(ses,
add_torrent_params::flag_merge_resume_http_seeds, "", "", true);
std::set<std::string> us = h.url_seeds();
@ -656,8 +640,7 @@ TORRENT_TEST(resume_override_torrent_deprecated)
{
// resume data overrides the .torrent_file
std::fprintf(stderr, "flags: no merge_resume_http_seed\n");
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
torrent_handle h = test_resume_flags(ses,
add_torrent_params::flag_merge_resume_trackers, "", "", true);
std::set<std::string> us = h.url_seeds();
@ -675,7 +658,7 @@ TORRENT_TEST(resume_override_torrent_deprecated)
TORRENT_TEST(file_priorities_default)
{
lt::session ses;
lt::session ses(settings());
std::vector<int> file_priorities = test_resume_flags(ses, 0, "", "").file_priorities();
TEST_EQUAL(file_priorities.size(), 3);
@ -687,7 +670,7 @@ TORRENT_TEST(file_priorities_default)
TORRENT_TEST(file_priorities_resume_seed_mode)
{
// in share mode file priorities should always be 0
lt::session ses;
lt::session ses(settings());
std::vector<int> file_priorities = test_resume_flags(ses,
add_torrent_params::flag_share_mode, "", "123").file_priorities();
@ -700,7 +683,7 @@ TORRENT_TEST(file_priorities_resume_seed_mode)
TORRENT_TEST(file_priorities_seed_mode)
{
// in share mode file priorities should always be 0
lt::session ses;
lt::session ses(settings());
std::vector<int> file_priorities = test_resume_flags(ses,
add_torrent_params::flag_share_mode, "123", "").file_priorities();
@ -714,7 +697,7 @@ void test_zero_file_prio(bool test_deprecated = false)
{
std::fprintf(stderr, "test_file_prio\n");
lt::session ses;
lt::session ses(settings());
std::shared_ptr<torrent_info> ti = generate_torrent();
add_torrent_params p;
p.ti = ti;
@ -781,8 +764,7 @@ void test_seed_mode(bool const file_prio, bool const pieces_have, bool const pie
std::fprintf(stderr, "test_seed_mode file_prio: %d pieces_have: %d piece_prio: %d\n"
, file_prio, pieces_have, piece_prio);
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
std::shared_ptr<torrent_info> ti = generate_torrent();
add_torrent_params p;
p.ti = ti;
@ -899,8 +881,7 @@ TORRENT_TEST(seed_mode_preserve)
TORRENT_TEST(resume_save_load)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
torrent_handle h = test_resume_flags(ses, 0, "123", "");
h.save_resume_data();
@ -926,8 +907,7 @@ TORRENT_TEST(resume_save_load)
TORRENT_TEST(resume_save_load_resume)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
torrent_handle h = test_resume_flags(ses, 0, "", "123");
h.save_resume_data();
@ -955,8 +935,7 @@ TORRENT_TEST(resume_save_load_resume)
TORRENT_TEST(file_priorities_resume)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
std::vector<int> file_priorities = test_resume_flags(ses, 0, "", "123").file_priorities();
TEST_EQUAL(file_priorities.size(), 3);
@ -967,8 +946,7 @@ TORRENT_TEST(file_priorities_resume)
TORRENT_TEST(file_priorities1)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
std::vector<int> file_priorities = test_resume_flags(ses, 0, "010").file_priorities();
TEST_EQUAL(file_priorities.size(), 3);
@ -981,8 +959,7 @@ TORRENT_TEST(file_priorities1)
TORRENT_TEST(file_priorities2)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
std::vector<int> file_priorities = test_resume_flags(ses, 0, "123").file_priorities();
TEST_EQUAL(file_priorities.size(), 3);
@ -993,8 +970,7 @@ TORRENT_TEST(file_priorities2)
TORRENT_TEST(file_priorities3)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
std::vector<int> file_priorities = test_resume_flags(ses, 0, "4321").file_priorities();
TEST_EQUAL(file_priorities.size(), 3);
@ -1005,8 +981,7 @@ TORRENT_TEST(file_priorities3)
TORRENT_TEST(plain)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
torrent_status s = test_resume_flags(ses, 0).status();
default_tests(s);
@ -1029,8 +1004,7 @@ TORRENT_TEST(plain)
TORRENT_TEST(seed_mode)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
torrent_status s = test_resume_flags(ses
, add_torrent_params::flag_seed_mode).status();
default_tests(s);
@ -1053,8 +1027,7 @@ TORRENT_TEST(seed_mode)
TORRENT_TEST(upload_mode)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
torrent_status s = test_resume_flags(ses, add_torrent_params::flag_upload_mode).status();
default_tests(s);
#ifdef TORRENT_WINDOWS
@ -1076,8 +1049,7 @@ TORRENT_TEST(upload_mode)
TORRENT_TEST(share_mode)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
torrent_status s = test_resume_flags(ses
, add_torrent_params::flag_share_mode).status();
default_tests(s);
@ -1100,8 +1072,7 @@ TORRENT_TEST(share_mode)
TORRENT_TEST(auto_managed)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
// resume data overrides the auto-managed flag
torrent_status s = test_resume_flags(ses, add_torrent_params::flag_auto_managed).status();
default_tests(s);
@ -1124,8 +1095,7 @@ TORRENT_TEST(auto_managed)
TORRENT_TEST(paused)
{
settings_pack sett = settings();
lt::session ses(sett);
lt::session ses(settings());
// resume data overrides the paused flag
torrent_status s = test_resume_flags(ses, add_torrent_params::flag_paused).status();
default_tests(s);

View File

@ -41,6 +41,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/bdecode.hpp"
#include "libtorrent/bencode.hpp"
#include "libtorrent/torrent_info.hpp"
#include "settings.hpp"
#include <fstream>
@ -50,11 +51,11 @@ namespace lt = libtorrent;
TORRENT_TEST(session)
{
settings_pack p;
settings_pack p = settings();
p.set_int(settings_pack::alert_mask, ~0);
lt::session ses(p);
settings_pack sett;
settings_pack sett = settings();
sett.set_int(settings_pack::cache_size, 100);
sett.set_int(settings_pack::max_queued_disk_bytes, 1000 * 16 * 1024);
@ -98,7 +99,7 @@ TORRENT_TEST(session)
TORRENT_TEST(async_add_torrent_duplicate_error)
{
settings_pack p;
settings_pack p = settings();
p.set_int(settings_pack::alert_mask, ~0);
lt::session ses(p);
@ -122,7 +123,7 @@ TORRENT_TEST(async_add_torrent_duplicate_error)
TORRENT_TEST(async_add_torrent_duplicate)
{
settings_pack p;
settings_pack p = settings();
p.set_int(settings_pack::alert_mask, ~0);
lt::session ses(p);
@ -148,7 +149,7 @@ TORRENT_TEST(async_add_torrent_duplicate)
TORRENT_TEST(load_empty_file)
{
settings_pack p;
settings_pack p = settings();
p.set_int(settings_pack::alert_mask, ~0);
lt::session ses(p);
@ -180,7 +181,7 @@ TORRENT_TEST(session_stats)
TORRENT_TEST(paused_session)
{
lt::session s;
lt::session s(settings());
s.pause();
lt::add_torrent_params ps;
@ -203,14 +204,14 @@ void test_save_restore(Set setup, Save s, Default d, Load l)
{
entry st;
{
settings_pack p;
settings_pack p = settings();
setup(p);
lt::session ses(p);
s(ses, st);
}
{
settings_pack p;
settings_pack p = settings();
d(p);
lt::session ses(p);
// the loading function takes a bdecode_node, so we have to transform the

View File

@ -33,6 +33,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/config.hpp"
#include "libtorrent/session.hpp"
#include "libtorrent/extensions.hpp"
#include "settings.hpp"
#include "test.hpp"
@ -85,11 +86,12 @@ TORRENT_TEST(default_plugins)
TORRENT_TEST(custom_dht_storage)
{
g_storage_constructor_invoked = false;
session_params params;
settings_pack p = settings();
p.set_bool(settings_pack::enable_dht, true);
session_params params(p);
params.dht_storage_constructor = dht_custom_storage_constructor;
lt::session ses(params);
TEST_CHECK(ses.is_dht_running() == true);
TEST_EQUAL(g_storage_constructor_invoked, true);
}
@ -99,7 +101,7 @@ TORRENT_TEST(custom_dht_storage)
TORRENT_TEST(add_plugin)
{
g_plugin_added_invoked = false;
session_params params;
session_params params(settings());
params.extensions.push_back(std::make_shared<custom_plugin>());
lt::session ses(params);

View File

@ -39,6 +39,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/torrent.hpp"
#include "libtorrent/peer_info.hpp"
#include "libtorrent/extensions.hpp"
#include "settings.hpp"
#include <tuple>
#include <iostream>
@ -50,7 +51,7 @@ namespace lt = libtorrent;
void test_running_torrent(std::shared_ptr<torrent_info> info, std::int64_t file_size)
{
settings_pack pack;
settings_pack pack = settings();
pack.set_int(settings_pack::alert_mask, alert::storage_notification);
pack.set_str(settings_pack::listen_interfaces, "0.0.0.0:48130");
pack.set_int(settings_pack::max_retry_port_bind, 10);
@ -187,7 +188,7 @@ TORRENT_TEST(total_wanted)
auto info = std::make_shared<torrent_info>(
&tmp[0], int(tmp.size()), std::ref(ec));
settings_pack pack;
settings_pack pack = settings();
pack.set_int(settings_pack::alert_mask, alert::storage_notification);
pack.set_str(settings_pack::listen_interfaces, "0.0.0.0:48130");
pack.set_int(settings_pack::max_retry_port_bind, 10);
@ -225,7 +226,7 @@ TORRENT_TEST(added_peers)
auto info = std::make_shared<torrent_info>(
&tmp[0], int(tmp.size()), std::ref(ec));
settings_pack pack;
settings_pack pack = settings();
pack.set_str(settings_pack::listen_interfaces, "0.0.0.0:48130");
pack.set_int(settings_pack::max_retry_port_bind, 10);
lt::session ses(pack);
@ -354,7 +355,7 @@ TORRENT_TEST(duplicate_is_not_error)
p.save_path = ".";
p.extensions.push_back(creator);
lt::session ses;
lt::session ses(settings());
ses.async_add_torrent(p);
ses.async_add_torrent(p);

View File

@ -128,6 +128,8 @@ static test_torrent_t test_torrents[] =
{ "invalid_name3.torrent" },
{ "symlink1.torrent" },
{ "unordered.torrent" },
{ "symlink_zero_size.torrent" },
{ "pad_file_no_path.torrent" },
};
struct test_failing_torrent_t
@ -147,13 +149,14 @@ test_failing_torrent_t test_error_torrents[] =
{ "string.torrent", errors::torrent_is_no_dict },
{ "negative_size.torrent", errors::torrent_invalid_length },
{ "negative_file_size.torrent", errors::torrent_invalid_length },
{ "invalid_path_list.torrent", errors::torrent_missing_name},
{ "invalid_path_list.torrent", errors::torrent_invalid_name},
{ "missing_path_list.torrent", errors::torrent_missing_name },
{ "invalid_pieces.torrent", errors::torrent_missing_pieces },
{ "unaligned_pieces.torrent", errors::torrent_invalid_hashes },
{ "invalid_root_hash.torrent", errors::torrent_invalid_hashes },
{ "invalid_root_hash2.torrent", errors::torrent_missing_pieces },
{ "invalid_file_size.torrent", errors::torrent_invalid_length },
{ "invalid_symlink.torrent", errors::torrent_invalid_name },
};
// TODO: test remap_files
@ -164,7 +167,6 @@ test_failing_torrent_t test_error_torrents[] =
// TODO: torrent with 'l' (symlink) attribute
// TODO: creating a merkle torrent (torrent_info::build_merkle_list)
// TODO: torrent with multiple trackers in multiple tiers, making sure we shuffle them (how do you test shuffling?, load it multiple times and make sure it's in different order at least once)
// TODO: torrents with a missing name
// TODO: torrents with a zero-length name
// TODO: torrents with a merkle tree and add_merkle_nodes
// TODO: torrent with a non-dictionary info-section
@ -714,6 +716,16 @@ TORRENT_TEST(parse_torrents)
TEST_EQUAL(ti->num_files(), 1);
TEST_EQUAL(ti->files().file_path(0), "temp....abc");
}
else if (std::string(test_torrents[i].file) == "symlink_zero_size.torrent")
{
TEST_EQUAL(ti->num_files(), 2);
TEST_EQUAL(ti->files().symlink(1), combine_path("foo", "bar"));
}
else if (std::string(test_torrents[i].file) == "pad_file_no_path.torrent")
{
TEST_EQUAL(ti->num_files(), 2);
TEST_EQUAL(ti->files().file_path(1), combine_path(".pad", "0"));
}
file_storage const& fs = ti->files();
for (int i = 0; i < fs.num_files(); ++i)

View File

@ -0,0 +1 @@
d10:created by10:libtorrent13:creation datei1359599503e4:infod5:filesld6:lengthi0e4:pathl1:a1:b3:bareed4:attr1:l6:lengthi425e4:pathl1:a1:b3:foo12:symlink pathl3:foo3:bari4eeeee4:name4:temp12:piece lengthi16384e6:pieces20:‚ž¼Œ&¾ÇJW}ÜA4u,·¼‡ee

View File

@ -0,0 +1 @@
d10:created by10:libtorrent13:creation datei1359599503e4:infod5:filesld4:pathl3:foo7:bar.txte6:lengthi45eed4:attr1:p6:lengthi2124eee4:name4:temp12:piece lengthi16384e6:pieces20:‚ž¼Œ&¾ÇJW}ÜA4u,·¼‡ee

View File

@ -1 +1 @@
d10:created by10:libtorrent13:creation datei1359599503e4:infod5:filesld6:lengthi425e4:pathl1:a1:b3:bareed4:attr1:l6:lengthi425e4:pathl1:a1:b3:fooeee4:name4:temp12:piece lengthi16384e6:pieces20:‚ž¼Œ&¾ÇJW}ÜA4u,·¼‡ee
d10:created by10:libtorrent13:creation datei1359599503e4:infod5:filesld6:lengthi425e4:pathl1:a1:b3:bareed4:attr1:l6:lengthi425e4:pathl1:a1:b3:fooe12:symlink pathl3:foo3:bareee4:name4:temp12:piece lengthi16384e6:pieces20:‚ž¼Œ&¾ÇJW}ÜA4u,·¼‡ee

View File

@ -0,0 +1 @@
d10:created by10:libtorrent13:creation datei1359599503e4:infod5:filesld6:lengthi425e4:pathl1:a1:b3:bareed4:attr1:l4:pathl1:a1:b3:fooe12:symlink pathl3:foo3:bareee4:name4:temp12:piece lengthi16384e6:pieces20:aaaaaaaaaaaaaaaaaaaaee

View File

@ -33,6 +33,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include "test.hpp"
#include "setup_transfer.hpp"
#include "web_seed_suite.hpp"
#include "settings.hpp"
#include "libtorrent/create_torrent.hpp"
#include "libtorrent/torrent_info.hpp"
@ -88,10 +89,10 @@ TORRENT_TEST(web_seed_redirect)
, int(buf.size()), ec);
{
settings_pack settings;
settings.set_int(settings_pack::max_queued_disk_bytes, 256 * 1024);
settings.set_int(settings_pack::alert_mask, ~(alert::progress_notification | alert::stats_notification));
libtorrent::session ses(settings);
settings_pack p = settings();
p.set_int(settings_pack::max_queued_disk_bytes, 256 * 1024);
p.set_int(settings_pack::alert_mask, ~(alert::progress_notification | alert::stats_notification));
libtorrent::session ses(p);
// disable keep-alive because otherwise the test will choke on seeing
// the disconnect (from the redirect)