merge fix
This commit is contained in:
commit
36a5a11ee2
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
1.1.1 release
|
1.1.1 release
|
||||||
|
|
||||||
|
* fix set_settings in python binding
|
||||||
* Added missing alert categories in python binding
|
* Added missing alert categories in python binding
|
||||||
* Added dht_get_peers_reply_alert alert in python binding
|
* Added dht_get_peers_reply_alert alert in python binding
|
||||||
|
|
||||||
|
|
|
@ -102,16 +102,17 @@ namespace
|
||||||
void make_settings_pack(lt::settings_pack& p, dict const& sett_dict)
|
void make_settings_pack(lt::settings_pack& p, dict const& sett_dict)
|
||||||
{
|
{
|
||||||
list iterkeys = (list)sett_dict.keys();
|
list iterkeys = (list)sett_dict.keys();
|
||||||
for (int i = 0; i < boost::python::len(iterkeys); i++)
|
int const len = boost::python::len(iterkeys);
|
||||||
|
for (int i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
std::string key = extract<std::string>(iterkeys[i]);
|
std::string const key = extract<std::string>(iterkeys[i]);
|
||||||
|
|
||||||
int sett = setting_by_name(key);
|
int sett = setting_by_name(key);
|
||||||
if (sett == 0) continue;
|
if (sett < 0) continue;
|
||||||
|
|
||||||
TORRENT_TRY
|
TORRENT_TRY
|
||||||
{
|
{
|
||||||
object value = sett_dict[key];
|
object const value = sett_dict[key];
|
||||||
switch (sett & settings_pack::type_mask)
|
switch (sett & settings_pack::type_mask)
|
||||||
{
|
{
|
||||||
case settings_pack::string_type_base:
|
case settings_pack::string_type_base:
|
||||||
|
|
|
@ -182,8 +182,9 @@ class test_session(unittest.TestCase):
|
||||||
def test_apply_settings(self):
|
def test_apply_settings(self):
|
||||||
|
|
||||||
s = lt.session({})
|
s = lt.session({})
|
||||||
s.apply_settings({'num_want': 66})
|
s.apply_settings({'num_want': 66, 'user_agent': 'test123'})
|
||||||
self.assertEqual(s.get_settings()['num_want'], 66)
|
self.assertEqual(s.get_settings()['num_want'], 66)
|
||||||
|
self.assertEqual(s.get_settings()['user_agent'], 'test123')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
|
|
@ -5,7 +5,6 @@ nobase_include_HEADERS = \
|
||||||
add_torrent_params.hpp \
|
add_torrent_params.hpp \
|
||||||
alert.hpp \
|
alert.hpp \
|
||||||
alert_manager.hpp \
|
alert_manager.hpp \
|
||||||
alert_observer.hpp \
|
|
||||||
alert_types.hpp \
|
alert_types.hpp \
|
||||||
alloca.hpp \
|
alloca.hpp \
|
||||||
allocator.hpp \
|
allocator.hpp \
|
||||||
|
@ -202,4 +201,3 @@ nobase_include_HEADERS = \
|
||||||
kademlia/item.hpp \
|
kademlia/item.hpp \
|
||||||
kademlia/get_item.hpp \
|
kademlia/get_item.hpp \
|
||||||
kademlia/get_peers.hpp
|
kademlia/get_peers.hpp
|
||||||
|
|
||||||
|
|
|
@ -1,58 +0,0 @@
|
||||||
/*
|
|
||||||
|
|
||||||
Copyright (c) 2012-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.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef TORRENT_ALERT_OBSERVER_HPP_INCLUDED
|
|
||||||
#define TORRENT_ALERT_OBSERVER_HPP_INCLUDED
|
|
||||||
|
|
||||||
#include <boost/cstdint.hpp>
|
|
||||||
|
|
||||||
namespace libtorrent
|
|
||||||
{
|
|
||||||
|
|
||||||
class alert;
|
|
||||||
|
|
||||||
struct alert_observer
|
|
||||||
{
|
|
||||||
friend struct alert_handler;
|
|
||||||
|
|
||||||
alert_observer(): num_types(0), flags(0) {}
|
|
||||||
virtual void handle_alert(alert const* a) = 0;
|
|
||||||
private:
|
|
||||||
boost::uint8_t types[64];
|
|
||||||
int num_types;
|
|
||||||
int flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // TORRENT_ALERT_OBSERVER_HPP_INCLUDED
|
|
||||||
|
|
|
@ -779,7 +779,7 @@ namespace libtorrent
|
||||||
|
|
||||||
// the peer class all TCP peers belong to by default
|
// the peer class all TCP peers belong to by default
|
||||||
// all tcp peer connections are subject to these
|
// all tcp peer connections are subject to these
|
||||||
// bandwidth limits. Local peers are excempted
|
// bandwidth limits. Local peers are exempted
|
||||||
// from this limit. The purpose is to be able to
|
// from this limit. The purpose is to be able to
|
||||||
// throttle TCP that passes over the internet
|
// throttle TCP that passes over the internet
|
||||||
// bottleneck (i.e. modem) to avoid starving out
|
// bottleneck (i.e. modem) to avoid starving out
|
||||||
|
@ -925,7 +925,7 @@ namespace libtorrent
|
||||||
int m_auto_manage_time_scaler;
|
int m_auto_manage_time_scaler;
|
||||||
|
|
||||||
// works like unchoke_time_scaler but it
|
// works like unchoke_time_scaler but it
|
||||||
// is only decresed when the unchoke set
|
// is only decreased when the unchoke set
|
||||||
// is recomputed, and when it reaches zero,
|
// is recomputed, and when it reaches zero,
|
||||||
// the optimistic unchoke is moved to another peer.
|
// the optimistic unchoke is moved to another peer.
|
||||||
// TODO: replace this by a proper asio timer
|
// TODO: replace this by a proper asio timer
|
||||||
|
@ -979,7 +979,7 @@ namespace libtorrent
|
||||||
boost::uint16_t session_time() const TORRENT_OVERRIDE
|
boost::uint16_t session_time() const TORRENT_OVERRIDE
|
||||||
{
|
{
|
||||||
// +1 is here to make it possible to distinguish uninitialized (to
|
// +1 is here to make it possible to distinguish uninitialized (to
|
||||||
// 0) timestamps and timestamps of things that happend during the
|
// 0) timestamps and timestamps of things that happened during the
|
||||||
// first second after the session was constructed
|
// first second after the session was constructed
|
||||||
boost::int64_t const ret = total_seconds(aux::time_now()
|
boost::int64_t const ret = total_seconds(aux::time_now()
|
||||||
- m_created) + 1;
|
- m_created) + 1;
|
||||||
|
@ -1053,7 +1053,8 @@ namespace libtorrent
|
||||||
libtorrent::utp_socket_manager m_utp_socket_manager;
|
libtorrent::utp_socket_manager m_utp_socket_manager;
|
||||||
|
|
||||||
#ifdef TORRENT_USE_OPENSSL
|
#ifdef TORRENT_USE_OPENSSL
|
||||||
// used for uTP connectons over SSL
|
// used for uTP connections over SSL
|
||||||
|
udp_socket m_ssl_udp_socket;
|
||||||
libtorrent::utp_socket_manager m_ssl_utp_socket_manager;
|
libtorrent::utp_socket_manager m_ssl_utp_socket_manager;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
// The bitfiled type stores any number of bits as a bitfield
|
// The bitfield type stores any number of bits as a bitfield
|
||||||
// in a heap allocated array.
|
// in a heap allocated array.
|
||||||
struct TORRENT_EXPORT bitfield
|
struct TORRENT_EXPORT bitfield
|
||||||
{
|
{
|
||||||
|
@ -55,7 +55,7 @@ namespace libtorrent
|
||||||
//
|
//
|
||||||
// The constructor taking a pointer ``b`` and ``bits`` copies a bitfield
|
// The constructor taking a pointer ``b`` and ``bits`` copies a bitfield
|
||||||
// from the specified buffer, and ``bits`` number of bits (rounded up to
|
// from the specified buffer, and ``bits`` number of bits (rounded up to
|
||||||
// the nearest byte boundry).
|
// the nearest byte boundary).
|
||||||
bitfield(): m_buf(NULL) {}
|
bitfield(): m_buf(NULL) {}
|
||||||
bitfield(int bits): m_buf(NULL)
|
bitfield(int bits): m_buf(NULL)
|
||||||
{ resize(bits); }
|
{ resize(bits); }
|
||||||
|
|
|
@ -157,4 +157,3 @@ namespace libtorrent
|
||||||
TORRENT_ASSERT(size() == bits);
|
TORRENT_ASSERT(size() == bits);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,7 +87,7 @@ namespace libtorrent
|
||||||
bool c2_quota_complete = !rhs->is_choked() && c2
|
bool c2_quota_complete = !rhs->is_choked() && c2
|
||||||
> (std::max)(t2->torrent_file().piece_length() * pieces, 256 * 1024);
|
> (std::max)(t2->torrent_file().piece_length() * pieces, 256 * 1024);
|
||||||
|
|
||||||
// if c2 has completed a quanta, it shuold be de-prioritized
|
// if c2 has completed a quanta, it should be de-prioritized
|
||||||
// and vice versa
|
// and vice versa
|
||||||
if (c1_quota_complete < c2_quota_complete) return true;
|
if (c1_quota_complete < c2_quota_complete) return true;
|
||||||
if (c1_quota_complete > c2_quota_complete) return false;
|
if (c1_quota_complete > c2_quota_complete) return false;
|
||||||
|
@ -174,7 +174,7 @@ namespace libtorrent
|
||||||
|
|
||||||
// the anti-leech seeding algorithm is based on the paper "Improving
|
// the anti-leech seeding algorithm is based on the paper "Improving
|
||||||
// BitTorrent: A Simple Approach" from Chow et. al. and ranks peers based
|
// BitTorrent: A Simple Approach" from Chow et. al. and ranks peers based
|
||||||
// on how many pieces they have, prefering to unchoke peers that just
|
// on how many pieces they have, preferring to unchoke peers that just
|
||||||
// started and peers that are close to completing. Like this:
|
// started and peers that are close to completing. Like this:
|
||||||
// ^
|
// ^
|
||||||
// | \ / |
|
// | \ / |
|
||||||
|
@ -417,4 +417,3 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -82,14 +82,14 @@ namespace libtorrent
|
||||||
struct stat s;
|
struct stat s;
|
||||||
if (lstat(convert_to_native(p).c_str(), &s) < 0) return 0;
|
if (lstat(convert_to_native(p).c_str(), &s) < 0) return 0;
|
||||||
int file_attr = 0;
|
int file_attr = 0;
|
||||||
if (s.st_mode & S_IXUSR)
|
if (s.st_mode & S_IXUSR)
|
||||||
file_attr += file_storage::attribute_executable;
|
file_attr += file_storage::attribute_executable;
|
||||||
if (S_ISLNK(s.st_mode))
|
if (S_ISLNK(s.st_mode))
|
||||||
file_attr += file_storage::attribute_symlink;
|
file_attr += file_storage::attribute_symlink;
|
||||||
return file_attr;
|
return file_attr;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TORRENT_WINDOWS
|
#ifndef TORRENT_WINDOWS
|
||||||
std::string get_symlink_path_impl(char const* path)
|
std::string get_symlink_path_impl(char const* path)
|
||||||
{
|
{
|
||||||
|
@ -150,7 +150,7 @@ namespace libtorrent
|
||||||
|
|
||||||
// mask all bits to check if the file is a symlink
|
// mask all bits to check if the file is a symlink
|
||||||
if ((file_flags & file_storage::attribute_symlink)
|
if ((file_flags & file_storage::attribute_symlink)
|
||||||
&& (flags & create_torrent::symlinks))
|
&& (flags & create_torrent::symlinks))
|
||||||
{
|
{
|
||||||
std::string sym_path = get_symlink_path(f);
|
std::string sym_path = get_symlink_path(f);
|
||||||
fs.add_file(l, 0, file_flags, s.mtime, sym_path);
|
fs.add_file(l, 0, file_flags, s.mtime, sym_path);
|
||||||
|
@ -324,10 +324,8 @@ namespace libtorrent
|
||||||
, m_include_mtime((flags & modification_time) != 0)
|
, m_include_mtime((flags & modification_time) != 0)
|
||||||
, m_include_symlinks((flags & symlinks) != 0)
|
, m_include_symlinks((flags & symlinks) != 0)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(fs.num_files() > 0);
|
|
||||||
|
|
||||||
// return instead of crash in release mode
|
// return instead of crash in release mode
|
||||||
if (fs.num_files() == 0) return;
|
if (fs.num_files() == 0 || fs.total_size() == 0) return;
|
||||||
|
|
||||||
if (!m_multifile && has_parent_path(m_files.file_path(0))) m_multifile = true;
|
if (!m_multifile && has_parent_path(m_files.file_path(0))) m_multifile = true;
|
||||||
|
|
||||||
|
@ -386,6 +384,10 @@ namespace libtorrent
|
||||||
, m_include_symlinks(false)
|
, m_include_symlinks(false)
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(ti.is_valid());
|
TORRENT_ASSERT(ti.is_valid());
|
||||||
|
TORRENT_ASSERT(ti.num_pieces() > 0);
|
||||||
|
TORRENT_ASSERT(ti.num_files() > 0);
|
||||||
|
TORRENT_ASSERT(ti.total_size() > 0);
|
||||||
|
|
||||||
if (ti.creation_date()) m_creation_date = *ti.creation_date();
|
if (ti.creation_date()) m_creation_date = *ti.creation_date();
|
||||||
|
|
||||||
if (!ti.creator().empty()) set_creator(ti.creator().c_str());
|
if (!ti.creator().empty()) set_creator(ti.creator().c_str());
|
||||||
|
@ -420,15 +422,15 @@ namespace libtorrent
|
||||||
|
|
||||||
entry create_torrent::generate() const
|
entry create_torrent::generate() const
|
||||||
{
|
{
|
||||||
TORRENT_ASSERT(m_files.piece_length() > 0);
|
|
||||||
|
|
||||||
entry dict;
|
entry dict;
|
||||||
|
|
||||||
if (m_files.num_files() == 0)
|
if (m_files.num_files() == 0 || m_files.total_size() == 0)
|
||||||
return dict;
|
return dict;
|
||||||
|
|
||||||
|
TORRENT_ASSERT(m_files.piece_length() > 0);
|
||||||
|
|
||||||
if (!m_urls.empty()) dict["announce"] = m_urls.front().first;
|
if (!m_urls.empty()) dict["announce"] = m_urls.front().first;
|
||||||
|
|
||||||
if (!m_nodes.empty())
|
if (!m_nodes.empty())
|
||||||
{
|
{
|
||||||
entry& nodes = dict["nodes"];
|
entry& nodes = dict["nodes"];
|
||||||
|
@ -470,7 +472,7 @@ namespace libtorrent
|
||||||
|
|
||||||
if (!m_created_by.empty())
|
if (!m_created_by.empty())
|
||||||
dict["created by"] = m_created_by;
|
dict["created by"] = m_created_by;
|
||||||
|
|
||||||
if (!m_url_seeds.empty())
|
if (!m_url_seeds.empty())
|
||||||
{
|
{
|
||||||
if (m_url_seeds.size() == 1)
|
if (m_url_seeds.size() == 1)
|
||||||
|
|
|
@ -443,6 +443,8 @@ namespace aux {
|
||||||
#if TORRENT_USE_ASSERTS
|
#if TORRENT_USE_ASSERTS
|
||||||
m_posting_torrent_updates = false;
|
m_posting_torrent_updates = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
update_time_now();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function is called by the creating thread, not in the message loop's
|
// This function is called by the creating thread, not in the message loop's
|
||||||
|
|
|
@ -1345,7 +1345,6 @@ namespace libtorrent
|
||||||
|
|
||||||
if (m_abort)
|
if (m_abort)
|
||||||
{
|
{
|
||||||
piece_block block_finished(p.piece, p.start / block_size());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11474,4 +11473,3 @@ namespace libtorrent
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -471,7 +471,7 @@ public:
|
||||||
// we set our cwnd to 1 MSS. This condition can happen either because
|
// we set our cwnd to 1 MSS. This condition can happen either because
|
||||||
// a packet has timed out and needs to be resent or because our
|
// a packet has timed out and needs to be resent or because our
|
||||||
// cwnd is set to less than one MSS during congestion control.
|
// cwnd is set to less than one MSS during congestion control.
|
||||||
// it can also happen if the other end sends an advertized window
|
// it can also happen if the other end sends an advertised window
|
||||||
// size less than one MSS.
|
// size less than one MSS.
|
||||||
time_point m_timeout;
|
time_point m_timeout;
|
||||||
|
|
||||||
|
@ -1819,7 +1819,7 @@ bool utp_socket_impl::send_pkt(int flags)
|
||||||
, effective_mtu - header_size);
|
, effective_mtu - header_size);
|
||||||
|
|
||||||
// if we have one MSS worth of data, make sure it fits in our
|
// if we have one MSS worth of data, make sure it fits in our
|
||||||
// congestion window and the advertized receive window from
|
// congestion window and the advertised receive window from
|
||||||
// the other end.
|
// the other end.
|
||||||
if (m_bytes_in_flight + payload_size > (std::min)(int(m_cwnd >> 16)
|
if (m_bytes_in_flight + payload_size > (std::min)(int(m_cwnd >> 16)
|
||||||
, int(m_adv_wnd - m_bytes_in_flight)))
|
, int(m_adv_wnd - m_bytes_in_flight)))
|
||||||
|
@ -2425,7 +2425,7 @@ void utp_socket_impl::ack_packet(packet* p, time_point const& receive_time
|
||||||
// this means our clock is not monotonic. Just assume the RTT was 100 ms
|
// this means our clock is not monotonic. Just assume the RTT was 100 ms
|
||||||
rtt = 100000;
|
rtt = 100000;
|
||||||
|
|
||||||
// the clock for this plaform is not monotonic!
|
// the clock for this platform is not monotonic!
|
||||||
TORRENT_ASSERT(false);
|
TORRENT_ASSERT(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2543,7 +2543,7 @@ bool utp_socket_impl::consume_incoming_data(
|
||||||
{
|
{
|
||||||
// if we don't have a buffer from the upper layer, and the
|
// if we don't have a buffer from the upper layer, and the
|
||||||
// number of queued up bytes, waiting for the upper layer,
|
// number of queued up bytes, waiting for the upper layer,
|
||||||
// exceeds the advertized receive window, start ignoring
|
// exceeds the advertised receive window, start ignoring
|
||||||
// more data packets
|
// more data packets
|
||||||
UTP_LOG("%8p: ERROR: our advertized window is not honored. "
|
UTP_LOG("%8p: ERROR: our advertized window is not honored. "
|
||||||
"recv_buf: %d buffered_in: %d max_size: %d\n"
|
"recv_buf: %d buffered_in: %d max_size: %d\n"
|
||||||
|
@ -2850,7 +2850,7 @@ bool utp_socket_impl::incoming_packet(aux::array_view<boost::uint8_t const> buf
|
||||||
{
|
{
|
||||||
// this is too far out to fit in our reorder buffer. Drop it
|
// this is too far out to fit in our reorder buffer. Drop it
|
||||||
// This is either an attack to try to break the connection
|
// This is either an attack to try to break the connection
|
||||||
// or a seariously damaged connection that lost a lot of
|
// or a seriously damaged connection that lost a lot of
|
||||||
// packets. Neither is very likely, and it should be OK
|
// packets. Neither is very likely, and it should be OK
|
||||||
// to drop the timestamp information.
|
// to drop the timestamp information.
|
||||||
UTP_LOG("%8p: ERROR: incoming packet seq_nr:%d our ack_nr:%d (ignored)\n"
|
UTP_LOG("%8p: ERROR: incoming packet seq_nr:%d our ack_nr:%d (ignored)\n"
|
||||||
|
@ -3187,7 +3187,7 @@ bool utp_socket_impl::incoming_packet(aux::array_view<boost::uint8_t const> buf
|
||||||
{
|
{
|
||||||
// we need to ack some data we received, and we didn't
|
// we need to ack some data we received, and we didn't
|
||||||
// end up sending any payload packets in the loop
|
// end up sending any payload packets in the loop
|
||||||
// above (becasue m_out_packets would have been incremented
|
// above (because m_out_packets would have been incremented
|
||||||
// in that case). This means we need to send an ack.
|
// in that case). This means we need to send an ack.
|
||||||
// don't do it right away, because we may still receive
|
// don't do it right away, because we may still receive
|
||||||
// more packets. defer the ack to send as few acks as possible
|
// more packets. defer the ack to send as few acks as possible
|
||||||
|
@ -3200,7 +3200,7 @@ bool utp_socket_impl::incoming_packet(aux::array_view<boost::uint8_t const> buf
|
||||||
|
|
||||||
if (m_state == UTP_STATE_ERROR_WAIT || m_state == UTP_STATE_DELETE) return true;
|
if (m_state == UTP_STATE_ERROR_WAIT || m_state == UTP_STATE_DELETE) return true;
|
||||||
|
|
||||||
// Everything up to the FIN has been receieved, respond with a FIN
|
// Everything up to the FIN has been received, respond with a FIN
|
||||||
// from our side.
|
// from our side.
|
||||||
if (m_eof && m_ack_nr == ((m_eof_seq_nr - 1) & ACK_MASK))
|
if (m_eof && m_ack_nr == ((m_eof_seq_nr - 1) & ACK_MASK))
|
||||||
{
|
{
|
||||||
|
@ -3404,7 +3404,7 @@ void utp_socket_impl::do_ledbat(const int acked_bytes, const int delay
|
||||||
|
|
||||||
// the portion of the in-flight bytes that were acked. This is used to make
|
// the portion of the in-flight bytes that were acked. This is used to make
|
||||||
// the gain factor be scaled by the rtt. The formula is applied once per
|
// the gain factor be scaled by the rtt. The formula is applied once per
|
||||||
// rtt, or on every ACK skaled by the number of ACKs per rtt
|
// rtt, or on every ACK scaled by the number of ACKs per rtt
|
||||||
TORRENT_ASSERT(in_flight > 0);
|
TORRENT_ASSERT(in_flight > 0);
|
||||||
TORRENT_ASSERT(acked_bytes > 0);
|
TORRENT_ASSERT(acked_bytes > 0);
|
||||||
|
|
||||||
|
@ -3450,7 +3450,7 @@ void utp_socket_impl::do_ledbat(const int acked_bytes, const int delay
|
||||||
// bytes to cwnd
|
// bytes to cwnd
|
||||||
if (m_ssthres != 0 && ((m_cwnd + exponential_gain) >> 16) > m_ssthres)
|
if (m_ssthres != 0 && ((m_cwnd + exponential_gain) >> 16) > m_ssthres)
|
||||||
{
|
{
|
||||||
// if we would exeed the slow start threshold by growing the cwnd
|
// if we would exceed the slow start threshold by growing the cwnd
|
||||||
// exponentially, don't do it, and leave slow-start mode. This
|
// exponentially, don't do it, and leave slow-start mode. This
|
||||||
// make us avoid causing more delay and/or packet loss by being too
|
// make us avoid causing more delay and/or packet loss by being too
|
||||||
// aggressive
|
// aggressive
|
||||||
|
@ -3760,4 +3760,3 @@ void utp_socket_impl::check_invariant() const
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,7 @@ struct dht_server
|
||||||
|
|
||||||
fprintf(stderr, "%s: DHT initialized on port %d\n", time_now_string(), m_port);
|
fprintf(stderr, "%s: DHT initialized on port %d\n", time_now_string(), m_port);
|
||||||
|
|
||||||
m_thread.reset(new thread(boost::bind(&dht_server::thread_fun, this)));
|
m_thread.reset(new libtorrent::thread(boost::bind(&dht_server::thread_fun, this)));
|
||||||
}
|
}
|
||||||
|
|
||||||
~dht_server()
|
~dht_server()
|
||||||
|
|
|
@ -92,7 +92,7 @@ struct peer_server
|
||||||
|
|
||||||
fprintf(stderr, "%s: PEER peer initialized on port %d\n", time_now_string(), m_port);
|
fprintf(stderr, "%s: PEER peer initialized on port %d\n", time_now_string(), m_port);
|
||||||
|
|
||||||
m_thread.reset(new thread(boost::bind(&peer_server::thread_fun, this)));
|
m_thread.reset(new libtorrent::thread(boost::bind(&peer_server::thread_fun, this)));
|
||||||
}
|
}
|
||||||
|
|
||||||
~peer_server()
|
~peer_server()
|
||||||
|
|
|
@ -258,7 +258,7 @@ TORRENT_TEST(wait_for_alert)
|
||||||
mgr.get_all(alerts);
|
mgr.get_all(alerts);
|
||||||
|
|
||||||
start = clock_type::now();
|
start = clock_type::now();
|
||||||
thread posting_thread(boost::bind(&post_torrent_added, &mgr));
|
libtorrent::thread posting_thread(boost::bind(&post_torrent_added, &mgr));
|
||||||
|
|
||||||
a = mgr.wait_for_alert(seconds(10));
|
a = mgr.wait_for_alert(seconds(10));
|
||||||
end = clock_type::now();
|
end = clock_type::now();
|
||||||
|
|
|
@ -77,11 +77,11 @@ TORRENT_TEST(threads)
|
||||||
{
|
{
|
||||||
condition_variable cond;
|
condition_variable cond;
|
||||||
libtorrent::mutex m;
|
libtorrent::mutex m;
|
||||||
std::list<thread*> threads;
|
std::list<libtorrent::thread*> threads;
|
||||||
int waiting = 0;
|
int waiting = 0;
|
||||||
for (int i = 0; i < 20; ++i)
|
for (int i = 0; i < 20; ++i)
|
||||||
{
|
{
|
||||||
threads.push_back(new thread(boost::bind(&fun, &cond, &m, &waiting, i)));
|
threads.push_back(new libtorrent::thread(boost::bind(&fun, &cond, &m, &waiting, i)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure all threads are waiting on the condition_variable
|
// make sure all threads are waiting on the condition_variable
|
||||||
|
@ -96,7 +96,7 @@ TORRENT_TEST(threads)
|
||||||
cond.notify_all();
|
cond.notify_all();
|
||||||
l.unlock();
|
l.unlock();
|
||||||
|
|
||||||
for (std::list<thread*>::iterator i = threads.begin(); i != threads.end(); ++i)
|
for (std::list<libtorrent::thread*>::iterator i = threads.begin(); i != threads.end(); ++i)
|
||||||
{
|
{
|
||||||
(*i)->join();
|
(*i)->join();
|
||||||
delete *i;
|
delete *i;
|
||||||
|
@ -107,8 +107,8 @@ TORRENT_TEST(threads)
|
||||||
boost::atomic<int> c(0);
|
boost::atomic<int> c(0);
|
||||||
for (int i = 0; i < 3; ++i)
|
for (int i = 0; i < 3; ++i)
|
||||||
{
|
{
|
||||||
threads.push_back(new thread(boost::bind(&increment, &cond, &m, &waiting, &c)));
|
threads.push_back(new libtorrent::thread(boost::bind(&increment, &cond, &m, &waiting, &c)));
|
||||||
threads.push_back(new thread(boost::bind(&decrement, &cond, &m, &waiting, &c)));
|
threads.push_back(new libtorrent::thread(boost::bind(&decrement, &cond, &m, &waiting, &c)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure all threads are waiting on the condition_variable
|
// make sure all threads are waiting on the condition_variable
|
||||||
|
@ -123,7 +123,7 @@ TORRENT_TEST(threads)
|
||||||
cond.notify_all();
|
cond.notify_all();
|
||||||
l.unlock();
|
l.unlock();
|
||||||
|
|
||||||
for (std::list<thread*>::iterator i = threads.begin(); i != threads.end(); ++i)
|
for (std::list<libtorrent::thread*>::iterator i = threads.begin(); i != threads.end(); ++i)
|
||||||
{
|
{
|
||||||
(*i)->join();
|
(*i)->join();
|
||||||
delete *i;
|
delete *i;
|
||||||
|
|
|
@ -83,10 +83,10 @@ TORRENT_TEST(time)
|
||||||
|
|
||||||
mutex m;
|
mutex m;
|
||||||
condition_variable cv;
|
condition_variable cv;
|
||||||
thread t1(boost::bind(&check_timer_loop, boost::ref(m), boost::ref(last), boost::ref(cv)));
|
libtorrent::thread t1(boost::bind(&check_timer_loop, boost::ref(m), boost::ref(last), boost::ref(cv)));
|
||||||
thread t2(boost::bind(&check_timer_loop, boost::ref(m), boost::ref(last), boost::ref(cv)));
|
libtorrent::thread t2(boost::bind(&check_timer_loop, boost::ref(m), boost::ref(last), boost::ref(cv)));
|
||||||
thread t3(boost::bind(&check_timer_loop, boost::ref(m), boost::ref(last), boost::ref(cv)));
|
libtorrent::thread t3(boost::bind(&check_timer_loop, boost::ref(m), boost::ref(last), boost::ref(cv)));
|
||||||
thread t4(boost::bind(&check_timer_loop, boost::ref(m), boost::ref(last), boost::ref(cv)));
|
libtorrent::thread t4(boost::bind(&check_timer_loop, boost::ref(m), boost::ref(last), boost::ref(cv)));
|
||||||
|
|
||||||
test_sleep(100);
|
test_sleep(100);
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ void test_running_torrent(boost::shared_ptr<torrent_info> info, boost::int64_t f
|
||||||
// test_sleep(500);
|
// test_sleep(500);
|
||||||
torrent_status st = h.status();
|
torrent_status st = h.status();
|
||||||
|
|
||||||
TEST_EQUAL(st.total_wanted, file_size * 3);
|
TEST_EQUAL(st.total_wanted, file_size); // we want the single file
|
||||||
TEST_EQUAL(st.total_wanted_done, 0);
|
TEST_EQUAL(st.total_wanted_done, 0);
|
||||||
|
|
||||||
std::vector<int> prio(info->num_files(), 1);
|
std::vector<int> prio(info->num_files(), 1);
|
||||||
|
@ -90,7 +90,7 @@ void test_running_torrent(boost::shared_ptr<torrent_info> info, boost::int64_t f
|
||||||
h.prioritize_files(prio);
|
h.prioritize_files(prio);
|
||||||
st = h.status();
|
st = h.status();
|
||||||
|
|
||||||
TEST_EQUAL(st.total_wanted, file_size * 2);
|
TEST_EQUAL(st.total_wanted, 0); // we don't want anything
|
||||||
TEST_EQUAL(st.total_wanted_done, 0);
|
TEST_EQUAL(st.total_wanted_done, 0);
|
||||||
TEST_EQUAL(int(h.file_priorities().size()), info->num_files());
|
TEST_EQUAL(int(h.file_priorities().size()), info->num_files());
|
||||||
if (!st.is_seeding)
|
if (!st.is_seeding)
|
||||||
|
@ -129,13 +129,12 @@ void test_running_torrent(boost::shared_ptr<torrent_info> info, boost::int64_t f
|
||||||
std::vector<char> piece(info->piece_length());
|
std::vector<char> piece(info->piece_length());
|
||||||
for (int i = 0; i < int(piece.size()); ++i)
|
for (int i = 0; i < int(piece.size()); ++i)
|
||||||
piece[i] = (i % 26) + 'A';
|
piece[i] = (i % 26) + 'A';
|
||||||
h.add_piece(0, &piece[0]);
|
h.add_piece(0, &piece[0], torrent_handle::overwrite_existing);
|
||||||
|
|
||||||
// wait until the piece is done writing and hashing
|
// wait until the piece is done writing and hashing
|
||||||
// TODO: wait for an alert rather than just waiting 10 seconds. This is kind of silly
|
wait_for_alert(ses, piece_finished_alert::alert_type, "piece_finished_alert");
|
||||||
test_sleep(2000);
|
|
||||||
st = h.status();
|
st = h.status();
|
||||||
TEST_CHECK(st.pieces.size() > 0 && st.pieces[0] == true);
|
TEST_CHECK(st.pieces.size() > 0);
|
||||||
|
|
||||||
std::cout << "reading piece 0" << std::endl;
|
std::cout << "reading piece 0" << std::endl;
|
||||||
h.read_piece(0);
|
h.read_piece(0);
|
||||||
|
@ -146,7 +145,7 @@ void test_running_torrent(boost::shared_ptr<torrent_info> info, boost::int64_t f
|
||||||
if (rpa)
|
if (rpa)
|
||||||
{
|
{
|
||||||
std::cout << "SUCCEEDED!" << std::endl;
|
std::cout << "SUCCEEDED!" << std::endl;
|
||||||
TEST_CHECK(memcmp(&piece[0], rpa->buffer.get(), piece.size()) == 0);
|
TEST_CHECK(memcmp(&piece[0], rpa->buffer.get(), info->piece_size(0)) == 0);
|
||||||
TEST_CHECK(rpa->size == info->piece_size(0));
|
TEST_CHECK(rpa->size == info->piece_size(0));
|
||||||
TEST_CHECK(rpa->piece == 0);
|
TEST_CHECK(rpa->piece == 0);
|
||||||
TEST_CHECK(hasher(&piece[0], int(piece.size())).final() == info->hash_for_piece(0));
|
TEST_CHECK(hasher(&piece[0], int(piece.size())).final() == info->hash_for_piece(0));
|
||||||
|
@ -251,27 +250,50 @@ TORRENT_TEST(torrent)
|
||||||
{
|
{
|
||||||
file_storage fs;
|
file_storage fs;
|
||||||
|
|
||||||
fs.add_file("test_torrent_dir2/tmp1", 0);
|
fs.add_file("test_torrent_dir2/tmp1", 1024);
|
||||||
libtorrent::create_torrent t(fs, 128 * 1024, 6);
|
libtorrent::create_torrent t(fs, 128 * 1024, 6);
|
||||||
|
|
||||||
|
std::vector<char> piece(128 * 1024);
|
||||||
|
for (int i = 0; i < int(piece.size()); ++i)
|
||||||
|
piece[i] = (i % 26) + 'A';
|
||||||
|
|
||||||
|
// calculate the hash for all pieces
|
||||||
|
sha1_hash ph = hasher(&piece[0], piece.size()).final();
|
||||||
|
int num = t.num_pieces();
|
||||||
|
TEST_CHECK(t.num_pieces() > 0);
|
||||||
|
for (int i = 0; i < num; ++i)
|
||||||
|
t.set_hash(i, ph);
|
||||||
|
|
||||||
std::vector<char> tmp;
|
std::vector<char> tmp;
|
||||||
std::back_insert_iterator<std::vector<char> > out(tmp);
|
std::back_insert_iterator<std::vector<char> > out(tmp);
|
||||||
bencode(out, t.generate());
|
bencode(out, t.generate());
|
||||||
error_code ec;
|
error_code ec;
|
||||||
boost::shared_ptr<torrent_info> info(boost::make_shared<torrent_info>(&tmp[0], tmp.size(), boost::ref(ec), 0));
|
boost::shared_ptr<torrent_info> info(boost::make_shared<torrent_info>(&tmp[0], tmp.size(), boost::ref(ec), 0));
|
||||||
test_running_torrent(info, 0);
|
test_running_torrent(info, 1024);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TORRENT_TEST(torrent_total_size_zero)
|
TORRENT_TEST(torrent_total_size_zero)
|
||||||
{
|
{
|
||||||
file_storage fs;
|
file_storage fs;
|
||||||
|
error_code ec;
|
||||||
|
|
||||||
fs.add_file("test_torrent_dir2/tmp1", 0);
|
fs.add_file("test_torrent_dir2/tmp1", 0);
|
||||||
libtorrent::create_torrent t(fs);
|
TEST_CHECK(fs.num_files() == 1);
|
||||||
|
TEST_CHECK(fs.total_size() == 0);
|
||||||
|
|
||||||
error_code ec;
|
ec.clear();
|
||||||
set_piece_hashes(t, ".", ec);
|
libtorrent::create_torrent t1(fs);
|
||||||
|
set_piece_hashes(t1, ".", ec);
|
||||||
|
TEST_CHECK(ec);
|
||||||
|
|
||||||
|
fs.add_file("test_torrent_dir2/tmp2", 0);
|
||||||
|
TEST_CHECK(fs.num_files() == 2);
|
||||||
|
TEST_CHECK(fs.total_size() == 0);
|
||||||
|
|
||||||
|
ec.clear();
|
||||||
|
libtorrent::create_torrent t2(fs);
|
||||||
|
set_piece_hashes(t2, ".", ec);
|
||||||
TEST_CHECK(ec);
|
TEST_CHECK(ec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@ struct udp_tracker
|
||||||
boost::detail::atomic_count m_udp_announces;
|
boost::detail::atomic_count m_udp_announces;
|
||||||
udp::socket m_socket;
|
udp::socket m_socket;
|
||||||
int m_port;
|
int m_port;
|
||||||
|
bool m_abort;
|
||||||
|
|
||||||
boost::shared_ptr<libtorrent::thread> m_thread;
|
boost::shared_ptr<libtorrent::thread> m_thread;
|
||||||
|
|
||||||
|
@ -77,12 +78,17 @@ struct udp_tracker
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_abort)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fprintf(stderr, "%s: UDP message %d bytes\n", time_now_string(), int(bytes_transferred));
|
fprintf(stderr, "%s: UDP message %d bytes\n", time_now_string(), int(bytes_transferred));
|
||||||
|
|
||||||
char* ptr = buffer;
|
char* ptr = buffer;
|
||||||
detail::read_uint64(ptr);
|
detail::read_uint64(ptr);
|
||||||
boost::uint32_t action = detail::read_uint32(ptr);
|
boost::uint32_t const action = detail::read_uint32(ptr);
|
||||||
boost::uint32_t transaction_id = detail::read_uint32(ptr);
|
boost::uint32_t const transaction_id = detail::read_uint32(ptr);
|
||||||
|
|
||||||
error_code e;
|
error_code e;
|
||||||
|
|
||||||
|
@ -140,6 +146,7 @@ struct udp_tracker
|
||||||
: m_udp_announces(0)
|
: m_udp_announces(0)
|
||||||
, m_socket(m_ios)
|
, m_socket(m_ios)
|
||||||
, m_port(0)
|
, m_port(0)
|
||||||
|
, m_abort(false)
|
||||||
{
|
{
|
||||||
error_code ec;
|
error_code ec;
|
||||||
m_socket.open(udp::v4(), ec);
|
m_socket.open(udp::v4(), ec);
|
||||||
|
@ -164,13 +171,19 @@ struct udp_tracker
|
||||||
|
|
||||||
fprintf(stderr, "%s: UDP tracker initialized on port %d\n", time_now_string(), m_port);
|
fprintf(stderr, "%s: UDP tracker initialized on port %d\n", time_now_string(), m_port);
|
||||||
|
|
||||||
m_thread.reset(new thread(boost::bind(&udp_tracker::thread_fun, this)));
|
m_thread.reset(new libtorrent::thread(boost::bind(&udp_tracker::thread_fun, this)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void stop()
|
||||||
|
{
|
||||||
|
m_abort = true;
|
||||||
|
m_socket.cancel();
|
||||||
|
m_socket.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
~udp_tracker()
|
~udp_tracker()
|
||||||
{
|
{
|
||||||
m_socket.cancel();
|
m_ios.post(boost::bind(&udp_tracker::stop, this));
|
||||||
m_socket.close();
|
|
||||||
if (m_thread) m_thread->join();
|
if (m_thread) m_thread->join();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue