From e05f396a5db237b79644c7b4b8b0c744caf218b1 Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Mon, 7 Jan 2008 05:48:28 +0000 Subject: [PATCH] made UPnP ignore devices that don't respond from a router IP (optional but on by default) --- docs/manual.html | 5 +++++ docs/manual.rst | 6 +++++ include/libtorrent/session_settings.hpp | 6 +++++ include/libtorrent/upnp.hpp | 4 +++- src/session_impl.cpp | 3 ++- src/upnp.cpp | 30 ++++++++++++++++++++++++- test/test_upnp.cpp | 2 +- 7 files changed, 52 insertions(+), 4 deletions(-) diff --git a/docs/manual.html b/docs/manual.html index 50dcd0a06..ccaf1f8bf 100644 --- a/docs/manual.html +++ b/docs/manual.html @@ -2458,6 +2458,7 @@ struct session_settings int inactivity_timeout; bool use_dht_as_fallback; bool free_torrent_hashes; + bool upnp_ignore_nonrouters; };

user_agent this is the client identification to the tracker. @@ -2565,6 +2566,10 @@ needed anymore since the torrent won't download anything more). If it's set to false they are not freed. If they are freed, the torrent_info returned by get_torrent_info() will return an object that may be incomplete, that cannot be passed back to add_torrent() for instance.

+

upnp_ignore_nonrouters indicates whether or not the UPnP implementation +should ignore any broadcast response from a device whose address is not the +configured router for this machine. i.e. it's a way to not talk to other +people's routers by mistake.

pe_settings

diff --git a/docs/manual.rst b/docs/manual.rst index 001f9fd5f..d3b60188b 100644 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -2446,6 +2446,7 @@ that will be sent to the tracker. The user-agent is a good way to identify your int inactivity_timeout; bool use_dht_as_fallback; bool free_torrent_hashes; + bool upnp_ignore_nonrouters; }; ``user_agent`` this is the client identification to the tracker. @@ -2578,6 +2579,11 @@ to false they are not freed. If they are freed, the torrent_info_ returned by get_torrent_info() will return an object that may be incomplete, that cannot be passed back to `add_torrent()`_ for instance. +``upnp_ignore_nonrouters`` indicates whether or not the UPnP implementation +should ignore any broadcast response from a device whose address is not the +configured router for this machine. i.e. it's a way to not talk to other +people's routers by mistake. + pe_settings =========== diff --git a/include/libtorrent/session_settings.hpp b/include/libtorrent/session_settings.hpp index 7cc7d26da..2817d27d2 100644 --- a/include/libtorrent/session_settings.hpp +++ b/include/libtorrent/session_settings.hpp @@ -117,6 +117,7 @@ namespace libtorrent , use_dht_as_fallback(true) #endif , free_torrent_hashes(true) + , upnp_ignore_nonrouters(true) {} // this is the user agent that will be sent to the tracker @@ -292,6 +293,11 @@ namespace libtorrent // make the get_torrent_info() function to return an incomplete // torrent object that cannot be passed back to add_torrent() bool free_torrent_hashes; + + // when this is true, the upnp port mapper will ignore + // any upnp devices that don't have an address that matches + // our currently configured router. + bool upnp_ignore_nonrouters; }; #ifndef TORRENT_DISABLE_DHT diff --git a/include/libtorrent/upnp.hpp b/include/libtorrent/upnp.hpp index 442d7aa4a..5f35616ca 100644 --- a/include/libtorrent/upnp.hpp +++ b/include/libtorrent/upnp.hpp @@ -68,7 +68,7 @@ class upnp : public intrusive_ptr_base public: upnp(io_service& ios, connection_queue& cc , address const& listen_interface, std::string const& user_agent - , portmap_callback_t const& cb); + , portmap_callback_t const& cb, bool ignore_nonrouters); ~upnp(); // maps the ports, if a port is set to 0 @@ -242,6 +242,8 @@ private: std::string m_model; + std::vector
m_filter; + #ifdef TORRENT_UPNP_LOGGING std::ofstream m_log; #endif diff --git a/src/session_impl.cpp b/src/session_impl.cpp index 6f0013c63..e2d4b8ef4 100755 --- a/src/session_impl.cpp +++ b/src/session_impl.cpp @@ -2339,7 +2339,8 @@ namespace detail , m_listen_interface.address() , m_settings.user_agent , bind(&session_impl::on_port_mapping - , this, _1, _2, _3)); + , this, _1, _2, _3) + , m_settings.upnp_ignore_nonrouters); m_upnp->discover_device(); m_upnp->set_mappings(m_listen_interface.port(), diff --git a/src/upnp.cpp b/src/upnp.cpp index 064b6550d..23a8d01a6 100644 --- a/src/upnp.cpp +++ b/src/upnp.cpp @@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/http_tracker_connection.hpp" #include "libtorrent/xml_parse.hpp" #include "libtorrent/connection_queue.hpp" +#include "libtorrent/enum_net.hpp" #include #include @@ -61,7 +62,7 @@ namespace libtorrent upnp::upnp(io_service& ios, connection_queue& cc , address const& listen_interface, std::string const& user_agent - , portmap_callback_t const& cb) + , portmap_callback_t const& cb, bool ignore_nonrouters) : m_udp_local_port(0) , m_tcp_local_port(0) , m_user_agent(user_agent) @@ -81,6 +82,21 @@ upnp::upnp(io_service& ios, connection_queue& cc m_log.open("upnp.log", std::ios::in | std::ios::out | std::ios::trunc); #endif m_retry_count = 0; + + if (ignore_nonrouters) + { + asio::error_code ec; + std::vector
const& net = enum_net_interfaces(m_io_service, ec); + m_filter.reserve(net.size()); + for (std::vector
::const_iterator i = net.begin() + , end(net.end()); i != end; ++i) + { + asio::error_code e; + address a = router_for_interface(*i, e); + if (e || is_loopback(a)) continue; + m_filter.push_back(a); + } + } } upnp::~upnp() @@ -249,6 +265,18 @@ void upnp::on_reply(udp::endpoint const& from, char* buffer Server:Microsoft-Windows-NT/5.1 UPnP/1.0 UPnP-Device-Host/1.0 */ + if (!m_filter.empty() && std::find(m_filter.begin(), m_filter.end() + , from.address()) == m_filter.end()) + { + // this upnp device is filtered because it's not in the + // list of configured routers +#ifdef TORRENT_UPNP_LOGGING + m_log << time_now_string() << " <== (" << from << ") Rootdevice " + "ignored because it's not out router" << std::endl; +#endif + return; + } + http_parser p; bool error = false; p.incoming(buffer::const_interval(buffer diff --git a/test/test_upnp.cpp b/test/test_upnp.cpp index 78828491c..f8f7e4b86 100644 --- a/test/test_upnp.cpp +++ b/test/test_upnp.cpp @@ -24,7 +24,7 @@ int main(int argc, char* argv[]) } connection_queue cc(ios); - boost::intrusive_ptr upnp_handler = new upnp(ios, cc, address_v4(), user_agent, &callback); + boost::intrusive_ptr upnp_handler = new upnp(ios, cc, address_v4(), user_agent, &callback, true); upnp_handler->discover_device(); deadline_timer timer(ios);