diff --git a/AUTHORS b/AUTHORS index 6ce674025..bb244d62c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -10,6 +10,7 @@ Magnus Jonsson Daniel Wallin Cory Nelson Stas Khirman +Ryan Norton Building and maintainance of the autotools scripts: Michael Wojciechowski diff --git a/examples/client_test.cpp b/examples/client_test.cpp index 6c905fe0d..9072eb3d2 100644 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -640,6 +640,12 @@ int main(int ac, char* av[]) // monitor when they're not in the directory anymore. handles_t handles; session ses; + // UPnP port mapping + ses.start_upnp(); + // NAT-PMP port mapping + ses.start_natpmp(); + // Local service discovery (finds peers on the local network) + ses.start_lsd(); ses.add_extension(&create_metadata_plugin); ses.add_extension(&create_ut_pex_plugin); diff --git a/include/libtorrent/aux_/session_impl.hpp b/include/libtorrent/aux_/session_impl.hpp index c878eb95c..6914d1455 100644 --- a/include/libtorrent/aux_/session_impl.hpp +++ b/include/libtorrent/aux_/session_impl.hpp @@ -299,6 +299,14 @@ namespace libtorrent { return m_dht_proxy; } #endif + void start_lsd(); + void start_natpmp(); + void start_upnp(); + + void stop_lsd(); + void stop_natpmp(); + void stop_upnp(); + // handles delayed alerts alert_manager m_alerts; @@ -417,9 +425,9 @@ namespace libtorrent // but for the udp port used by the DHT. int m_external_udp_port; #endif - natpmp m_natpmp; - upnp m_upnp; - lsd m_lsd; + boost::shared_ptr m_natpmp; + boost::shared_ptr m_upnp; + boost::shared_ptr m_lsd; // the timer used to fire the second_tick deadline_timer m_timer; diff --git a/include/libtorrent/session.hpp b/include/libtorrent/session.hpp index 7cd9961bd..0c34f46f8 100755 --- a/include/libtorrent/session.hpp +++ b/include/libtorrent/session.hpp @@ -244,6 +244,16 @@ namespace libtorrent connection_queue& get_connection_queue(); + // starts/stops UPnP, NATPMP or LSD port mappers + // they are stopped by default + void start_lsd(); + void start_natpmp(); + void start_upnp(); + + void stop_lsd(); + void stop_natpmp(); + void stop_upnp(); + // Resource management used for global limits. resource_request m_ul_bandwidth_quota; resource_request m_dl_bandwidth_quota; diff --git a/src/session.cpp b/src/session.cpp index 229f251c6..650654dbf 100755 --- a/src/session.cpp +++ b/src/session.cpp @@ -360,6 +360,36 @@ namespace libtorrent m_impl->set_severity_level(s); } + void session::start_lsd() + { + m_impl->start_lsd(); + } + + void session::start_natpmp() + { + m_impl->start_natpmp(); + } + + void session::start_upnp() + { + m_impl->start_upnp(); + } + + void session::stop_lsd() + { + m_impl->stop_lsd(); + } + + void session::stop_natpmp() + { + m_impl->stop_natpmp(); + } + + void session::stop_upnp() + { + m_impl->stop_upnp(); + } + connection_queue& session::get_connection_queue() { return m_impl->m_half_open; diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 007b83ca8..1e4cc0960 100755 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -494,13 +494,6 @@ namespace libtorrent { namespace detail , m_dht_same_port(true) , m_external_udp_port(0) #endif - , m_natpmp(m_io_service, m_listen_interface.address() - , bind(&session_impl::on_port_mapping, this, _1, _2, _3)) - , m_upnp(m_io_service, m_half_open, m_listen_interface.address() - , m_settings.user_agent - , 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_next_connect_torrent(0) , m_checker_impl(*this) @@ -1081,8 +1074,10 @@ namespace libtorrent { namespace detail { session_impl::mutex_t::scoped_lock l(m_mutex); open_listen_port(); - m_natpmp.set_mappings(m_listen_interface.port(), 0); - m_upnp.set_mappings(m_listen_interface.port(), 0); + if (m_natpmp.get()) + m_natpmp->set_mappings(m_listen_interface.port(), 0); + if (m_upnp.get()) + m_upnp->set_mappings(m_listen_interface.port(), 0); } ptime timer = time_now(); @@ -1107,8 +1102,10 @@ namespace libtorrent { namespace detail deadline_timer tracker_timer(m_io_service); // this will remove the port mappings - m_natpmp.close(); - m_upnp.close(); + if (m_natpmp.get()) + m_natpmp->close(); + if (m_upnp.get()) + m_upnp->close(); #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) (*m_logger) << time_now_string() << " locking mutex\n"; @@ -1518,13 +1515,18 @@ namespace libtorrent { namespace detail if (new_listen_address) { - m_natpmp.rebind(new_interface.address()); - m_upnp.rebind(new_interface.address()); - m_lsd.rebind(new_interface.address()); + if (m_natpmp.get()) + m_natpmp->rebind(new_interface.address()); + if (m_upnp.get()) + m_upnp->rebind(new_interface.address()); + if (m_lsd.get()) + m_lsd->rebind(new_interface.address()); } - m_natpmp.set_mappings(m_listen_interface.port(), 0); - m_upnp.set_mappings(m_listen_interface.port(), 0); + if (m_natpmp.get()) + m_natpmp->set_mappings(m_listen_interface.port(), 0); + if (m_upnp.get()) + m_upnp->set_mappings(m_listen_interface.port(), 0); #ifndef TORRENT_DISABLE_DHT if ((new_listen_address || m_dht_same_port) && m_dht) @@ -1534,8 +1536,10 @@ namespace libtorrent { namespace detail // the listen interface changed, rebind the dht listen socket as well m_dht->rebind(new_interface.address() , 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); + if (m_natpmp.get()) + m_natpmp->set_mappings(0, m_dht_settings.service_port); + if (m_upnp.get()) + m_upnp->set_mappings(0, m_dht_settings.service_port); } #endif @@ -1557,7 +1561,8 @@ namespace libtorrent { namespace detail { mutex_t::scoped_lock l(m_mutex); // use internal listen port for local peers - m_lsd.announce(ih, m_listen_interface.port()); + if (m_lsd.get()) + m_lsd->announce(ih, m_listen_interface.port()); } void session_impl::on_lsd_peer(tcp::endpoint peer, sha1_hash const& ih) @@ -1677,8 +1682,10 @@ namespace libtorrent { namespace detail m_dht_settings.service_port = m_listen_interface.port(); } m_external_udp_port = 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); + if (m_natpmp.get()) + m_natpmp->set_mappings(0, m_dht_settings.service_port); + if (m_upnp.get()) + m_upnp->set_mappings(0, m_dht_settings.service_port); m_dht = new dht::dht_tracker(m_io_service , m_dht_settings, m_listen_interface.address() , startup_state); @@ -1708,8 +1715,10 @@ namespace libtorrent { namespace detail { m_dht->rebind(m_listen_interface.address() , settings.service_port); - m_natpmp.set_mappings(0, m_dht_settings.service_port); - m_upnp.set_mappings(0, m_dht_settings.service_port); + if (m_natpmp.get()) + m_natpmp->set_mappings(0, m_dht_settings.service_port); + if (m_upnp.get()) + m_upnp->set_mappings(0, m_dht_settings.service_port); m_external_udp_port = settings.service_port; } m_dht_settings = settings; @@ -1882,6 +1891,69 @@ namespace libtorrent { namespace detail mutex_t::scoped_lock l(m_mutex); return m_dl_bandwidth_manager.throttle(); } + + + void session_impl::start_lsd() + { + mutex_t::scoped_lock l(m_mutex); + m_lsd.reset(new lsd(m_io_service + , m_listen_interface.address() + , bind(&session_impl::on_lsd_peer, this, _1, _2))); + } + + void session_impl::start_natpmp() + { + mutex_t::scoped_lock l(m_mutex); + m_natpmp.reset(new natpmp(m_io_service + , m_listen_interface.address() + , bind(&session_impl::on_port_mapping + , this, _1, _2, _3))); + + m_natpmp->set_mappings(m_listen_interface.port(), +#ifndef TORRENT_DISABLE_DHT + m_dht ? m_dht_settings.service_port : +#endif + 0); + } + + void session_impl::start_upnp() + { + mutex_t::scoped_lock l(m_mutex); + m_upnp.reset(new upnp(m_io_service, m_half_open + , m_listen_interface.address() + , m_settings.user_agent + , bind(&session_impl::on_port_mapping + , this, _1, _2, _3))); + + m_upnp->set_mappings(m_listen_interface.port(), +#ifndef TORRENT_DISABLE_DHT + m_dht ? m_dht_settings.service_port : +#endif + 0); + } + + void session_impl::stop_lsd() + { + mutex_t::scoped_lock l(m_mutex); + m_lsd.reset(); + } + + void session_impl::stop_natpmp() + { + mutex_t::scoped_lock l(m_mutex); + if (m_natpmp.get()) + m_natpmp->close(); + m_natpmp.reset(); + } + + void session_impl::stop_upnp() + { + mutex_t::scoped_lock l(m_mutex); + if (m_upnp.get()) + m_upnp->close(); + m_upnp.reset(); + } + #ifndef NDEBUG void session_impl::check_invariant(const char *place) diff --git a/src/torrent.cpp b/src/torrent.cpp index 01640afb7..fc1a7c105 100755 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -174,7 +174,9 @@ namespace libtorrent , m_resolve_countries(false) #endif , m_announce_timer(ses.m_io_service) +#ifndef TORRENT_DISABLE_DHT , m_last_dht_announce(time_now() - minutes(15)) +#endif , m_policy() , m_ses(ses) , m_checker(checker) @@ -245,7 +247,9 @@ namespace libtorrent , m_resolve_countries(false) #endif , m_announce_timer(ses.m_io_service) +#ifndef TORRENT_DISABLE_DHT , m_last_dht_announce(time_now() - minutes(15)) +#endif , m_policy() , m_ses(ses) , m_checker(checker)