added peer_blocked_alert which is generated when a peer is blocked by the IP filter. Fixed the ip-filter parsing in client_test and made it report the peer_blocked_alert. Added documentation.

This commit is contained in:
Arvid Norberg 2007-04-17 05:56:43 +00:00
parent 32dc04c09b
commit 849db39472
7 changed files with 154 additions and 70 deletions

View File

@ -137,34 +137,35 @@
<li><a class="reference" href="#metadata-failed-alert" id="id114" name="id114">metadata_failed_alert</a></li> <li><a class="reference" href="#metadata-failed-alert" id="id114" name="id114">metadata_failed_alert</a></li>
<li><a class="reference" href="#metadata-received-alert" id="id115" name="id115">metadata_received_alert</a></li> <li><a class="reference" href="#metadata-received-alert" id="id115" name="id115">metadata_received_alert</a></li>
<li><a class="reference" href="#fastresume-rejected-alert" id="id116" name="id116">fastresume_rejected_alert</a></li> <li><a class="reference" href="#fastresume-rejected-alert" id="id116" name="id116">fastresume_rejected_alert</a></li>
<li><a class="reference" href="#dispatcher" id="id117" name="id117">dispatcher</a></li> <li><a class="reference" href="#peer-blocked-alert" id="id117" name="id117">peer_blocked_alert</a></li>
<li><a class="reference" href="#dispatcher" id="id118" name="id118">dispatcher</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference" href="#exceptions" id="id118" name="id118">exceptions</a><ul> <li><a class="reference" href="#exceptions" id="id119" name="id119">exceptions</a><ul>
<li><a class="reference" href="#invalid-handle" id="id119" name="id119">invalid_handle</a></li> <li><a class="reference" href="#invalid-handle" id="id120" name="id120">invalid_handle</a></li>
<li><a class="reference" href="#duplicate-torrent" id="id120" name="id120">duplicate_torrent</a></li> <li><a class="reference" href="#duplicate-torrent" id="id121" name="id121">duplicate_torrent</a></li>
<li><a class="reference" href="#invalid-encoding" id="id121" name="id121">invalid_encoding</a></li> <li><a class="reference" href="#invalid-encoding" id="id122" name="id122">invalid_encoding</a></li>
<li><a class="reference" href="#type-error" id="id122" name="id122">type_error</a></li> <li><a class="reference" href="#type-error" id="id123" name="id123">type_error</a></li>
<li><a class="reference" href="#invalid-torrent-file" id="id123" name="id123">invalid_torrent_file</a></li> <li><a class="reference" href="#invalid-torrent-file" id="id124" name="id124">invalid_torrent_file</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference" href="#fast-resume" id="id124" name="id124">fast resume</a><ul> <li><a class="reference" href="#fast-resume" id="id125" name="id125">fast resume</a><ul>
<li><a class="reference" href="#file-format" id="id125" name="id125">file format</a></li> <li><a class="reference" href="#file-format" id="id126" name="id126">file format</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference" href="#threads" id="id126" name="id126">threads</a></li> <li><a class="reference" href="#threads" id="id127" name="id127">threads</a></li>
<li><a class="reference" href="#storage-allocation" id="id127" name="id127">storage allocation</a><ul> <li><a class="reference" href="#storage-allocation" id="id128" name="id128">storage allocation</a><ul>
<li><a class="reference" href="#full-allocation" id="id128" name="id128">full allocation</a></li> <li><a class="reference" href="#full-allocation" id="id129" name="id129">full allocation</a></li>
<li><a class="reference" href="#compact-allocation" id="id129" name="id129">compact allocation</a></li> <li><a class="reference" href="#compact-allocation" id="id130" name="id130">compact allocation</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference" href="#extensions" id="id130" name="id130">extensions</a><ul> <li><a class="reference" href="#extensions" id="id131" name="id131">extensions</a><ul>
<li><a class="reference" href="#metadata-from-peers" id="id131" name="id131">metadata from peers</a></li> <li><a class="reference" href="#metadata-from-peers" id="id132" name="id132">metadata from peers</a></li>
<li><a class="reference" href="#http-seeding" id="id132" name="id132">HTTP seeding</a></li> <li><a class="reference" href="#http-seeding" id="id133" name="id133">HTTP seeding</a></li>
</ul> </ul>
</li> </li>
<li><a class="reference" href="#filename-checks" id="id133" name="id133">filename checks</a></li> <li><a class="reference" href="#filename-checks" id="id134" name="id134">filename checks</a></li>
<li><a class="reference" href="#acknowledgments" id="id134" name="id134">acknowledgments</a></li> <li><a class="reference" href="#acknowledgments" id="id135" name="id135">acknowledgments</a></li>
</ul> </ul>
</div> </div>
<div class="section"> <div class="section">
@ -486,6 +487,8 @@ void set_ip_filter(ip_filter const&amp; filter);
connections based on their originating ip address. The default filter will allow connections based on their originating ip address. The default filter will allow
connections to any ip address. To build a set of rules for which addresses are connections to any ip address. To build a set of rules for which addresses are
accepted and not, see <a class="reference" href="#ip-filter">ip_filter</a>.</p> accepted and not, see <a class="reference" href="#ip-filter">ip_filter</a>.</p>
<p>Each time a peer is blocked because of the IP filter, a <a class="reference" href="#peer-blocked-alert">peer_blocked_alert</a> is
generated.</p>
</div> </div>
<div class="section"> <div class="section">
<h2><a id="status" name="status">status()</a></h2> <h2><a id="status" name="status">status()</a></h2>
@ -2883,6 +2886,22 @@ struct fastresume_rejected_alert: torrent_alert
</pre> </pre>
</div> </div>
<div class="section"> <div class="section">
<h2><a id="peer-blocked-alert" name="peer-blocked-alert">peer_blocked_alert</a></h2>
<p>This alert is generated when a peer is blocked by the IP filter. It has the severity leve
<tt class="docutils literal"><span class="pre">info</span></tt>. The <tt class="docutils literal"><span class="pre">ip</span></tt> member is the address that was blocked.</p>
<pre class="literal-block">
struct peer_blocked_alert: alert
{
peer_blocked_alert(address const&amp; ip_
, std::string const&amp; msg);
address ip;
virtual std::auto_ptr&lt;alert&gt; clone() const;
};
</pre>
</div>
<div class="section">
<h2><a id="dispatcher" name="dispatcher">dispatcher</a></h2> <h2><a id="dispatcher" name="dispatcher">dispatcher</a></h2>
<p>The <tt class="docutils literal"><span class="pre">handle_alert</span></tt> class is defined in <tt class="docutils literal"><span class="pre">&lt;libtorrent/alert.hpp&gt;</span></tt>.</p> <p>The <tt class="docutils literal"><span class="pre">handle_alert</span></tt> class is defined in <tt class="docutils literal"><span class="pre">&lt;libtorrent/alert.hpp&gt;</span></tt>.</p>
<p>Examples usage:</p> <p>Examples usage:</p>

View File

@ -345,6 +345,9 @@ connections based on their originating ip address. The default filter will allow
connections to any ip address. To build a set of rules for which addresses are connections to any ip address. To build a set of rules for which addresses are
accepted and not, see ip_filter_. accepted and not, see ip_filter_.
Each time a peer is blocked because of the IP filter, a peer_blocked_alert_ is
generated.
status() status()
-------- --------
@ -2970,6 +2973,24 @@ resume file was rejected. It is generated at severity level ``warning``.
}; };
peer_blocked_alert
------------------
This alert is generated when a peer is blocked by the IP filter. It has the severity leve
``info``. The ``ip`` member is the address that was blocked.
::
struct peer_blocked_alert: alert
{
peer_blocked_alert(address const& ip_
, std::string const& msg);
address ip;
virtual std::auto_ptr<alert> clone() const;
};
dispatcher dispatcher
---------- ----------

View File

@ -673,15 +673,16 @@ int main(int ac, char* av[])
if (line[0] == '#') continue; if (line[0] == '#') continue;
int a, b, c, d; int a, b, c, d;
char dummy; char dummy;
in >> a >> dummy >> b >> dummy >> c >> dummy >> d >> dummy; std::stringstream ln(line);
ln >> a >> dummy >> b >> dummy >> c >> dummy >> d >> dummy;
address_v4 start((a << 24) + (b << 16) + (c << 8) + d); address_v4 start((a << 24) + (b << 16) + (c << 8) + d);
in >> a >> dummy >> b >> dummy >> c >> dummy >> d >> dummy; ln >> a >> dummy >> b >> dummy >> c >> dummy >> d >> dummy;
address_v4 last((a << 24) + (b << 16) + (c << 8) + d); address_v4 last((a << 24) + (b << 16) + (c << 8) + d);
int flags; int flags;
in >> flags; ln >> flags;
if (flags <= 127) flags = ip_filter::blocked; if (flags <= 127) flags = ip_filter::blocked;
else flags = 0; else flags = 0;
if (in.fail()) break; if (ln.fail()) break;
filter.add_rule(start, last, flags); filter.add_rule(start, last, flags);
} }
ses.set_ip_filter(filter); ses.set_ip_filter(filter);
@ -835,6 +836,10 @@ int main(int ac, char* av[])
{ {
event_string << "web seed '" << p->url << "': " << p->msg(); event_string << "web seed '" << p->url << "': " << p->msg();
} }
else if (peer_blocked_alert* p = dynamic_cast<peer_blocked_alert*>(a.get()))
{
event_string << "(" << p->ip << ") " << p->msg();
}
else else
{ {
event_string << a->msg(); event_string << a->msg();

View File

@ -57,7 +57,9 @@ POSSIBILITY OF SUCH DAMAGE.
#include "libtorrent/time.hpp" #include "libtorrent/time.hpp"
#include "libtorrent/config.hpp" #include "libtorrent/config.hpp"
#define TORRENT_MAX_ALERT_TYPES 10 #ifndef TORRENT_MAX_ALERT_TYPES
#define TORRENT_MAX_ALERT_TYPES 15
#endif
namespace libtorrent { namespace libtorrent {
@ -72,7 +74,7 @@ namespace libtorrent {
// a timestamp is automatically created in the constructor // a timestamp is automatically created in the constructor
ptime timestamp() const; ptime timestamp() const;
const std::string& msg() const; std::string const& msg() const;
severity_t severity() const; severity_t severity() const;
@ -112,57 +114,45 @@ namespace libtorrent {
struct void_; struct void_;
template< template<class Handler
class Handler , BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, class T)>
, BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, class T)
>
void handle_alert_dispatch( void handle_alert_dispatch(
const std::auto_ptr<alert>& alert_ const std::auto_ptr<alert>& alert_, const Handler& handler
, const Handler& handler , const std::type_info& typeid_
, const std::type_info& typeid_ , BOOST_PP_ENUM_BINARY_PARAMS(TORRENT_MAX_ALERT_TYPES, T, *p))
, BOOST_PP_ENUM_BINARY_PARAMS(TORRENT_MAX_ALERT_TYPES, T, *p))
{ {
if (typeid_ == typeid(T0)) if (typeid_ == typeid(T0))
handler(*static_cast<T0*>(alert_.get())); handler(*static_cast<T0*>(alert_.get()));
else else
handle_alert_dispatch( handle_alert_dispatch(alert_, handler, typeid_
alert_ , BOOST_PP_ENUM_SHIFTED_PARAMS(
, handler TORRENT_MAX_ALERT_TYPES, p), (void_*)0);
, typeid_
, BOOST_PP_ENUM_SHIFTED_PARAMS(TORRENT_MAX_ALERT_TYPES, p), (void_*)0
);
} }
template<class Handler> template<class Handler>
void handle_alert_dispatch( void handle_alert_dispatch(
const std::auto_ptr<alert>& alert_ const std::auto_ptr<alert>& alert_
, const Handler& handler , const Handler& handler
, const std::type_info& typeid_ , const std::type_info& typeid_
, BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, void_* BOOST_PP_INTERCEPT)) , BOOST_PP_ENUM_PARAMS(TORRENT_MAX_ALERT_TYPES, void_* BOOST_PP_INTERCEPT))
{ {
throw unhandled_alert(); throw unhandled_alert();
} }
} // namespace detail } // namespace detail
template< template<BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(
BOOST_PP_ENUM_PARAMS_WITH_A_DEFAULT(TORRENT_MAX_ALERT_TYPES, class T, detail::void_) TORRENT_MAX_ALERT_TYPES, class T, detail::void_)>
>
struct TORRENT_EXPORT handle_alert struct TORRENT_EXPORT handle_alert
{ {
template<class Handler> template<class Handler>
handle_alert( handle_alert(const std::auto_ptr<alert>& alert_
const std::auto_ptr<alert>& alert_ , const Handler& handler)
, const Handler& handler)
{ {
#define ALERT_POINTER_TYPE(z, n, text) (BOOST_PP_CAT(T, n)*)0 #define ALERT_POINTER_TYPE(z, n, text) (BOOST_PP_CAT(T, n)*)0
detail::handle_alert_dispatch( detail::handle_alert_dispatch(alert_, handler, typeid(*alert_)
alert_ , BOOST_PP_ENUM(TORRENT_MAX_ALERT_TYPES, ALERT_POINTER_TYPE, _));
, handler
, typeid(*alert_)
, BOOST_PP_ENUM(TORRENT_MAX_ALERT_TYPES, ALERT_POINTER_TYPE, _)
);
#undef ALERT_POINTER_TYPE #undef ALERT_POINTER_TYPE
} }

View File

@ -280,6 +280,20 @@ namespace libtorrent
{ return std::auto_ptr<alert>(new fastresume_rejected_alert(*this)); } { return std::auto_ptr<alert>(new fastresume_rejected_alert(*this)); }
}; };
struct TORRENT_EXPORT peer_blocked_alert: alert
{
peer_blocked_alert(address const& ip_
, std::string const& msg)
: alert(alert::info, msg)
, ip(ip_)
{}
address ip;
virtual std::auto_ptr<alert> clone() const
{ return std::auto_ptr<alert>(new peer_blocked_alert(*this)); }
};
} }

View File

@ -597,6 +597,12 @@ namespace libtorrent { namespace detail
#if defined(TORRENT_VERBOSE_LOGGING) #if defined(TORRENT_VERBOSE_LOGGING)
(*i->second->m_logger) << "*** CONNECTION FILTERED\n"; (*i->second->m_logger) << "*** CONNECTION FILTERED\n";
#endif #endif
if (m_alerts.should_post(alert::info))
{
m_alerts.post_alert(peer_blocked_alert(sender.address()
, "peer connection closed by IP filter"));
}
session_impl::connection_map::iterator j = i; session_impl::connection_map::iterator j = i;
++i; ++i;
j->second->disconnect(); j->second->disconnect();
@ -767,7 +773,11 @@ namespace libtorrent { namespace detail
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
(*m_logger) << "filtered blocked ip\n"; (*m_logger) << "filtered blocked ip\n";
#endif #endif
// TODO: issue an info-alert when an ip is blocked!! if (m_alerts.should_post(alert::info))
{
m_alerts.post_alert(peer_blocked_alert(endp.address()
, "incoming connection blocked by IP filter"));
}
return; return;
} }
@ -1018,15 +1028,13 @@ namespace libtorrent { namespace detail
catch (std::exception& exc) catch (std::exception& exc)
{ {
#ifndef NDEBUG #ifndef NDEBUG
std::string err = exc.what(); std::cerr << exc.what() << std::endl;
assert(false);
#endif #endif
}; // msvc 7.1 seems to require this }; // msvc 7.1 seems to require this
void session_impl::connection_completed( void session_impl::connection_completed(
boost::intrusive_ptr<peer_connection> const& p) boost::intrusive_ptr<peer_connection> const& p) try
#ifndef NDEBUG
try
#endif
{ {
mutex_t::scoped_lock l(m_mutex); mutex_t::scoped_lock l(m_mutex);
@ -1039,12 +1047,13 @@ namespace libtorrent { namespace detail
process_connection_queue(); process_connection_queue();
} }
#ifndef NDEBUG
catch (std::exception& e) catch (std::exception& e)
{ {
#ifndef NDEBUG
std::cerr << e.what() << std::endl;
assert(false); assert(false);
};
#endif #endif
};
void session_impl::operator()() void session_impl::operator()()
{ {

View File

@ -573,6 +573,12 @@ namespace libtorrent
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
debug_log("blocked ip from tracker: " + i->ip); debug_log("blocked ip from tracker: " + i->ip);
#endif #endif
if (m_ses.m_alerts.should_post(alert::info))
{
m_ses.m_alerts.post_alert(peer_blocked_alert(a.address()
, "peer from tracker blocked by IP filter"));
}
continue; continue;
} }
@ -615,6 +621,12 @@ namespace libtorrent
#if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING)
debug_log("blocked ip from tracker: " + host->endpoint().address().to_string()); debug_log("blocked ip from tracker: " + host->endpoint().address().to_string());
#endif #endif
if (m_ses.m_alerts.should_post(alert::info))
{
m_ses.m_alerts.post_alert(peer_blocked_alert(host->endpoint().address()
, "peer from tracker blocked by IP filter"));
}
return; return;
} }
@ -1394,13 +1406,6 @@ namespace libtorrent
if (m_ses.is_aborted()) return; if (m_ses.is_aborted()) return;
tcp::endpoint a(host->endpoint()); tcp::endpoint a(host->endpoint());
if (m_ses.m_ip_filter.access(a.address()) & ip_filter::blocked)
{
// TODO: post alert: "proxy at " + a.address().to_string() + " (" + hostname + ") blocked by ip filter");
return;
}
std::string protocol; std::string protocol;
std::string hostname; std::string hostname;
int port; int port;
@ -1408,6 +1413,16 @@ namespace libtorrent
boost::tie(protocol, hostname, port, path) boost::tie(protocol, hostname, port, path)
= parse_url_components(url); = parse_url_components(url);
if (m_ses.m_ip_filter.access(a.address()) & ip_filter::blocked)
{
if (m_ses.m_alerts.should_post(alert::info))
{
m_ses.m_alerts.post_alert(peer_blocked_alert(a.address()
, "proxy (" + hostname + ") blocked by IP filter"));
}
return;
}
tcp::resolver::query q(hostname, boost::lexical_cast<std::string>(port)); tcp::resolver::query q(hostname, boost::lexical_cast<std::string>(port));
m_host_resolver.async_resolve(q, m_ses.m_strand.wrap( m_host_resolver.async_resolve(q, m_ses.m_strand.wrap(
bind(&torrent::on_name_lookup, shared_from_this(), _1, _2, url, a))); bind(&torrent::on_name_lookup, shared_from_this(), _1, _2, url, a)));
@ -1456,7 +1471,11 @@ namespace libtorrent
if (m_ses.m_ip_filter.access(a.address()) & ip_filter::blocked) if (m_ses.m_ip_filter.access(a.address()) & ip_filter::blocked)
{ {
// TODO: post alert: "web seed at " + a.address().to_string() + " blocked by ip filter"); if (m_ses.m_alerts.should_post(alert::info))
{
m_ses.m_alerts.post_alert(peer_blocked_alert(a.address()
, "web seed (" + url + ") blocked by IP filter"));
}
return; return;
} }
@ -1841,7 +1860,14 @@ namespace libtorrent
INVARIANT_CHECK; INVARIANT_CHECK;
tcp::endpoint const& a(peerinfo->ip); tcp::endpoint const& a(peerinfo->ip);
if (m_ses.m_ip_filter.access(a.address()) & ip_filter::blocked) if (m_ses.m_ip_filter.access(a.address()) & ip_filter::blocked)
{
if (m_ses.m_alerts.should_post(alert::info))
{
m_ses.m_alerts.post_alert(peer_blocked_alert(a.address()
, "peer connection blocked by IP filter"));
}
throw protocol_error(a.address().to_string() + " blocked by ip filter"); throw protocol_error(a.address().to_string() + " blocked by ip filter");
}
if (m_connections.find(a) != m_connections.end()) if (m_connections.find(a) != m_connections.end())
throw protocol_error("already connected to peer"); throw protocol_error("already connected to peer");