forked from premiere/premiere-libtorrent
first stab at getting local service discovery
This commit is contained in:
parent
2555daa95f
commit
5e32484194
1
Jamfile
1
Jamfile
|
@ -62,6 +62,7 @@ SOURCES =
|
||||||
ut_pex.cpp
|
ut_pex.cpp
|
||||||
logger.cpp
|
logger.cpp
|
||||||
file_pool.cpp
|
file_pool.cpp
|
||||||
|
lsd.cpp
|
||||||
;
|
;
|
||||||
|
|
||||||
KADEMLIA_SOURCES =
|
KADEMLIA_SOURCES =
|
||||||
|
|
|
@ -19,6 +19,7 @@ libtorrent/identify_client.hpp \
|
||||||
libtorrent/invariant_check.hpp \
|
libtorrent/invariant_check.hpp \
|
||||||
libtorrent/io.hpp \
|
libtorrent/io.hpp \
|
||||||
libtorrent/ip_filter.hpp \
|
libtorrent/ip_filter.hpp \
|
||||||
|
libtorrent/lsd.hpp \
|
||||||
libtorrent/peer.hpp \
|
libtorrent/peer.hpp \
|
||||||
libtorrent/peer_connection.hpp \
|
libtorrent/peer_connection.hpp \
|
||||||
libtorrent/bt_peer_connection.hpp \
|
libtorrent/bt_peer_connection.hpp \
|
||||||
|
|
|
@ -79,6 +79,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/bandwidth_manager.hpp"
|
#include "libtorrent/bandwidth_manager.hpp"
|
||||||
#include "libtorrent/natpmp.hpp"
|
#include "libtorrent/natpmp.hpp"
|
||||||
#include "libtorrent/upnp.hpp"
|
#include "libtorrent/upnp.hpp"
|
||||||
|
#include "libtorrent/lsd.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
@ -280,12 +281,15 @@ namespace libtorrent
|
||||||
|
|
||||||
torrent_handle find_torrent_handle(sha1_hash const& info_hash);
|
torrent_handle find_torrent_handle(sha1_hash const& info_hash);
|
||||||
|
|
||||||
|
void announce_lsd(sha1_hash const& ih);
|
||||||
|
|
||||||
// handles delayed alerts
|
// handles delayed alerts
|
||||||
alert_manager m_alerts;
|
alert_manager m_alerts;
|
||||||
|
|
||||||
// private:
|
// private:
|
||||||
|
|
||||||
|
void on_lsd_peer(tcp::endpoint peer, sha1_hash const& ih);
|
||||||
|
|
||||||
// this is where all active sockets are stored.
|
// this is where all active sockets are stored.
|
||||||
// the selector can sleep while there's no activity on
|
// the selector can sleep while there's no activity on
|
||||||
// them
|
// them
|
||||||
|
@ -395,6 +399,7 @@ namespace libtorrent
|
||||||
#endif
|
#endif
|
||||||
natpmp m_natpmp;
|
natpmp m_natpmp;
|
||||||
upnp m_upnp;
|
upnp m_upnp;
|
||||||
|
lsd m_lsd;
|
||||||
|
|
||||||
// the timer used to fire the second_tick
|
// the timer used to fire the second_tick
|
||||||
deadline_timer m_timer;
|
deadline_timer m_timer;
|
||||||
|
|
|
@ -575,11 +575,17 @@ namespace libtorrent
|
||||||
// country resolution in this torrent
|
// country resolution in this torrent
|
||||||
bool m_resolve_countries;
|
bool m_resolve_countries;
|
||||||
|
|
||||||
|
// this announce timer is used both
|
||||||
|
// by Local service discovery and
|
||||||
|
// by the DHT.
|
||||||
|
deadline_timer m_announce_timer;
|
||||||
|
|
||||||
|
// this is called once per announce interval
|
||||||
|
void on_announce(asio::error_code const& e);
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
static void on_dht_announce_response_disp(boost::weak_ptr<torrent> t
|
static void on_dht_announce_response_disp(boost::weak_ptr<torrent> t
|
||||||
, std::vector<tcp::endpoint> const& peers);
|
, std::vector<tcp::endpoint> const& peers);
|
||||||
deadline_timer m_dht_announce_timer;
|
|
||||||
void on_dht_announce(asio::error_code const& e);
|
|
||||||
void on_dht_announce_response(std::vector<tcp::endpoint> const& peers);
|
void on_dht_announce_response(std::vector<tcp::endpoint> const& peers);
|
||||||
bool should_announce_dht() const;
|
bool should_announce_dht() const;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,7 +8,7 @@ stat.cpp storage.cpp torrent.cpp torrent_handle.cpp \
|
||||||
torrent_info.cpp tracker_manager.cpp http_connection.cpp \
|
torrent_info.cpp tracker_manager.cpp http_connection.cpp \
|
||||||
http_tracker_connection.cpp udp_tracker_connection.cpp \
|
http_tracker_connection.cpp udp_tracker_connection.cpp \
|
||||||
alert.cpp identify_client.cpp ip_filter.cpp file.cpp metadata_transfer.cpp \
|
alert.cpp identify_client.cpp ip_filter.cpp file.cpp metadata_transfer.cpp \
|
||||||
logger.cpp file_pool.cpp ut_pex.cpp \
|
logger.cpp file_pool.cpp ut_pex.cpp lsd.cpp \
|
||||||
\
|
\
|
||||||
kademlia/closest_nodes.cpp \
|
kademlia/closest_nodes.cpp \
|
||||||
kademlia/dht_tracker.cpp \
|
kademlia/dht_tracker.cpp \
|
||||||
|
@ -47,6 +47,7 @@ $(top_srcdir)/include/libtorrent/identify_client.hpp \
|
||||||
$(top_srcdir)/include/libtorrent/invariant_check.hpp \
|
$(top_srcdir)/include/libtorrent/invariant_check.hpp \
|
||||||
$(top_srcdir)/include/libtorrent/io.hpp \
|
$(top_srcdir)/include/libtorrent/io.hpp \
|
||||||
$(top_srcdir)/include/libtorrent/ip_filter.hpp \
|
$(top_srcdir)/include/libtorrent/ip_filter.hpp \
|
||||||
|
$(top_srcdir)/include/libtorrent/lsd.hpp \
|
||||||
$(top_srcdir)/include/libtorrent/peer.hpp \
|
$(top_srcdir)/include/libtorrent/peer.hpp \
|
||||||
$(top_srcdir)/include/libtorrent/peer_connection.hpp \
|
$(top_srcdir)/include/libtorrent/peer_connection.hpp \
|
||||||
$(top_srcdir)/include/libtorrent/bt_peer_connection.hpp \
|
$(top_srcdir)/include/libtorrent/bt_peer_connection.hpp \
|
||||||
|
|
|
@ -499,6 +499,8 @@ namespace libtorrent { namespace detail
|
||||||
, m_upnp(m_io_service, m_listen_interface.address()
|
, m_upnp(m_io_service, m_listen_interface.address()
|
||||||
, m_settings.user_agent
|
, m_settings.user_agent
|
||||||
, bind(&session_impl::on_port_mapping, this, _1, _2, _3))
|
, bind(&session_impl::on_port_mapping, this, _1, _2, _3))
|
||||||
|
, m_lsd(m_io_service, m_listen_interface.address()
|
||||||
|
, bind(&session_impl::on_lsd_peer, this, _1, _2))
|
||||||
, m_timer(m_io_service)
|
, m_timer(m_io_service)
|
||||||
, m_checker_impl(*this)
|
, m_checker_impl(*this)
|
||||||
{
|
{
|
||||||
|
@ -1460,14 +1462,13 @@ namespace libtorrent { namespace detail
|
||||||
if (m_listen_socket)
|
if (m_listen_socket)
|
||||||
m_listen_socket.reset();
|
m_listen_socket.reset();
|
||||||
|
|
||||||
bool new_listen_address = m_listen_interface.address() != new_interface.address();
|
|
||||||
|
|
||||||
m_incoming_connection = false;
|
m_incoming_connection = false;
|
||||||
m_listen_interface = new_interface;
|
m_listen_interface = new_interface;
|
||||||
|
|
||||||
open_listen_port();
|
open_listen_port();
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
|
bool new_listen_address = m_listen_interface.address() != new_interface.address();
|
||||||
if ((new_listen_address || m_dht_same_port) && m_dht)
|
if ((new_listen_address || m_dht_same_port) && m_dht)
|
||||||
{
|
{
|
||||||
if (m_dht_same_port)
|
if (m_dht_same_port)
|
||||||
|
@ -1479,6 +1480,7 @@ namespace libtorrent { namespace detail
|
||||||
{
|
{
|
||||||
m_natpmp.rebind(new_interface.address());
|
m_natpmp.rebind(new_interface.address());
|
||||||
m_upnp.rebind(new_interface.address());
|
m_upnp.rebind(new_interface.address());
|
||||||
|
m_lsd.rebind(new_interface.address());
|
||||||
}
|
}
|
||||||
m_natpmp.set_mappings(0, m_dht_settings.service_port);
|
m_natpmp.set_mappings(0, m_dht_settings.service_port);
|
||||||
m_upnp.set_mappings(0, m_dht_settings.service_port);
|
m_upnp.set_mappings(0, m_dht_settings.service_port);
|
||||||
|
@ -1501,6 +1503,26 @@ namespace libtorrent { namespace detail
|
||||||
return m_external_listen_port;
|
return m_external_listen_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void session_impl::announce_lsd(sha1_hash const& ih)
|
||||||
|
{
|
||||||
|
mutex_t::scoped_lock l(m_mutex);
|
||||||
|
m_lsd.announce(ih, m_external_listen_port);
|
||||||
|
}
|
||||||
|
|
||||||
|
void session_impl::on_lsd_peer(tcp::endpoint peer, sha1_hash const& ih)
|
||||||
|
{
|
||||||
|
mutex_t::scoped_lock l(m_mutex);
|
||||||
|
|
||||||
|
boost::shared_ptr<torrent> t = find_torrent(ih).lock();
|
||||||
|
if (!t) return;
|
||||||
|
|
||||||
|
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
|
||||||
|
(*m_logger) << to_simple_string(second_clock::universal_time())
|
||||||
|
<< ": added peer from local discovery: " << peer << "\n";
|
||||||
|
#endif
|
||||||
|
t->get_policy().peer_from_tracker(peer, peer_id(0));
|
||||||
|
}
|
||||||
|
|
||||||
void session_impl::on_port_mapping(int tcp_port, int udp_port
|
void session_impl::on_port_mapping(int tcp_port, int udp_port
|
||||||
, std::string const& errmsg)
|
, std::string const& errmsg)
|
||||||
{
|
{
|
||||||
|
|
|
@ -245,9 +245,7 @@ namespace libtorrent
|
||||||
, m_host_resolver(ses.m_io_service)
|
, m_host_resolver(ses.m_io_service)
|
||||||
, m_resolving_country(false)
|
, m_resolving_country(false)
|
||||||
, m_resolve_countries(false)
|
, m_resolve_countries(false)
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
, m_announce_timer(ses.m_io_service)
|
||||||
, m_dht_announce_timer(ses.m_io_service)
|
|
||||||
#endif
|
|
||||||
, m_policy()
|
, m_policy()
|
||||||
, m_ses(ses)
|
, m_ses(ses)
|
||||||
, m_checker(checker)
|
, m_checker(checker)
|
||||||
|
@ -301,14 +299,9 @@ namespace libtorrent
|
||||||
m_policy.reset(new policy(this));
|
m_policy.reset(new policy(this));
|
||||||
init();
|
init();
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
m_announce_timer.expires_from_now(seconds(1));
|
||||||
if (should_announce_dht())
|
m_announce_timer.async_wait(m_ses.m_strand.wrap(
|
||||||
{
|
bind(&torrent::on_announce, this, _1)));
|
||||||
m_dht_announce_timer.expires_from_now(seconds(10));
|
|
||||||
m_dht_announce_timer.async_wait(m_ses.m_strand.wrap(
|
|
||||||
bind(&torrent::on_dht_announce, this, _1)));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
torrent::torrent(
|
torrent::torrent(
|
||||||
|
@ -337,9 +330,7 @@ namespace libtorrent
|
||||||
, m_host_resolver(ses.m_io_service)
|
, m_host_resolver(ses.m_io_service)
|
||||||
, m_resolving_country(false)
|
, m_resolving_country(false)
|
||||||
, m_resolve_countries(false)
|
, m_resolve_countries(false)
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
, m_announce_timer(ses.m_io_service)
|
||||||
, m_dht_announce_timer(ses.m_io_service)
|
|
||||||
#endif
|
|
||||||
, m_policy()
|
, m_policy()
|
||||||
, m_ses(ses)
|
, m_ses(ses)
|
||||||
, m_checker(checker)
|
, m_checker(checker)
|
||||||
|
@ -395,14 +386,9 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
m_policy.reset(new policy(this));
|
m_policy.reset(new policy(this));
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
m_announce_timer.expires_from_now(seconds(1));
|
||||||
if (should_announce_dht())
|
m_announce_timer.async_wait(m_ses.m_strand.wrap(
|
||||||
{
|
bind(&torrent::on_announce, this, _1)));
|
||||||
m_dht_announce_timer.expires_from_now(seconds(10));
|
|
||||||
m_dht_announce_timer.async_wait(m_ses.m_strand.wrap(
|
|
||||||
bind(&torrent::on_dht_announce, this, _1)));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
|
@ -480,6 +466,32 @@ namespace libtorrent
|
||||||
m_net_interface = tcp::endpoint(address::from_string(net_interface), 0);
|
m_net_interface = tcp::endpoint(address::from_string(net_interface), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void torrent::on_announce(asio::error_code const& e)
|
||||||
|
{
|
||||||
|
if (e) return;
|
||||||
|
|
||||||
|
m_announce_timer.expires_from_now(boost::posix_time::minutes(30));
|
||||||
|
m_announce_timer.async_wait(m_ses.m_strand.wrap(
|
||||||
|
bind(&torrent::on_announce, this, _1)));
|
||||||
|
|
||||||
|
// announce with the local discovery service
|
||||||
|
m_ses.announce_lsd(m_torrent_file.info_hash());
|
||||||
|
|
||||||
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
|
if (!m_ses.m_dht) return;
|
||||||
|
if (should_announce_dht())
|
||||||
|
{
|
||||||
|
// TODO: There should be a way to abort an announce operation on the dht.
|
||||||
|
// when the torrent is destructed
|
||||||
|
boost::weak_ptr<torrent> self(shared_from_this());
|
||||||
|
assert(m_ses.m_external_listen_port > 0);
|
||||||
|
m_ses.m_dht->announce(m_torrent_file.info_hash()
|
||||||
|
, m_ses.m_external_listen_port
|
||||||
|
, m_ses.m_strand.wrap(bind(&torrent::on_dht_announce_response_disp, self, _1)));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
|
|
||||||
void torrent::on_dht_announce_response_disp(boost::weak_ptr<libtorrent::torrent> t
|
void torrent::on_dht_announce_response_disp(boost::weak_ptr<libtorrent::torrent> t
|
||||||
|
@ -490,25 +502,6 @@ namespace libtorrent
|
||||||
tor->on_dht_announce_response(peers);
|
tor->on_dht_announce_response(peers);
|
||||||
}
|
}
|
||||||
|
|
||||||
void torrent::on_dht_announce(asio::error_code const& e)
|
|
||||||
{
|
|
||||||
if (e) return;
|
|
||||||
if (should_announce_dht())
|
|
||||||
{
|
|
||||||
m_dht_announce_timer.expires_from_now(boost::posix_time::minutes(30));
|
|
||||||
m_dht_announce_timer.async_wait(m_ses.m_strand.wrap(
|
|
||||||
bind(&torrent::on_dht_announce, this, _1)));
|
|
||||||
}
|
|
||||||
if (!m_ses.m_dht) return;
|
|
||||||
// TODO: There should be a way to abort an announce operation on the dht.
|
|
||||||
// when the torrent is destructed
|
|
||||||
boost::weak_ptr<torrent> self(shared_from_this());
|
|
||||||
assert(m_ses.m_external_listen_port > 0);
|
|
||||||
m_ses.m_dht->announce(m_torrent_file.info_hash()
|
|
||||||
, m_ses.m_external_listen_port
|
|
||||||
, m_ses.m_strand.wrap(bind(&torrent::on_dht_announce_response_disp, self, _1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void torrent::on_dht_announce_response(std::vector<tcp::endpoint> const& peers)
|
void torrent::on_dht_announce_response(std::vector<tcp::endpoint> const& peers)
|
||||||
{
|
{
|
||||||
if (peers.empty()) return;
|
if (peers.empty()) return;
|
||||||
|
@ -2170,14 +2163,12 @@ namespace libtorrent
|
||||||
m_next_request = second_clock::universal_time() + seconds(delay);
|
m_next_request = second_clock::universal_time() + seconds(delay);
|
||||||
|
|
||||||
#ifndef TORRENT_DISABLE_DHT
|
#ifndef TORRENT_DISABLE_DHT
|
||||||
// only start the dht announce unless we already are already running
|
// only start the announce if we want to announce with the dht
|
||||||
// the announce timer (a positive expiration time indicates
|
if (should_announce_dht())
|
||||||
// that it's running)
|
|
||||||
if (m_dht_announce_timer.expires_from_now().is_negative() && should_announce_dht())
|
|
||||||
{
|
{
|
||||||
m_dht_announce_timer.expires_from_now(boost::posix_time::seconds(1));
|
m_announce_timer.expires_from_now(boost::posix_time::seconds(1));
|
||||||
m_dht_announce_timer.async_wait(m_ses.m_strand.wrap(
|
m_announce_timer.async_wait(m_ses.m_strand.wrap(
|
||||||
bind(&torrent::on_dht_announce, this, _1)));
|
bind(&torrent::on_announce, this, _1)));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue