From dc6564fa1103ab201fa4f0452c0faf43e27fea2e Mon Sep 17 00:00:00 2001 From: Arvid Norberg Date: Wed, 22 Oct 2008 19:40:32 +0000 Subject: [PATCH] applies ip filter to trackers as well --- include/libtorrent/http_connection.hpp | 7 ++-- .../libtorrent/http_tracker_connection.hpp | 7 ++-- include/libtorrent/udp_tracker_connection.hpp | 6 ++-- src/http_connection.cpp | 7 ++++ src/http_tracker_connection.cpp | 33 ++++++++++++++----- src/tracker_manager.cpp | 4 +-- src/udp_tracker_connection.cpp | 24 ++++++++++---- 7 files changed, 65 insertions(+), 23 deletions(-) diff --git a/include/libtorrent/http_connection.hpp b/include/libtorrent/http_connection.hpp index b13b457fa..fb88d0649 100644 --- a/include/libtorrent/http_connection.hpp +++ b/include/libtorrent/http_connection.hpp @@ -65,7 +65,7 @@ typedef boost::function http_connect_handler; -// TODO: add bind interface +typedef boost::function&)> http_filter_handler; // when bottled, the last two arguments to the handler // will always be 0 @@ -73,12 +73,14 @@ struct http_connection : boost::enable_shared_from_this, boost: { http_connection(io_service& ios, connection_queue& cc , http_handler const& handler, bool bottled = true - , http_connect_handler const& ch = http_connect_handler()) + , http_connect_handler const& ch = http_connect_handler() + , http_filter_handler const& fh = http_filter_handler()) : m_sock(ios) , m_read_pos(0) , m_resolver(ios) , m_handler(handler) , m_connect_handler(ch) + , m_filter_handler(fh) , m_timer(ios) , m_last_receive(time_now()) , m_bottled(bottled) @@ -148,6 +150,7 @@ private: http_parser m_parser; http_handler m_handler; http_connect_handler m_connect_handler; + http_filter_handler m_filter_handler; deadline_timer m_timer; time_duration m_timeout; ptime m_last_receive; diff --git a/include/libtorrent/http_tracker_connection.hpp b/include/libtorrent/http_tracker_connection.hpp index ec34260b0..f71baa0d0 100644 --- a/include/libtorrent/http_tracker_connection.hpp +++ b/include/libtorrent/http_tracker_connection.hpp @@ -57,6 +57,7 @@ namespace libtorrent class http_parser; class connection_queue; struct session_settings; + namespace aux { struct session_impl; } class TORRENT_EXPORT http_tracker_connection : public tracker_connection @@ -71,7 +72,7 @@ namespace libtorrent , tracker_request const& req , address bind_infc , boost::weak_ptr c - , session_settings const& stn + , aux::session_impl const& ses , proxy_settings const& ps , std::string const& password = ""); @@ -83,6 +84,8 @@ namespace libtorrent boost::intrusive_ptr self() { return boost::intrusive_ptr(this); } + void on_filter(http_connection& c, std::list& endpoints); + void on_response(error_code const& ec, http_parser const& parser , char const* data, int size); @@ -93,7 +96,7 @@ namespace libtorrent tracker_manager& m_man; boost::shared_ptr m_tracker_connection; - session_settings const& m_settings; + aux::session_impl const& m_ses; address m_bind_iface; proxy_settings const& m_ps; connection_queue& m_cc; diff --git a/include/libtorrent/udp_tracker_connection.hpp b/include/libtorrent/udp_tracker_connection.hpp index fe51df1fb..114e414f2 100644 --- a/include/libtorrent/udp_tracker_connection.hpp +++ b/include/libtorrent/udp_tracker_connection.hpp @@ -59,6 +59,8 @@ POSSIBILITY OF SUCH DAMAGE. namespace libtorrent { + namespace aux { struct session_impl; } + class TORRENT_EXPORT udp_tracker_connection: public tracker_connection { friend class tracker_manager; @@ -71,7 +73,7 @@ namespace libtorrent , tracker_request const& req , address bind_infc , boost::weak_ptr c - , session_settings const& stn + , aux::session_impl const& ses , proxy_settings const& ps); void start(); @@ -113,7 +115,7 @@ namespace libtorrent int m_transaction_id; boost::int64_t m_connection_id; - session_settings const& m_settings; + aux::session_impl const& m_ses; int m_attempts; action_t m_state; diff --git a/src/http_connection.cpp b/src/http_connection.cpp index a524f180d..f57ed4f0d 100644 --- a/src/http_connection.cpp +++ b/src/http_connection.cpp @@ -273,6 +273,13 @@ void http_connection::on_resolve(error_code const& e std::transform(i, tcp::resolver::iterator(), std::back_inserter(m_endpoints) , boost::bind(&tcp::resolver::iterator::value_type::endpoint, _1)); + if (m_filter_handler) m_filter_handler(*this, m_endpoints); + if (m_endpoints.empty()) + { + close(); + return; + } + // The following statement causes msvc to crash (ICE). Since it's not // necessary in the vast majority of cases, just ignore the endpoint // order for windows diff --git a/src/http_tracker_connection.cpp b/src/http_tracker_connection.cpp index 099f1ee4c..01487013a 100644 --- a/src/http_tracker_connection.cpp +++ b/src/http_tracker_connection.cpp @@ -60,6 +60,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/torrent.hpp" #include "libtorrent/io.hpp" #include "libtorrent/socket.hpp" +#include "libtorrent/aux_/session_impl.hpp" using namespace libtorrent; using boost::bind; @@ -74,12 +75,12 @@ namespace libtorrent , tracker_request const& req , address bind_infc , boost::weak_ptr c - , session_settings const& stn + , aux::session_impl const& ses , proxy_settings const& ps , std::string const& auth) : tracker_connection(man, req, ios, bind_infc, c) , m_man(man) - , m_settings(stn) + , m_ses(ses) , m_bind_iface(bind_infc) , m_ps(ps) , m_cc(cc) @@ -106,6 +107,8 @@ namespace libtorrent url.replace(pos, 8, "scrape"); } + session_settings const& settings = m_ses.settings(); + // if request-string already contains // some parameters, append an ampersand instead // of a question mark @@ -155,10 +158,10 @@ namespace libtorrent url += boost::lexical_cast( (std::min)(tracker_req().num_want, 999)); - if (m_settings.announce_ip != address()) + if (settings.announce_ip != address()) { error_code ec; - std::string ip = m_settings.announce_ip.to_string(ec); + std::string ip = settings.announce_ip.to_string(ec); if (!ec) url += "&ip=" + ip; } @@ -174,14 +177,16 @@ namespace libtorrent } m_tracker_connection.reset(new http_connection(m_ios, m_cc - , boost::bind(&http_tracker_connection::on_response, self(), _1, _2, _3, _4))); + , boost::bind(&http_tracker_connection::on_response, self(), _1, _2, _3, _4) + , true, http_connect_handler() + , boost::bind(&http_tracker_connection::on_filter, self(), _1, _2))); int timeout = tracker_req().event==tracker_request::stopped - ?m_settings.stop_tracker_timeout - :m_settings.tracker_completion_timeout; + ?settings.stop_tracker_timeout + :settings.tracker_completion_timeout; m_tracker_connection->get(url, seconds(timeout) - , 1, &m_ps, 5, m_settings.user_agent, m_bind_iface); + , 1, &m_ps, 5, settings.user_agent, m_bind_iface); // the url + 100 estimated header size sent_bytes(url.size() + 100); @@ -206,6 +211,18 @@ namespace libtorrent tracker_connection::close(); } + void http_tracker_connection::on_filter(http_connection& c, std::list& endpoints) + { + // remove endpoints that are filtered by the IP filter + endpoints.erase(std::remove_if(endpoints.begin(), endpoints.end() + , boost::bind(&ip_filter::access, boost::ref(m_ses.m_ip_filter) + , boost::bind(&tcp::endpoint::address, _1)) == ip_filter::blocked) + , endpoints.end()); + + if (endpoints.empty()) + fail(-1, "blocked by IP filter"); + } + void http_tracker_connection::on_response(error_code const& ec , http_parser const& parser, char const* data, int size) { diff --git a/src/tracker_manager.cpp b/src/tracker_manager.cpp index e0053096a..cad9d9a89 100644 --- a/src/tracker_manager.cpp +++ b/src/tracker_manager.cpp @@ -232,13 +232,13 @@ namespace libtorrent { con = new http_tracker_connection( ios, cc, *this, req, bind_infc, c - , m_ses.settings(), m_proxy, auth); + , m_ses, m_proxy, auth); } else if (protocol == "udp") { con = new udp_tracker_connection( ios, cc, *this, req, bind_infc - , c, m_ses.settings(), m_proxy); + , c, m_ses, m_proxy); } else { diff --git a/src/udp_tracker_connection.cpp b/src/udp_tracker_connection.cpp index 921101b26..e1f7771e1 100644 --- a/src/udp_tracker_connection.cpp +++ b/src/udp_tracker_connection.cpp @@ -55,6 +55,7 @@ POSSIBILITY OF SUCH DAMAGE. #include "libtorrent/parse_url.hpp" #include "libtorrent/udp_tracker_connection.hpp" #include "libtorrent/io.hpp" +#include "libtorrent/aux_/session_impl.hpp" namespace { @@ -80,7 +81,7 @@ namespace libtorrent , tracker_request const& req , address bind_infc , boost::weak_ptr c - , session_settings const& stn + , aux::session_impl const& ses , proxy_settings const& proxy) : tracker_connection(man, req, ios, bind_infc, c) , m_man(man) @@ -88,7 +89,7 @@ namespace libtorrent , m_socket(ios, boost::bind(&udp_tracker_connection::on_receive, self(), _1, _2, _3, _4), cc) , m_transaction_id(0) , m_connection_id(0) - , m_settings(stn) + , m_ses(ses) , m_attempts(0) , m_state(action_error) { @@ -111,14 +112,16 @@ namespace libtorrent return; } + session_settings const& settings = m_ses.settings(); + udp::resolver::query q(hostname, boost::lexical_cast(port)); m_name_lookup.async_resolve(q , boost::bind( &udp_tracker_connection::name_lookup, self(), _1, _2)); set_timeout(tracker_req().event == tracker_request::stopped - ? m_settings.stop_tracker_timeout - : m_settings.tracker_completion_timeout - , m_settings.tracker_receive_timeout); + ? settings.stop_tracker_timeout + : settings.tracker_completion_timeout + , settings.tracker_receive_timeout); #if defined TORRENT_VERBOSE_LOGGING || defined TORRENT_LOGGING boost::shared_ptr cb = requester(); if (cb) cb->debug_log(("*** UDP_TRACKER [ initiating name lookup: " + hostname + " ]").c_str()); @@ -165,6 +168,12 @@ namespace libtorrent { target_address = *target; } + + if (m_ses.m_ip_filter.access(target_address.address()) & ip_filter::blocked) + { + fail(-1, "blocked by IP filter"); + return; + } if (cb) cb->m_tracker_address = tcp::endpoint(target_address.address(), target_address.port()); m_target = target_address; @@ -476,6 +485,7 @@ namespace libtorrent char* out = buf; tracker_request const& req = tracker_req(); + session_settings const& settings = m_ses.settings(); detail::write_int64(m_connection_id, out); // connection_id detail::write_int32(action_announce, out); // action (announce) @@ -489,8 +499,8 @@ namespace libtorrent detail::write_int64(req.uploaded, out); // uploaded detail::write_int32(req.event, out); // event // ip address - if (m_settings.announce_ip != address() && m_settings.announce_ip.is_v4()) - detail::write_uint32(m_settings.announce_ip.to_v4().to_ulong(), out); + if (settings.announce_ip != address() && settings.announce_ip.is_v4()) + detail::write_uint32(settings.announce_ip.to_v4().to_ulong(), out); else detail::write_int32(0, out); detail::write_int32(req.key, out); // key