summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libtorrent/include/libtorrent/aux_/session_impl.hpp6
-rw-r--r--libtorrent/include/libtorrent/socket.hpp16
-rw-r--r--libtorrent/src/http_connection.cpp1
-rwxr-xr-xlibtorrent/src/session_impl.cpp27
-rwxr-xr-xlibtorrent/src/torrent.cpp3
5 files changed, 50 insertions, 3 deletions
diff --git a/libtorrent/include/libtorrent/aux_/session_impl.hpp b/libtorrent/include/libtorrent/aux_/session_impl.hpp
index 033522bb7..04f575a1a 100644
--- a/libtorrent/include/libtorrent/aux_/session_impl.hpp
+++ b/libtorrent/include/libtorrent/aux_/session_impl.hpp
@@ -53,6 +53,7 @@ POSSIBILITY OF SUCH DAMAGE.
#include <boost/filesystem/path.hpp>
#include <boost/thread.hpp>
#include <boost/thread/recursive_mutex.hpp>
+#include <boost/thread/condition.hpp>
#ifdef _MSC_VER
#pragma warning(pop)
@@ -175,6 +176,7 @@ namespace libtorrent
dht_settings const& get_dht_settings() const { return m_dht_settings; }
void start_dht(entry const& startup_state);
void stop_dht();
+
entry dht_state() const;
#endif
@@ -346,6 +348,8 @@ namespace libtorrent
// private:
+ void dht_state_callback(boost::condition& c
+ , entry& e, bool& done) const;
void on_lsd_peer(tcp::endpoint peer, sha1_hash const& ih);
#ifndef TORRENT_DISABLE_POOL_ALLOCATOR
@@ -366,7 +370,7 @@ namespace libtorrent
// this is where all active sockets are stored.
// the selector can sleep while there's no activity on
// them
- io_service m_io_service;
+ mutable io_service m_io_service;
// handles disk io requests asynchronously
// peers have pointers into the disk buffer
diff --git a/libtorrent/include/libtorrent/socket.hpp b/libtorrent/include/libtorrent/socket.hpp
index d4cc9bdb0..98f5d8151 100644
--- a/libtorrent/include/libtorrent/socket.hpp
+++ b/libtorrent/include/libtorrent/socket.hpp
@@ -213,6 +213,22 @@ namespace libtorrent
int m_value;
};
+#ifdef TORRENT_WINDOWS
+ struct v6_protection_level
+ {
+ v6_protection_level(int level): m_value(level) {}
+ template<class Protocol>
+ int level(Protocol const&) const { return IPPROTO_IPV6; }
+ template<class Protocol>
+ int name(Protocol const&) const { return IPV6_PROTECTION_LEVEL; }
+ template<class Protocol>
+ int const* data(Protocol const&) const { return &m_value; }
+ template<class Protocol>
+ size_t size(Protocol const&) const { return sizeof(m_value); }
+ int m_value;
+ };
+#endif
+
struct type_of_service
{
type_of_service(char val): m_value(val) {}
diff --git a/libtorrent/src/http_connection.cpp b/libtorrent/src/http_connection.cpp
index 8f9104548..4f752ba9f 100644
--- a/libtorrent/src/http_connection.cpp
+++ b/libtorrent/src/http_connection.cpp
@@ -181,6 +181,7 @@ void http_connection::start(std::string const& hostname, std::string const& port
if (m_bind_addr != address_v4::any())
{
error_code ec;
+ m_sock.open(m_bind_addr.is_v4()?tcp::v4():tcp::v6(), ec);
m_sock.bind(tcp::endpoint(m_bind_addr, 0), ec);
if (ec)
{
diff --git a/libtorrent/src/session_impl.cpp b/libtorrent/src/session_impl.cpp
index d1aca0f1e..5596b7fef 100755
--- a/libtorrent/src/session_impl.cpp
+++ b/libtorrent/src/session_impl.cpp
@@ -593,7 +593,14 @@ namespace aux {
s.sock.reset(new socket_acceptor(m_io_service));
s.sock->open(ep.protocol(), ec);
s.sock->set_option(socket_acceptor::reuse_address(true), ec);
- if (ep.protocol() == tcp::v6()) s.sock->set_option(v6only(v6_only), ec);
+ if (ep.protocol() == tcp::v6())
+ {
+ s.sock->set_option(v6only(v6_only), ec);
+#ifdef TORRENT_WINDOWS
+ // enable Teredo on windows
+ s.sock->set_option(v6_protection_level(PROTECTION_LEVEL_UNRESTRICTED), ec);
+#endif
+ }
s.sock->bind(ep, ec);
while (ec && retries > 0)
{
@@ -2150,11 +2157,27 @@ namespace aux {
m_dht_settings.service_port = m_listen_interface.port();
}
+ void session_impl::dht_state_callback(boost::condition& c
+ , entry& e, bool& done) const
+ {
+ mutex_t::scoped_lock l(m_mutex);
+ if (m_dht) e = m_dht->state();
+ done = true;
+ l.unlock();
+ c.notify_all();
+ }
+
entry session_impl::dht_state() const
{
+ boost::condition cond;
mutex_t::scoped_lock l(m_mutex);
if (!m_dht) return entry();
- return m_dht->state();
+ entry e;
+ bool done = false;
+ m_io_service.post(boost::bind(&session_impl::dht_state_callback
+ , this, boost::ref(cond), boost::ref(e), boost::ref(done)));
+ while (!done) cond.wait(l);
+ return e;
}
void session_impl::add_dht_node(std::pair<std::string, int> const& node)
diff --git a/libtorrent/src/torrent.cpp b/libtorrent/src/torrent.cpp
index 0f6ee3f18..383ea5bc7 100755
--- a/libtorrent/src/torrent.cpp
+++ b/libtorrent/src/torrent.cpp
@@ -729,6 +729,7 @@ namespace libtorrent
void torrent::on_piece_checked(int ret, disk_io_job const& j)
{
session_impl::mutex_t::scoped_lock l(m_ses.m_mutex);
+ INVARIANT_CHECK;
if (ret == piece_manager::disk_check_aborted)
{
@@ -3883,9 +3884,11 @@ namespace libtorrent
// if we haven't yet met the seed limits, set the seed_ratio_not_met
// flag. That will make this seed prioritized
+ // downloaded may be 0 if the torrent is 0-sized
size_type downloaded = (std::max)(m_total_downloaded, m_torrent_file->total_size());
if (seed_time < s.seed_time_limit
&& (seed_time > 1 && download_time / float(seed_time) < s.seed_time_ratio_limit)
+ && downloaded > 0
&& m_total_uploaded / downloaded < s.share_ratio_limit)
ret |= seed_ratio_not_met;