merge RC_1_1 into master

This commit is contained in:
arvidn 2017-10-08 18:21:25 +02:00
commit 1d15e6bfb4
18 changed files with 251 additions and 129 deletions

View File

@ -79,6 +79,8 @@
1.1.5 release
* fix parsing of torrents with certain invalid filenames
* fix leak of torrent_peer objecs (entries in peer_list)
* fix leak of peer_class objects (when setting per-torrent rate limits)
* expose peer_class API to python binding
* fix integer overflow in whole_pieces_threshold logic

125
Jamfile
View File

@ -47,27 +47,24 @@ VERSION = 1.2.0 ;
# rule for linking the correct libraries depending
# on features and target-os
rule linking ( properties * )
rule link-openssl ( properties * )
{
local result ;
# openssl libraries, if enabled
# exclude gcc from a regular windows build to make mingw
# link against the regular unix library name
if <crypto>openssl in $(properties)
if <openssl-version>pre1.1 in $(properties)
&& <target-os>windows in $(properties)
&& ! <toolset>gcc in $(properties)
{
if <openssl-version>pre1.1 in $(properties)
&& <target-os>windows in $(properties)
&& ! <toolset>gcc in $(properties)
{
result += <library>ssleay32 <library>libeay32 ;
}
else
{
# on windows the library names were changed to be in line with other
# system starting with OpenSSL 1.1
result += <library>crypto <library>ssl ;
}
result += <library>ssleay32 <library>libeay32 ;
}
else
{
# on windows the library names were changed to be in line with other
# system starting with OpenSSL 1.1
result += <library>crypto <library>ssl ;
}
if <crypto>libcrypto in $(properties)
@ -88,9 +85,7 @@ rule linking ( properties * )
}
# windows needs some more libraries when using openSSL
if ( <crypto>openssl in $(properties)
|| <crypto>libcrypto in $(propertes) )
&& <target-os>windows in $(properties)
if <target-os>windows in $(properties)
&& ! <toolset>gcc in $(properties)
{
result += <library>advapi32
@ -99,7 +94,13 @@ rule linking ( properties * )
<library>gdi32
;
}
echo "link openssl = " $(result) ;
return $(result) ;
}
rule linking ( properties * )
{
local result ;
if <simulator>on in $(properties)
{
result += <library>/libsimulator//simulator ;
@ -375,7 +376,7 @@ rule default-build ( properties * )
return $(result) ;
}
rule tag ( name : type ? : property-set )
rule tag ( name : type ? : property-set )
{
name = [ virtual-target.add-prefix-and-suffix $(name) : $(type) : $(property-set) ] ;
@ -388,6 +389,78 @@ rule tag ( name : type ? : property-set )
return $(name) ;
}
# the search path to pick up the openssl libraries from. This is the <search>
# property of those libraries
rule openssl-lib-path ( properties * )
{
local OPENSSL_LIB = [ feature.get-values <openssl-lib> : $(properties) ] ;
if <target-os>darwin in $(properties) && $(OPENSSL_LIB) = ""
{
# on macOS, default to pick up openssl from the homebrew installation
# brew install openssl
OPENSSL_LIB = /usr/local/opt/openssl/lib ;
}
else if <target-os>windows in $(properties)
&& <toolset>gcc in $(properties)
&& $(OPENSSL_LIB) = ""
{
# on mingw, assume openssl is installed in c:\OpenSSL-Win32 by default
OPENSSL_LIB = c:\\OpenSSL-Win32\\lib ;
}
else if <target-os>windows in $(properties) && $(OPENSSL_LIB) = ""
{
# on windows, just assume openssl is installed to c:\openssl
if <address-model>64 in $(properties)
{ OPENSSL_LIB = c:\\openssl\\lib64 ; }
else
{ OPENSSL_LIB = c:\\openssl\\lib ; }
}
local result ;
result += <search>$(OPENSSL_LIB) ;
echo "openssl-lib-path = " $(result) ;
return $(result) ;
}
# the include path to pick up openssl headers from. This is the
# usage-requirement for the openssl-related libraries
rule openssl-include-path ( properties * )
{
local OPENSSL_INCLUDE = [ feature.get-values <openssl-include> : $(properties) ] ;
if <target-os>darwin in $(properties) && $(OPENSSL_INCLUDE) = ""
{
# on macOS, default to pick up openssl from the homebrew installation
# brew install openssl
OPENSSL_INCLUDE = /usr/local/opt/openssl/include ;
}
else if <target-os>windows in $(properties)
&& <toolset>gcc in $(properties)
&& $(OPENSSL_INCLUDE) = ""
{
# on mingw, assume openssl is installed in c:\OpenSSL-Win32 by default
OPENSSL_INCLUDE = c:\\OpenSSL-Win32\\include ;
}
else if <target-os>windows in $(properties) && $(OPENSSL_INCLUDE) = ""
{
# on windows, just assume openssl is installed to c:\openssl
# not sure if there's a better way to find out where it may be
if <address-model>64 in $(properties)
{ OPENSSL_INCLUDE = c:\\openssl\\include64 ; }
else
{ OPENSSL_INCLUDE = c:\\openssl\\include ; }
}
local result ;
result += <include>$(OPENSSL_INCLUDE) ;
echo "openssl-include-path = " $(result) ;
return $(result) ;
}
feature openssl-lib : : free path ;
feature openssl-include : : free path ;
feature ipv6 : on off : composite propagated link-incompatible ;
feature.compose <ipv6>off : <define>TORRENT_USE_IPV6=0 ;
@ -515,9 +588,12 @@ variant test_arm : debug
<export-extra>on <asserts>on
;
lib crypto : : <name>crypto <conditional>@openssl-lib-path : : <conditional>@openssl-include-path ;
lib ssl : : <name>ssl <use>crypto <conditional>@openssl-lib-path : : <conditional>@openssl-include-path ;
# required for openssl on windows
lib ssleay32 : : <name>ssleay32 ;
lib libeay32 : : <name>libeay32 ;
lib ssleay32 : : <name>ssleay32 <conditional>@openssl-lib-path : : <conditional>@openssl-include-path ;
lib libeay32 : : <name>libeay32 <conditional>@openssl-lib-path : : <conditional>@openssl-include-path ;
lib advapi32 : : <name>advapi32 ;
lib user32 : : <name>user32 ;
lib shell32 : : <name>shell32 ;
@ -534,12 +610,7 @@ lib libiconv : : <name>iconv <link>shared <search>/usr/local/lib ;
# openssl on linux/bsd etc.
lib gcrypt : : <name>gcrypt <link>shared <search>/opt/local/lib ;
# pick up openssl on macos from brew
lib crypto : : <name>crypto <target-os>darwin <search>/usr/local/opt/openssl/lib : <link>shared : <include>/usr/local/opt/openssl/include ;
lib ssl : : <name>ssl <use>crypto <target-os>darwin <search>/usr/local/opt/openssl/lib : <link>shared : <include>/usr/local/opt/openssl/include ;
lib crypto : : <name>crypto : <link>shared ;
lib ssl : : <name>ssl <use>crypto : <link>shared ;
alias openssl-libraries : : : : <conditional>@link-openssl ;
lib libsocket : : <use>libnsl <name>socket <link>shared <search>/usr/sfw/lib <link>shared ;
lib libnsl : : <name>nsl <link>shared <search>/usr/sfw/lib <link>shared ;
@ -754,6 +825,8 @@ lib torrent
<link>shared:<define>TORRENT_BUILDING_SHARED
<define>BOOST_NO_DEPRECATED
<link>shared:<define>BOOST_SYSTEM_SOURCE
<crypto>openssl:<library>openssl-libraries
<crypto>libcrypto:<library>openssl-libraries
<dht>on:<source>src/kademlia/$(KADEMLIA_SOURCES).cpp
<dht>on:<source>ed25519/src/$(ED25519_SOURCES).cpp

View File

@ -20,8 +20,6 @@ environment:
model: 64
python: 1
crypto: openssl
linkflags: 'linkflags="/LIBPATH:C:\\openssl-1.0.1p-vs2015\\lib64"'
include: 'include="c:\\openssl-1.0.1p-vs2015\\include"'
- variant: test_debug
compiler: gcc
model: 32
@ -38,10 +36,11 @@ install:
- if %compiler% == msvc-14.0 if defined crypto (
echo extracting openssl-2015
& 7z x -oc:\ -aoa openssl-1.0.1p-vs2015.7z > nul
& copy c:\openssl-1.0.1p-vs2015\lib64\ssleay32MT.lib c:\openssl-1.0.1p-vs2015\lib64\ssleay32.lib
& copy c:\openssl-1.0.1p-vs2015\lib64\libeay32MT.lib c:\openssl-1.0.1p-vs2015\lib64\libeay32.lib
& copy c:\openssl-1.0.1p-vs2015\lib\ssleay32MT.lib c:\openssl-1.0.1p-vs2015\lib\ssleay32.lib
& copy c:\openssl-1.0.1p-vs2015\lib\libeay32MT.lib c:\openssl-1.0.1p-vs2015\lib\libeay32.lib
& rename c:\openssl-1.0.1p-vs2015 openssl
& copy c:\openssl\lib64\ssleay32MT.lib c:\openssl\lib64\ssleay32.lib
& copy c:\openssl\lib64\libeay32MT.lib c:\openssl\lib64\libeay32.lib
& copy c:\openssl\lib\ssleay32MT.lib c:\openssl\lib\ssleay32.lib
& copy c:\openssl\lib\libeay32MT.lib c:\openssl\lib\libeay32.lib
)
- if not defined crypto ( set crypto=built-in )
- if not defined linkflags ( set linkflags="" )
@ -69,32 +68,32 @@ cache:
build_script:
# examples
- cd %ROOT_DIRECTORY%\examples
- b2.exe --hash openssl-version=pre1.1 warnings-as-errors=on -j2 %compiler% address-model=%model% debug-iterators=on picker-debugging=on invariant-checks=full variant=%variant% %linkflags% %include% link=shared crypto=%crypto%
- b2.exe --hash crypto=openssl openssl-version=pre1.1 warnings-as-errors=on -j2 %compiler% address-model=%model% debug-iterators=on picker-debugging=on invariant-checks=full variant=%variant% %linkflags% %include% link=shared crypto=%crypto%
# tools
- cd %ROOT_DIRECTORY%\tools
- b2.exe --hash openssl-version=pre1.1 warnings-as-errors=on -j2 %compiler% address-model=%model% debug-iterators=on picker-debugging=on invariant-checks=full variant=%variant% %linkflags% %include% link=shared crypto=%crypto%
- b2.exe --hash crypto=openssl openssl-version=pre1.1 warnings-as-errors=on -j2 %compiler% address-model=%model% debug-iterators=on picker-debugging=on invariant-checks=full variant=%variant% %linkflags% %include% link=shared crypto=%crypto%
# test
- cd %ROOT_DIRECTORY%\test
- b2.exe --hash openssl-version=pre1.1 warnings-as-errors=on -j2 %compiler% address-model=%model% debug-iterators=on picker-debugging=on invariant-checks=full variant=%variant% %linkflags% %include% link=shared crypto=%crypto% win-tests test_upnp test_natpmp testing.execute=off
- b2.exe --hash crypto=openssl openssl-version=pre1.1 warnings-as-errors=on -j2 %compiler% address-model=%model% debug-iterators=on picker-debugging=on invariant-checks=full variant=%variant% %linkflags% %include% link=shared crypto=%crypto% win-tests test_upnp test_natpmp testing.execute=off
# python binding
- cd %ROOT_DIRECTORY%\bindings\python
# we use 64 bit python builds
- if defined python (
b2.exe --hash openssl-version=pre1.1 warnings-as-errors=on -j2 %compiler% address-model=%model% debug-iterators=on picker-debugging=on invariant-checks=full variant=%variant% %linkflags% %include% link=shared crypto=%crypto% libtorrent-link=shared stage_module stage_dependencies
b2.exe --hash crypto=openssl openssl-version=pre1.1 warnings-as-errors=on -j2 %compiler% address-model=%model% debug-iterators=on picker-debugging=on invariant-checks=full variant=%variant% %linkflags% %include% link=shared crypto=%crypto% libtorrent-link=shared stage_module stage_dependencies
)
# simulations
- cd %ROOT_DIRECTORY%\simulation
- if defined sim (
b2.exe --hash openssl-version=pre1.1 warnings-as-errors=on -j2 %compiler% address-model=%model% debug-iterators=on picker-debugging=on invariant-checks=full variant=%variant% deprecated-functions=off %linkflags% %include% link=shared crypto=built-in testing.execute=off
b2.exe --hash crypto=openssl openssl-version=pre1.1 warnings-as-errors=on -j2 %compiler% address-model=%model% debug-iterators=on picker-debugging=on invariant-checks=full variant=%variant% deprecated-functions=off %linkflags% %include% link=shared crypto=built-in testing.execute=off
)
test_script:
- cd %ROOT_DIRECTORY%\test
- appveyor-retry b2.exe -l400 --hash openssl-version=pre1.1 warnings-as-errors=on -j2 %compiler% address-model=%model% debug-iterators=on picker-debugging=on invariant-checks=full variant=%variant% %linkflags% %include% link=shared crypto=%crypto% win-tests
- appveyor-retry b2.exe -l400 --hash crypto=openssl openssl-version=pre1.1 warnings-as-errors=on -j2 %compiler% address-model=%model% debug-iterators=on picker-debugging=on invariant-checks=full variant=%variant% %linkflags% %include% link=shared crypto=%crypto% win-tests
- cd %ROOT_DIRECTORY%\bindings\python
# we use 64 bit python build

View File

@ -23,9 +23,9 @@ rm -f bindings/python/Makefile bindings/python/Makefile.in
chmod a-x docs/*.rst docs/*.htm* src/*.cpp include/libtorrent/*.hpp
./autotool.sh
./configure --enable-python-binding --enable-examples=yes --enable-encryption --enable-tests=yes --with-boost-system=mt --with-boost-python=mt
./configure --enable-python-binding --enable-examples=yes --enable-encryption --enable-tests=yes --with-boost-system=mt --with-boost-chrono=mt --with-boost-random=mt --with-boost-python=mt --with-openssl=/usr/local/opt/openssl
make V=1 -j8 check
./configure --enable-python-binding --enable-examples=yes --enable-encryption --with-boost-system=mt --with-boost-python=mt
./configure --enable-python-binding --enable-examples=yes --enable-encryption --with-boost-system=mt --with-boost-chrono=mt --with-boost-random=mt --with-boost-python=mt --with-openssl=/usr/local/opt/openssl
make V=1 -j8 dist

View File

@ -237,6 +237,14 @@ windows format (``c:/boost_1_64_0``).
The ``Jamfile`` will define ``NDEBUG`` when it's building a release build.
For more build configuration flags see `Build configurations`_.
When enabling linking against openssl (by setting the ``crypto`` feature to
``openssl``) the Jamfile will look in some default directory for the openssl
headers and libraries. On macOS, it will look for the homebrew openssl package.
On windows it will look in ``c:\openssl`` and mingw in ``c:\OpenSSL-Win32``.
To customize the library path and include path for openssl, set the features
``openssl-lib`` and ``openssl-include`` respectively.
Build features:
+--------------------------+----------------------------------------------------+
@ -247,6 +255,13 @@ Build features:
| | * ``shared`` - links dynamically against the boost |
| | libraries. |
+--------------------------+----------------------------------------------------+
| ``openssl-lib`` | can be used to specify the directory where libssl |
| | and libcrypto are installed (or the windows |
| | counterparts). |
+--------------------------+----------------------------------------------------+
| ``openssl-include`` | can be used to specify the include directory where |
| | the openssl headers are installed. |
+--------------------------+----------------------------------------------------+
| ``logging`` | * ``off`` - logging alerts disabled. The |
| | reason to disable logging is to keep the binary |
| | size low where that matters. |
@ -281,9 +296,10 @@ Build features:
| ``crypto`` | * ``built-in`` - (default) uses built-in SHA-1 |
| | implementation. In macOS/iOS it uses |
| | CommonCrypto SHA-1 implementation. |
| | * ``openssl`` - links against openssl to enable |
| | torrents over ssl feature. |
| | the option crypto=libcrypto. |
| | * ``openssl`` - links against openssl and |
| | libcrypto to use for SHA-1 hashing. |
| | This also enables HTTPS-tracker support and |
| | support for bittorrent over SSL. |
| | * ``libcrypto`` - links against libcrypto |
| | to use the SHA-1 implementation. |
| | * ``gcrypt`` - links against libgcrypt |

View File

@ -294,8 +294,8 @@ namespace aux {
void reopen_listen_sockets();
void reopen_outgoing_sockets();
torrent_peer_allocator_interface* get_peer_allocator() override
{ return &m_peer_allocator; }
torrent_peer_allocator_interface& get_peer_allocator() override
{ return m_peer_allocator; }
io_service& get_io_service() override { return m_io_service; }
resolver_interface& get_resolver() override { return m_host_resolver; }

View File

@ -147,7 +147,7 @@ namespace libtorrent { namespace aux {
virtual alert_manager& alerts() = 0;
virtual torrent_peer_allocator_interface* get_peer_allocator() = 0;
virtual torrent_peer_allocator_interface& get_peer_allocator() = 0;
virtual io_service& get_io_service() = 0;
virtual resolver_interface& get_resolver() = 0;

View File

@ -168,13 +168,6 @@ POSSIBILITY OF SUCH DAMAGE.
#if TARGET_OS_IPHONE
#define TORRENT_USE_SC_NETWORK_REACHABILITY 1
#endif
#else // __APPLE__
// FreeBSD has a reasonable iconv signature
// unless we're on glibc
#ifndef __GLIBC__
# define TORRENT_ICONV_ARG(x) (x)
#endif
#endif // __APPLE__
#define TORRENT_USE_DEV_RANDOM 1
@ -328,7 +321,6 @@ POSSIBILITY OF SUCH DAMAGE.
#define TORRENT_USE_IFCONF 1
#define TORRENT_USE_SYSCTL 1
#define TORRENT_USE_IPV6 0
#define TORRENT_ICONV_ARG(x) (x)
#define TORRENT_USE_WRITEV 0
#define TORRENT_USE_READV 0
@ -355,10 +347,6 @@ POSSIBILITY OF SUCH DAMAGE.
#define TORRENT_NO_RETURN
#endif
#ifndef TORRENT_ICONV_ARG
#define TORRENT_ICONV_ARG(x) const_cast<char**>(x)
#endif
#if defined __GNUC__ || defined __clang__
#define TORRENT_FORMAT(fmt, ellipsis) __attribute__((__format__(__printf__, fmt, ellipsis)))
#else

View File

@ -71,7 +71,6 @@ namespace libtorrent {
, loop_counter(0)
, port(0)
, max_failcount(3)
, peer_allocator(nullptr)
{}
bool is_paused;
bool is_finished;
@ -98,9 +97,6 @@ namespace libtorrent {
// a connect candidate
int max_failcount;
// this must be set to a torrent_peer allocator
torrent_peer_allocator_interface* peer_allocator;
// if any peer were removed during this call, they are returned in
// this vector. The caller would want to make sure there are no
// references to these torrent_peers anywhere
@ -111,7 +107,8 @@ namespace libtorrent {
{
public:
peer_list();
peer_list(torrent_peer_allocator_interface& alloc);
~peer_list();
#if TORRENT_USE_I2P
torrent_peer* add_i2p_peer(string_view destination
@ -209,6 +206,10 @@ namespace libtorrent {
private:
// not copyable
peer_list(peer_list const&);
peer_list& operator=(peer_list const&);
void recalculate_connect_candidates(torrent_state* state);
void update_connect_candidates(int delta);
@ -242,6 +243,10 @@ namespace libtorrent {
// if so, don't delete it.
torrent_peer* m_locked_peer;
// the peer allocator, as stored from the constructor
// this must be available in the destructor to free all peers
torrent_peer_allocator_interface& m_peer_allocator;
// the number of seeds in the torrent_peer list
std::uint32_t m_num_seeds:31;
@ -257,7 +262,7 @@ namespace libtorrent {
// since the torrent_peer list can grow too large
// to scan all of it, start at this index
int m_round_robin;
int m_round_robin = 0;
// a list of good connect candidates
std::vector<torrent_peer*> m_candidate_cache;
@ -268,11 +273,11 @@ namespace libtorrent {
// yet reached their max try count and they
// have the connectable state (we have a listen
// port for them).
int m_num_connect_candidates;
int m_num_connect_candidates = 0;
// if a peer has failed this many times or more, we don't consider
// it a connect candidate anymore.
int m_max_failcount;
int m_max_failcount = 3;
};
}

View File

@ -549,6 +549,17 @@ namespace libtorrent {
#if TORRENT_USE_ICONV
namespace {
// this is a helper function to deduce the type of the second argument to
// the iconv() function.
template <typename Input>
size_t call_iconv(size_t (&fun)(iconv_t, Input**, size_t*, char**, size_t*)
, iconv_t cd, char const** in, size_t* insize, char** out, size_t* outsize)
{
return fun(cd, const_cast<Input**>(in), insize, out, outsize);
}
std::string iconv_convert_impl(std::string const& s, iconv_t h)
{
std::string ret;
@ -557,11 +568,10 @@ namespace {
ret.resize(outsize);
char const* in = s.c_str();
char* out = &ret[0];
// posix has a weird iconv signature. implementations
// differ on what this signature should be, so we use
// a macro to let config.hpp determine it
size_t retval = ::iconv(h, TORRENT_ICONV_ARG(&in), &insize,
&out, &outsize);
// posix has a weird iconv() signature. implementations
// differ on the type of the second parameter. We use a helper template
// to deduce what we need to cast to.
std::size_t const retval = call_iconv(::iconv, h, &in, &insize, &out, &outsize);
if (retval == size_t(-1)) return s;
// if this string has an invalid utf-8 sequence in it, don't touch it
if (insize != 0) return s;

View File

@ -114,17 +114,24 @@ namespace {
namespace libtorrent {
peer_list::peer_list()
peer_list::peer_list(torrent_peer_allocator_interface& alloc)
: m_locked_peer(nullptr)
, m_peer_allocator(alloc)
, m_num_seeds(0)
, m_finished(0)
, m_round_robin(0)
, m_num_connect_candidates(0)
, m_max_failcount(3)
{
thread_started();
}
peer_list::~peer_list()
{
for (peers_t::iterator i = m_peers.begin()
, end(m_peers.end()); i != end; ++i)
{
m_peer_allocator.free_peer_entry(*i);
}
}
void peer_list::set_max_failcount(torrent_state* state)
{
if (state->max_failcount == m_max_failcount) return;
@ -293,7 +300,7 @@ namespace libtorrent {
(*i)->in_use = false;
#endif
state->peer_allocator->free_peer_entry(*i);
m_peer_allocator.free_peer_entry(*i);
m_peers.erase(i);
}
@ -746,7 +753,7 @@ namespace libtorrent {
#else
bool const is_v6 = false;
#endif
torrent_peer* p = state->peer_allocator->allocate_peer_entry(
torrent_peer* p = m_peer_allocator.allocate_peer_entry(
is_v6 ? torrent_peer_allocator_interface::ipv6_peer_type
: torrent_peer_allocator_interface::ipv4_peer_type);
if (p == nullptr) return false;
@ -1024,7 +1031,7 @@ namespace libtorrent {
// we don't have any info about this peer.
// add a new entry
torrent_peer* p = state->peer_allocator->allocate_peer_entry(
torrent_peer* p = m_peer_allocator.allocate_peer_entry(
torrent_peer_allocator_interface::i2p_peer_type);
if (p == nullptr) return nullptr;
new (p) i2p_peer(destination, true, src);
@ -1039,7 +1046,7 @@ namespace libtorrent {
p->in_use = false;
#endif
state->peer_allocator->free_peer_entry(p);
m_peer_allocator.free_peer_entry(p);
return nullptr;
}
return p;
@ -1094,7 +1101,7 @@ namespace libtorrent {
#else
bool const is_v6 = false;
#endif
p = state->peer_allocator->allocate_peer_entry(
p = m_peer_allocator.allocate_peer_entry(
is_v6 ? torrent_peer_allocator_interface::ipv6_peer_type
: torrent_peer_allocator_interface::ipv4_peer_type);
if (p == nullptr) return nullptr;
@ -1115,7 +1122,8 @@ namespace libtorrent {
#if TORRENT_USE_ASSERTS
p->in_use = false;
#endif
state->peer_allocator->free_peer_entry(p);
// TODO: 3 this is not exception safe!
m_peer_allocator.free_peer_entry(p);
return nullptr;
}
state->first_time_seen = true;

View File

@ -1026,7 +1026,7 @@ namespace libtorrent {
void torrent::need_peer_list()
{
if (m_peer_list) return;
m_peer_list.reset(new peer_list);
m_peer_list.reset(new peer_list(m_ses.get_peer_allocator()));
}
void torrent::handle_exception()
@ -9975,7 +9975,6 @@ namespace libtorrent {
: settings().get_int(settings_pack::max_peerlist_size);
ret.min_reconnect_time = settings().get_int(settings_pack::min_reconnect_time);
ret.peer_allocator = m_ses.get_peer_allocator();
ret.ip = m_ses.external_address();
ret.port = m_ses.listen_port();
ret.max_failcount = settings().get_int(settings_pack::max_failcount);

View File

@ -424,6 +424,7 @@ namespace {
if (p && p.list_size() > 0)
{
std::size_t const preallocate = path.size() + std::size_t(path_length(p, ec));
std::size_t const orig_path_len = path.size();
if (ec) return false;
path.reserve(preallocate);
@ -439,6 +440,14 @@ namespace {
}
sanitize_append_path_element(path, e.string_value());
}
// if all path elements were sanitized away, we need to use another
// name instead
if (path.size() == orig_path_len)
{
path += TORRENT_SEPARATOR;
path += "_";
}
}
else if (file_flags & file_storage::flag_pad_file)
{

View File

@ -110,6 +110,8 @@ EXTRA_DIST = Jamfile \
test_torrents/url_seed_multi_space.torrent \
test_torrents/url_seed_multi_space_nolist.torrent \
test_torrents/whitespace_url.torrent \
test_torrents/invalid_filename.torrent \
test_torrents/invalid_filename2.torrent \
mutable_test_torrents/test1.torrent \
mutable_test_torrents/test1_pad_files.torrent \
mutable_test_torrents/test1_single.torrent\

View File

@ -164,14 +164,13 @@ bool has_peer(peer_list const& p, tcp::endpoint const& ep)
return its.first != its.second;
}
torrent_state init_state(torrent_peer_allocator& allocator)
torrent_state init_state()
{
torrent_state st;
st.is_finished = false;
st.is_paused = false;
st.max_peerlist_size = 1000;
st.allow_multiple_connections_per_ip = false;
st.peer_allocator = &allocator;
st.port = 9999;
return st;
}
@ -205,9 +204,9 @@ static torrent_peer_allocator allocator;
// when disallowing it
TORRENT_TEST(multiple_ips_disallowed)
{
torrent_state st = init_state(allocator);
torrent_state st = init_state();
mock_torrent t(&st);
peer_list p;
peer_list p(allocator);
t.m_p = &p;
TEST_EQUAL(p.num_connect_candidates(), 0);
torrent_peer* peer1 = p.add_peer(ep("10.0.0.2", 3000), {}, 0, &st);
@ -227,10 +226,10 @@ TORRENT_TEST(multiple_ips_disallowed)
// when allowing it
TORRENT_TEST(multiple_ips_allowed)
{
torrent_state st = init_state(allocator);
torrent_state st = init_state();
mock_torrent t(&st);
st.allow_multiple_connections_per_ip = true;
peer_list p;
peer_list p(allocator);
t.m_p = &p;
torrent_peer* peer1 = p.add_peer(ep("10.0.0.2", 3000), {}, 0, &st);
TEST_EQUAL(p.num_connect_candidates(), 1);
@ -249,10 +248,10 @@ TORRENT_TEST(multiple_ips_allowed)
// with allow_multiple_connections_per_ip enabled
TORRENT_TEST(multiple_ips_allowed2)
{
torrent_state st = init_state(allocator);
torrent_state st = init_state();
mock_torrent t(&st);
st.allow_multiple_connections_per_ip = true;
peer_list p;
peer_list p(allocator);
t.m_p = &p;
torrent_peer* peer1 = p.add_peer(ep("10.0.0.2", 3000), {}, 0, &st);
TEST_EQUAL(p.num_connect_candidates(), 1);
@ -288,10 +287,10 @@ TORRENT_TEST(multiple_ips_allowed2)
// with allow_multiple_connections_per_ip disabled
TORRENT_TEST(multiple_ips_disallowed2)
{
torrent_state st = init_state(allocator);
torrent_state st = init_state();
mock_torrent t(&st);
st.allow_multiple_connections_per_ip = false;
peer_list p;
peer_list p(allocator);
t.m_p = &p;
torrent_peer* peer1 = p.add_peer(ep("10.0.0.2", 3000), {}, 0, &st);
TEST_EQUAL(p.num_connect_candidates(), 1);
@ -322,10 +321,10 @@ TORRENT_TEST(multiple_ips_disallowed2)
// and update_peer_port
TORRENT_TEST(update_peer_port)
{
torrent_state st = init_state(allocator);
torrent_state st = init_state();
mock_torrent t(&st);
st.allow_multiple_connections_per_ip = false;
peer_list p;
peer_list p(allocator);
t.m_p = &p;
TEST_EQUAL(p.num_connect_candidates(), 0);
auto c = std::make_shared<mock_peer_connection>(&t, true, ep("10.0.0.1", 8080));
@ -345,10 +344,10 @@ TORRENT_TEST(update_peer_port)
// and update_peer_port, causing collission
TORRENT_TEST(update_peer_port_collide)
{
torrent_state st = init_state(allocator);
torrent_state st = init_state();
mock_torrent t(&st);
st.allow_multiple_connections_per_ip = true;
peer_list p;
peer_list p(allocator);
t.m_p = &p;
torrent_peer* peer2 = p.add_peer(ep("10.0.0.1", 4000), {}, 0, &st);
@ -381,10 +380,10 @@ std::shared_ptr<mock_peer_connection> shared_from_this(lt::peer_connection_inter
// test ip filter
TORRENT_TEST(ip_filter)
{
torrent_state st = init_state(allocator);
torrent_state st = init_state();
mock_torrent t(&st);
st.allow_multiple_connections_per_ip = false;
peer_list p;
peer_list p(allocator);
t.m_p = &p;
// add peer 1
@ -419,10 +418,10 @@ TORRENT_TEST(ip_filter)
// test port filter
TORRENT_TEST(port_filter)
{
torrent_state st = init_state(allocator);
torrent_state st = init_state();
mock_torrent t(&st);
st.allow_multiple_connections_per_ip = false;
peer_list p;
peer_list p(allocator);
t.m_p = &p;
// add peer 1
@ -457,10 +456,10 @@ TORRENT_TEST(port_filter)
// test banning peers
TORRENT_TEST(ban_peers)
{
torrent_state st = init_state(allocator);
torrent_state st = init_state();
mock_torrent t(&st);
st.allow_multiple_connections_per_ip = false;
peer_list p;
peer_list p(allocator);
t.m_p = &p;
torrent_peer* peer1 = add_peer(p, st, ep("10.0.0.1", 4000));
@ -497,11 +496,11 @@ TORRENT_TEST(ban_peers)
// test erase_peers when we fill up the peer list
TORRENT_TEST(erase_peers)
{
torrent_state st = init_state(allocator);
torrent_state st = init_state();
mock_torrent t(&st);
st.max_peerlist_size = 100;
st.allow_multiple_connections_per_ip = true;
peer_list p;
peer_list p(allocator);
t.m_p = &p;
for (int i = 0; i < 100; ++i)
@ -530,11 +529,11 @@ TORRENT_TEST(erase_peers)
// test set_ip_filter
TORRENT_TEST(set_ip_filter)
{
torrent_state st = init_state(allocator);
torrent_state st = init_state();
std::vector<address> banned;
mock_torrent t(&st);
peer_list p;
peer_list p(allocator);
t.m_p = &p;
for (int i = 0; i < 100; ++i)
@ -560,11 +559,11 @@ TORRENT_TEST(set_ip_filter)
// test set_port_filter
TORRENT_TEST(set_port_filter)
{
torrent_state st = init_state(allocator);
torrent_state st = init_state();
std::vector<address> banned;
mock_torrent t(&st);
peer_list p;
peer_list p(allocator);
t.m_p = &p;
for (int i = 0; i < 100; ++i)
@ -591,10 +590,10 @@ TORRENT_TEST(set_port_filter)
// test set_max_failcount
TORRENT_TEST(set_max_failcount)
{
torrent_state st = init_state(allocator);
torrent_state st = init_state();
mock_torrent t(&st);
peer_list p;
peer_list p(allocator);
t.m_p = &p;
for (int i = 0; i < 100; ++i)
@ -621,10 +620,10 @@ TORRENT_TEST(set_max_failcount)
// test set_seed
TORRENT_TEST(set_seed)
{
torrent_state st = init_state(allocator);
torrent_state st = init_state();
mock_torrent t(&st);
peer_list p;
peer_list p(allocator);
t.m_p = &p;
for (int i = 0; i < 100; ++i)
@ -655,11 +654,11 @@ TORRENT_TEST(set_seed)
// test has_peer
TORRENT_TEST(has_peer)
{
torrent_state st = init_state(allocator);
torrent_state st = init_state();
std::vector<address> banned;
mock_torrent t(&st);
peer_list p;
peer_list p(allocator);
t.m_p = &p;
torrent_peer* peer1 = add_peer(p, st, ep("10.10.0.1", 10));
@ -687,11 +686,11 @@ TORRENT_TEST(has_peer)
// test connect_candidates torrent_finish
TORRENT_TEST(connect_candidates_finish)
{
torrent_state st = init_state(allocator);
torrent_state st = init_state();
std::vector<address> banned;
mock_torrent t(&st);
peer_list p;
peer_list p(allocator);
t.m_p = &p;
torrent_peer* peer1 = add_peer(p, st, ep("10.10.0.1", 10));
@ -726,10 +725,10 @@ TORRENT_TEST(connect_candidates_finish)
// test self-connection
TORRENT_TEST(self_connection)
{
torrent_state st = init_state(allocator);
torrent_state st = init_state();
mock_torrent t(&st);
st.allow_multiple_connections_per_ip = false;
peer_list p;
peer_list p(allocator);
t.m_p = &p;
// add and connect peer
@ -756,10 +755,10 @@ TORRENT_TEST(self_connection)
// test double connection (both incoming)
TORRENT_TEST(double_connection)
{
torrent_state st = init_state(allocator);
torrent_state st = init_state();
mock_torrent t(&st);
st.allow_multiple_connections_per_ip = false;
peer_list p;
peer_list p(allocator);
t.m_p = &p;
// we are 10.0.0.1 and the other peer is 10.0.0.2
@ -784,10 +783,10 @@ TORRENT_TEST(double_connection)
// test double connection (we loose)
TORRENT_TEST(double_connection_loose)
{
torrent_state st = init_state(allocator);
torrent_state st = init_state();
mock_torrent t(&st);
st.allow_multiple_connections_per_ip = false;
peer_list p;
peer_list p(allocator);
t.m_p = &p;
// we are 10.0.0.1 and the other peer is 10.0.0.2
@ -813,10 +812,10 @@ TORRENT_TEST(double_connection_loose)
// test double connection (we win)
TORRENT_TEST(double_connection_win)
{
torrent_state st = init_state(allocator);
torrent_state st = init_state();
mock_torrent t(&st);
st.allow_multiple_connections_per_ip = false;
peer_list p;
peer_list p(allocator);
t.m_p = &p;
// we are 10.0.0.1 and the other peer is 10.0.0.2
@ -842,11 +841,11 @@ TORRENT_TEST(double_connection_win)
// test incoming connection when we are at the list size limit
TORRENT_TEST(incoming_size_limit)
{
torrent_state st = init_state(allocator);
torrent_state st = init_state();
st.max_peerlist_size = 5;
mock_torrent t(&st);
st.allow_multiple_connections_per_ip = false;
peer_list p;
peer_list p(allocator);
t.m_p = &p;
torrent_peer* peer1 = add_peer(p, st, ep("10.0.0.1", 8080));
@ -887,11 +886,11 @@ TORRENT_TEST(incoming_size_limit)
// test new peer when we are at the list size limit
TORRENT_TEST(new_peer_size_limit)
{
torrent_state st = init_state(allocator);
torrent_state st = init_state();
st.max_peerlist_size = 5;
mock_torrent t(&st);
st.allow_multiple_connections_per_ip = false;
peer_list p;
peer_list p(allocator);
t.m_p = &p;
torrent_peer* peer1 = add_peer(p, st, ep("10.0.0.1", 8080));

View File

@ -128,6 +128,8 @@ static test_torrent_t test_torrents[] =
{ "pad_file_no_path.torrent" },
{ "large.torrent" },
{ "absolute_filename.torrent" },
{ "invalid_filename.torrent" },
{ "invalid_filename2.torrent" },
};
struct test_failing_torrent_t
@ -802,6 +804,14 @@ TORRENT_TEST(parse_torrents)
TEST_EQUAL(ti->files().file_path(file_index_t{0}), combine_path("temp", "abcde"));
TEST_EQUAL(ti->files().file_path(file_index_t{1}), combine_path("temp", "foobar"));
}
else if (std::string(test_torrents[i].file) == "invalid_filename.torrent")
{
TEST_EQUAL(ti->num_files(), 2);
}
else if (std::string(test_torrents[i].file) == "invalid_filename2.torrent")
{
TEST_EQUAL(ti->num_files(), 3);
}
file_storage const& fs = ti->files();
for (file_index_t i{0}; i != file_index_t(fs.num_files()); ++i)

View File

@ -0,0 +1 @@
d10:created by10:libtorrent13:creation datei1419490173e4:infod5:filesld6:lengthi51200e4:pathl1:feed6:lengthi14336e4:pathl1:.eee4:name5:\est212:piece lengthi16384e6:pieces80:01234567890123456789012345678901234567890123456789012345678901234567890123456789ee

View File

@ -0,0 +1 @@
d10:created by10:libtorrent13:creation datei1419490173e4:infod5:filesld6:lengthi51200e4:pathl1:feed6:lengthi14335e4:pathl1:.1:.eed6:lengthi1e4:pathl1:/1:.eee4:name5:\est212:piece lengthi16384e6:pieces80:01234567890123456789012345678901234567890123456789012345678901234567890123456789ee