forked from premiere/premiere-libtorrent
completed IPv6 support in ip_filter and updated test_ip_filter and documentation. Documented recently added extensions to DHT.
This commit is contained in:
parent
a42189af62
commit
fe0d570f05
|
@ -1,3 +1,6 @@
|
|||
* added an extension to the DHT network protocol to support the
|
||||
exchange of nodes with IPv6 addresses.
|
||||
* modified the ip_filter api slightly to support IPv6
|
||||
* modified the api slightly to make sequenced download threshold
|
||||
a per torrent-setting.
|
||||
* changed the address type to support IPv6
|
||||
|
|
|
@ -242,6 +242,14 @@ logging=none dht-support=on dht-support=logging dht-support=off
|
|||
<h2><a name="building-with-autotools">building with autotools</a></h2>
|
||||
<p>First of all, you need to install <tt class="docutils literal"><span class="pre">automake</span></tt> and <tt class="docutils literal"><span class="pre">autoconf</span></tt>. Many
|
||||
unix/linux systems comes with these preinstalled.</p>
|
||||
<p>The prerequisites for building libtorrent is boost.thread, boost.date_time
|
||||
and boost.filesystem. Those are the <em>compiled</em> boost libraries needed. The
|
||||
headers-only libraries needed include (but is not necessarily limited to)
|
||||
boost.bind, boost.ref, boost.multi_index, boost.optional, boost.lexical_cast,
|
||||
boost.integer, boost.iterator, boost.tuple, boost.array, boost.function,
|
||||
boost.smart_ptr, boost.preprocessor, boost.static_assert.</p>
|
||||
<p>If you want to build the <tt class="docutils literal"><span class="pre">client_test</span></tt> example, you'll also need boost.regex
|
||||
and boost.program_options.</p>
|
||||
<div class="section" id="step-1-generating-the-build-system">
|
||||
<h3><a name="step-1-generating-the-build-system">Step 1: Generating the build system</a></h3>
|
||||
<p>No build system is present if libtorrent is checked out from CVS - it
|
||||
|
|
|
@ -232,6 +232,16 @@ building with autotools
|
|||
First of all, you need to install ``automake`` and ``autoconf``. Many
|
||||
unix/linux systems comes with these preinstalled.
|
||||
|
||||
The prerequisites for building libtorrent is boost.thread, boost.date_time
|
||||
and boost.filesystem. Those are the *compiled* boost libraries needed. The
|
||||
headers-only libraries needed include (but is not necessarily limited to)
|
||||
boost.bind, boost.ref, boost.multi_index, boost.optional, boost.lexical_cast,
|
||||
boost.integer, boost.iterator, boost.tuple, boost.array, boost.function,
|
||||
boost.smart_ptr, boost.preprocessor, boost.static_assert.
|
||||
|
||||
If you want to build the ``client_test`` example, you'll also need boost.regex
|
||||
and boost.program_options.
|
||||
|
||||
Step 1: Generating the build system
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||
<meta name="generator" content="Docutils 0.3.9: http://docutils.sourceforge.net/" />
|
||||
<title></title>
|
||||
<meta name="author" content="Arvid Norberg, arvid@rasterbar.com" />
|
||||
<link rel="stylesheet" href="style.css" type="text/css" />
|
||||
</head>
|
||||
<body>
|
||||
<div class="document">
|
||||
<table class="docinfo" frame="void" rules="none">
|
||||
<col class="docinfo-name" />
|
||||
<col class="docinfo-content" />
|
||||
<tbody valign="top">
|
||||
<tr><th class="docinfo-name">Author:</th>
|
||||
<td>Arvid Norberg, <a class="last reference" href="mailto:arvid@rasterbar.com">arvid@rasterbar.com</a></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="section" id="mainline-dht-extensions">
|
||||
<h1><a name="mainline-dht-extensions">Mainline DHT extensions</a></h1>
|
||||
<p>libtorrent implements a few extensions to the Mainline DHT protocol.</p>
|
||||
<div class="section" id="client-identification">
|
||||
<h2><a name="client-identification">client identification</a></h2>
|
||||
<p>In each DHT packet, an extra key is inserted named "v". This is a string
|
||||
describing the client and version used. This can help alot when debugging
|
||||
and finding errors in client implementations. The string is encoded as four
|
||||
characters, two characters describing the client and two characters interpreted
|
||||
as a binary number describing the client version.</p>
|
||||
<p>Currently known clients:</p>
|
||||
<table border="1" class="docutils">
|
||||
<colgroup>
|
||||
<col width="65%" />
|
||||
<col width="35%" />
|
||||
</colgroup>
|
||||
<tbody valign="top">
|
||||
<tr><td>uTorrent</td>
|
||||
<td><tt class="docutils literal"><span class="pre">UT</span></tt></td>
|
||||
</tr>
|
||||
<tr><td>libtorrent</td>
|
||||
<td><tt class="docutils literal"><span class="pre">LT</span></tt></td>
|
||||
</tr>
|
||||
<tr><td>MooPolice</td>
|
||||
<td><tt class="docutils literal"><span class="pre">MP</span></tt></td>
|
||||
</tr>
|
||||
<tr><td>GetRight</td>
|
||||
<td><tt class="docutils literal"><span class="pre">GR</span></tt></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="section" id="ipv6-support">
|
||||
<h2><a name="ipv6-support">IPv6 support</a></h2>
|
||||
<p>The only DHT messages that don't support IPv6 is the <tt class="docutils literal"><span class="pre">nodes</span></tt> reply. It
|
||||
encodes all the contacts as 6 bytes sequences packed together in sequence in
|
||||
string. The problem is that IPv6 endpoints cannot be encoded as 6 bytes, but
|
||||
needs 18 bytes. The extension libtorrent applies is to add another key, called
|
||||
<tt class="docutils literal"><span class="pre">nodes2</span></tt> which is encoded as a list of strings. Each string represents one
|
||||
contact and is encoded as 20 bytes node-id and then a variable length encoded
|
||||
IP address (6 bytes in IPv4 case and 18 bytes in IPv6 case).</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -30,10 +30,11 @@ IPv6 support
|
|||
------------
|
||||
|
||||
The only DHT messages that don't support IPv6 is the ``nodes`` reply. It
|
||||
encodes all the contacts as 6 bytes sequences packet together in sequence in
|
||||
string. The problem is that IPv6 endpoints cannot be encoded as 6 bytes, but
|
||||
18 bytes. The extension libtorrent applies is to add another key, called
|
||||
encodes all the contacts as 6 bytes sequences packed together in sequence in
|
||||
string. The problem is that IPv6 endpoints cannot be encoded as 6 bytes, but
|
||||
needs 18 bytes. The extension libtorrent applies is to add another key, called
|
||||
``nodes2`` which is encoded as a list of strings. Each string represents one
|
||||
contact and is encoded as 20 bytes node-id and then a variable length encoded
|
||||
IP address (6 bytes in IPv4 case and 18 bytes in IPv6 case).
|
||||
|
||||
|
||||
|
|
|
@ -34,7 +34,8 @@
|
|||
<h1><a name="examples">examples</a></h1>
|
||||
<p>Except for the example programs in this manual, there's also a bigger example
|
||||
of a (little bit) more complete client, <tt class="docutils literal"><span class="pre">client_test</span></tt>. There are separate
|
||||
instructions for how to use it <a class="reference" href="client_test.html">here</a> if you'd like to try it.</p>
|
||||
instructions for how to use it <a class="reference" href="client_test.html">here</a> if you'd like to try it. Note that building
|
||||
<tt class="docutils literal"><span class="pre">client_test</span></tt> also requires boost.regex and boost.program_options library.</p>
|
||||
<div class="section" id="dump-torrent">
|
||||
<h2><a name="dump-torrent">dump_torrent</a></h2>
|
||||
<p>This is an example of a program that will take a torrent-file as a parameter and
|
||||
|
|
|
@ -13,7 +13,8 @@ examples
|
|||
|
||||
Except for the example programs in this manual, there's also a bigger example
|
||||
of a (little bit) more complete client, ``client_test``. There are separate
|
||||
instructions for how to use it here__ if you'd like to try it.
|
||||
instructions for how to use it here__ if you'd like to try it. Note that building
|
||||
``client_test`` also requires boost.regex and boost.program_options library.
|
||||
|
||||
__ client_test.html
|
||||
|
||||
|
|
|
@ -47,44 +47,47 @@ example client.</p>
|
|||
project (including this documentation). The current state includes the
|
||||
following features:</p>
|
||||
<ul class="simple">
|
||||
<li>Trackerless torrents (using a kademlia DHT)</li>
|
||||
<li>trackerless torrents (using the Mainline kademlia DHT protocol) with
|
||||
some <a class="reference" href="dht_extensions.html">DHT extensions</a>.</li>
|
||||
<li>support for IPv6</li>
|
||||
<li>piece-wise, unordered, incremental file allocation</li>
|
||||
<li>uses separate threads for checking files and for main downloader, with a
|
||||
fool-proof thread-safe library interface. (i.e. There's no way for the
|
||||
user to cause a deadlock). (see <a class="reference" href="manual.html#threads">threads</a>)</li>
|
||||
<li>adjusts the length of the request queue depending on download rate.</li>
|
||||
<li>multitracker extension support (as <a class="reference" href="http://home.elp.rr.com/tur/multitracker-spec.txt">specified by John Hoffman</a>)</li>
|
||||
<li>supports files > 2 gigabytes.</li>
|
||||
<li>serves multiple torrents on a single port and in a single thread</li>
|
||||
<li>gzipped tracker-responses</li>
|
||||
<li>fast resume support, a way to get rid of the costly piece check at the
|
||||
start of a resumed torrent. Saves the storage state, piece_picker state
|
||||
as well as all local peers in a separate fast-resume file.</li>
|
||||
<li><a class="reference" href="manual.html#http-seeding">HTTP seeding</a>, as <a class="reference" href="http://www.getright.com/seedtorrent.html">specified by Michael Burford of GetRight</a>.</li>
|
||||
<li>piece picking on block-level (as opposed to piece-level).
|
||||
This means it can download parts of the same piece from different peers.
|
||||
It will also prefer to download whole pieces from single peers if the
|
||||
download speed is high enough from that particular peer.</li>
|
||||
<li>supports the <a class="reference" href="extension_protocol.html">udp-tracker protocol</a> by Olaf van der Spek.</li>
|
||||
<li>queues torrents for file check, instead of checking all of them in parallel.</li>
|
||||
<li>supports http proxies and proxy authentication</li>
|
||||
<li>uses separate threads for checking files and for main downloader, with a
|
||||
fool-proof thread-safe library interface. (i.e. There's no way for the
|
||||
user to cause a deadlock). (see <a class="reference" href="manual.html#threads">threads</a>)</li>
|
||||
<li>supports http proxies and basic proxy authentication</li>
|
||||
<li>gzipped tracker-responses</li>
|
||||
<li>can limit the upload and download bandwidth usage and the maximum number of
|
||||
unchoked peers</li>
|
||||
<li>piece-wise, unordered, incremental file allocation</li>
|
||||
<li>implements fair trade. User settable trade-ratio, must at least be 1:1,
|
||||
but one can choose to trade 1 for 2 or any other ratio that isn't unfair
|
||||
to the other party.</li>
|
||||
<li>fast resume support, a way to get rid of the costly piece check at the
|
||||
start of a resumed torrent. Saves the storage state, piece_picker state
|
||||
as well as all local peers in a separate fast-resume file.</li>
|
||||
<li>supports an <a class="reference" href="extension_protocol.html">extension protocol</a>. See <a class="reference" href="manual.html#extensions">extensions</a>.</li>
|
||||
<li>supports files > 2 gigabytes.</li>
|
||||
<li>supports an <a class="reference" href="udp_tracker_protocol.html">extension protocol</a>. See <a class="reference" href="manual.html#extensions">extensions</a>.</li>
|
||||
<li>supports the <tt class="docutils literal"><span class="pre">no_peer_id=1</span></tt> extension that will ease the load off trackers.</li>
|
||||
<li>supports the <a class="reference" href="udp_tracker_protocol.html">udp-tracker protocol</a> by Olaf van der Spek.</li>
|
||||
<li>possibility to limit the number of connections.</li>
|
||||
<li>delays have messages if there's no other outgoing traffic to the peer, and
|
||||
doesn't send have messages to peers that already has the piece. This saves
|
||||
bandwidth.</li>
|
||||
<li>does not have any requirements on the piece order in a torrent that it
|
||||
resumes. This means it can resume a torrent downloaded by any client.</li>
|
||||
<li>adjusts the length of the request queue depending on download rate.</li>
|
||||
<li>supports the <tt class="docutils literal"><span class="pre">compact=1</span></tt> tracker parameter.</li>
|
||||
<li>selective downloading. The ability to select which parts of a torrent you
|
||||
want to download.</li>
|
||||
<li>ip filter</li>
|
||||
<li>ip filter to disallow ip addresses and ip ranges from connecting and
|
||||
being connected</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="section" id="portability">
|
||||
|
|
|
@ -29,45 +29,49 @@ libtorrent is still being developed, however it is stable. It is an ongoing
|
|||
project (including this documentation). The current state includes the
|
||||
following features:
|
||||
|
||||
* Trackerless torrents (using a kademlia DHT)
|
||||
* trackerless torrents (using the Mainline kademlia DHT protocol) with
|
||||
some `DHT extensions`_.
|
||||
* support for IPv6
|
||||
* piece-wise, unordered, incremental file allocation
|
||||
* uses separate threads for checking files and for main downloader, with a
|
||||
fool-proof thread-safe library interface. (i.e. There's no way for the
|
||||
user to cause a deadlock). (see threads_)
|
||||
* adjusts the length of the request queue depending on download rate.
|
||||
* multitracker extension support (as `specified by John Hoffman`__)
|
||||
* supports files > 2 gigabytes.
|
||||
* serves multiple torrents on a single port and in a single thread
|
||||
* gzipped tracker-responses
|
||||
* fast resume support, a way to get rid of the costly piece check at the
|
||||
start of a resumed torrent. Saves the storage state, piece_picker state
|
||||
as well as all local peers in a separate fast-resume file.
|
||||
* `HTTP seeding`_, as `specified by Michael Burford of GetRight`__.
|
||||
* piece picking on block-level (as opposed to piece-level).
|
||||
This means it can download parts of the same piece from different peers.
|
||||
It will also prefer to download whole pieces from single peers if the
|
||||
download speed is high enough from that particular peer.
|
||||
* supports the `udp-tracker protocol`__ by Olaf van der Spek.
|
||||
* queues torrents for file check, instead of checking all of them in parallel.
|
||||
* supports http proxies and proxy authentication
|
||||
* uses separate threads for checking files and for main downloader, with a
|
||||
fool-proof thread-safe library interface. (i.e. There's no way for the
|
||||
user to cause a deadlock). (see threads_)
|
||||
* supports http proxies and basic proxy authentication
|
||||
* gzipped tracker-responses
|
||||
* can limit the upload and download bandwidth usage and the maximum number of
|
||||
unchoked peers
|
||||
* piece-wise, unordered, incremental file allocation
|
||||
* implements fair trade. User settable trade-ratio, must at least be 1:1,
|
||||
but one can choose to trade 1 for 2 or any other ratio that isn't unfair
|
||||
to the other party.
|
||||
* fast resume support, a way to get rid of the costly piece check at the
|
||||
start of a resumed torrent. Saves the storage state, piece_picker state
|
||||
as well as all local peers in a separate fast-resume file.
|
||||
* supports an `extension protocol`__. See extensions_.
|
||||
* supports files > 2 gigabytes.
|
||||
* supports the ``no_peer_id=1`` extension that will ease the load off trackers.
|
||||
* supports the `udp-tracker protocol`__ by Olaf van der Spek.
|
||||
* possibility to limit the number of connections.
|
||||
* delays have messages if there's no other outgoing traffic to the peer, and
|
||||
doesn't send have messages to peers that already has the piece. This saves
|
||||
bandwidth.
|
||||
* does not have any requirements on the piece order in a torrent that it
|
||||
resumes. This means it can resume a torrent downloaded by any client.
|
||||
* adjusts the length of the request queue depending on download rate.
|
||||
* supports the ``compact=1`` tracker parameter.
|
||||
* selective downloading. The ability to select which parts of a torrent you
|
||||
want to download.
|
||||
* ip filter
|
||||
* ip filter to disallow ip addresses and ip ranges from connecting and
|
||||
being connected
|
||||
|
||||
.. _`DHT extensions`: dht_extensions.html
|
||||
__ http://home.elp.rr.com/tur/multitracker-spec.txt
|
||||
__ http://www.getright.com/seedtorrent.html
|
||||
__ extension_protocol.html
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<body>
|
||||
<div class="document">
|
||||
<div id="librarySidebar"><ul class="simple">
|
||||
<li><a class="reference" href="http://sourceforge.net/project/showfiles.php?group_id=79942">download</a></li>
|
||||
<li><a class="reference" href="features.html">features</a></li>
|
||||
<li><a class="reference" href="building.html">building libtorrent</a></li>
|
||||
<li><a class="reference" href="examples.html">examples</a></li>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<div id="librarySidebar">
|
||||
|
||||
|
||||
* download_
|
||||
* features_
|
||||
* `building libtorrent`_
|
||||
* examples_
|
||||
|
@ -22,6 +22,7 @@
|
|||
libtorrent
|
||||
==========
|
||||
|
||||
.. _download: http://sourceforge.net/project/showfiles.php?group_id=79942
|
||||
.. _features: features.html
|
||||
.. _`building libtorrent`: building.html
|
||||
.. _examples: examples.html
|
||||
|
|
|
@ -1939,28 +1939,32 @@ the number of outstanding requests to use with url-seeds. Default is 5.</p>
|
|||
<h1><a name="ip-filter">ip_filter</a></h1>
|
||||
<p>The <tt class="docutils literal"><span class="pre">ip_filter</span></tt> class is a set of rules that uniquely categorizes all
|
||||
ip addresses as allowed or disallowed. The default constructor creates
|
||||
a single rule that allows all addresses (0.0.0.0 - 255.255.255.255).
|
||||
The <tt class="docutils literal"><span class="pre">address</span></tt> type here is <tt class="docutils literal"><span class="pre">asio::ip::address_v4</span></tt>. It can also be
|
||||
accessed as <tt class="docutils literal"><span class="pre">libtorrent::address</span></tt>.</p>
|
||||
a single rule that allows all addresses (0.0.0.0 - 255.255.255.255 for
|
||||
the IPv4 range, and the equivalent range covering all addresses for the
|
||||
IPv6 range).</p>
|
||||
<blockquote>
|
||||
<pre class="literal-block">
|
||||
template <class Addr>
|
||||
struct ip_range
|
||||
{
|
||||
Addr first;
|
||||
Addr last;
|
||||
int flags;
|
||||
};
|
||||
|
||||
class ip_filter
|
||||
{
|
||||
public:
|
||||
enum access_flags { blocked = 1 };
|
||||
|
||||
ip_filter();
|
||||
void add_rule(address_v4 first, address_v4 last, int flags);
|
||||
int access(address_v4 const& addr) const;
|
||||
void add_rule(address first, address last, int flags);
|
||||
int access(address const& addr) const;
|
||||
|
||||
struct ip_range
|
||||
{
|
||||
address_v4 first;
|
||||
address_v4 last;
|
||||
int flags;
|
||||
};
|
||||
typedef boost::tuple<std::vector<ip_range<address_v4> >
|
||||
, std::vector<ip_range<address_v6> > > filter_tuple_t;
|
||||
|
||||
std::vector<ip_range> export_filter() const;
|
||||
filter_tuple_t export_filter() const;
|
||||
};
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
@ -1979,13 +1983,15 @@ ip_filter()
|
|||
<h2><a name="add-rule">add_rule()</a></h2>
|
||||
<blockquote>
|
||||
<pre class="literal-block">
|
||||
void add_rule(address_v4 first, address_v4 last, int flags);
|
||||
void add_rule(address first, address last, int flags);
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>Adds a rule to the filter. <tt class="docutils literal"><span class="pre">first</span></tt> and <tt class="docutils literal"><span class="pre">last</span></tt> defines a range of
|
||||
ip addresses that will be marked with the given flags. The <tt class="docutils literal"><span class="pre">flags</span></tt>
|
||||
can currently be 0, which means allowed, or <tt class="docutils literal"><span class="pre">ip_filter::blocked</span></tt>, which
|
||||
means disallowed.</p>
|
||||
<p>precondition:
|
||||
<tt class="docutils literal"><span class="pre">first.is_v4()</span> <span class="pre">==</span> <span class="pre">last.is_v4()</span> <span class="pre">&&</span> <span class="pre">first.is_v6()</span> <span class="pre">==</span> <span class="pre">last.is_v6()</span></tt></p>
|
||||
<p>postcondition:
|
||||
<tt class="docutils literal"><span class="pre">access(x)</span> <span class="pre">==</span> <span class="pre">flags</span></tt> for every <tt class="docutils literal"><span class="pre">x</span></tt> in the range [<tt class="docutils literal"><span class="pre">first</span></tt>, <tt class="docutils literal"><span class="pre">last</span></tt>]</p>
|
||||
<p>This means that in a case of overlapping ranges, the last one applied takes
|
||||
|
@ -1995,7 +2001,7 @@ precedence.</p>
|
|||
<h2><a name="access">access()</a></h2>
|
||||
<blockquote>
|
||||
<pre class="literal-block">
|
||||
int access(address_v4 const& addr) const;
|
||||
int access(address const& addr) const;
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>Returns the access permissions for the given address (<tt class="docutils literal"><span class="pre">addr</span></tt>). The permission
|
||||
|
@ -2007,13 +2013,16 @@ the current filter.</p>
|
|||
<h2><a name="export-filter">export_filter()</a></h2>
|
||||
<blockquote>
|
||||
<pre class="literal-block">
|
||||
std::vector<ip_range> export_filter() const;
|
||||
boost::tuple<std::vector<ip_range<address_v4> >
|
||||
, std::vector<ip_range<address_v6> > > export_filter() const;
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p>This function will return the current state of the filter in the minimum number of
|
||||
ranges possible. They are sorted from ranges in low addresses to high addresses. Each
|
||||
entry in the returned vector is a range with the access control specified in its
|
||||
<tt class="docutils literal"><span class="pre">flags</span></tt> field.</p>
|
||||
<p>The return value is a tuple containing two range-lists. One for IPv4 addresses
|
||||
and one for IPv6 addresses.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="section" id="big-number">
|
||||
|
|
|
@ -1935,29 +1935,33 @@ ip_filter
|
|||
|
||||
The ``ip_filter`` class is a set of rules that uniquely categorizes all
|
||||
ip addresses as allowed or disallowed. The default constructor creates
|
||||
a single rule that allows all addresses (0.0.0.0 - 255.255.255.255).
|
||||
The ``address`` type here is ``asio::ip::address_v4``. It can also be
|
||||
accessed as ``libtorrent::address``.
|
||||
a single rule that allows all addresses (0.0.0.0 - 255.255.255.255 for
|
||||
the IPv4 range, and the equivalent range covering all addresses for the
|
||||
IPv6 range).
|
||||
|
||||
::
|
||||
|
||||
template <class Addr>
|
||||
struct ip_range
|
||||
{
|
||||
Addr first;
|
||||
Addr last;
|
||||
int flags;
|
||||
};
|
||||
|
||||
class ip_filter
|
||||
{
|
||||
public:
|
||||
enum access_flags { blocked = 1 };
|
||||
|
||||
ip_filter();
|
||||
void add_rule(address_v4 first, address_v4 last, int flags);
|
||||
int access(address_v4 const& addr) const;
|
||||
void add_rule(address first, address last, int flags);
|
||||
int access(address const& addr) const;
|
||||
|
||||
struct ip_range
|
||||
{
|
||||
address_v4 first;
|
||||
address_v4 last;
|
||||
int flags;
|
||||
};
|
||||
typedef boost::tuple<std::vector<ip_range<address_v4> >
|
||||
, std::vector<ip_range<address_v6> > > filter_tuple_t;
|
||||
|
||||
std::vector<ip_range> export_filter() const;
|
||||
filter_tuple_t export_filter() const;
|
||||
};
|
||||
|
||||
|
||||
|
@ -1979,13 +1983,16 @@ add_rule()
|
|||
|
||||
::
|
||||
|
||||
void add_rule(address_v4 first, address_v4 last, int flags);
|
||||
void add_rule(address first, address last, int flags);
|
||||
|
||||
Adds a rule to the filter. ``first`` and ``last`` defines a range of
|
||||
ip addresses that will be marked with the given flags. The ``flags``
|
||||
can currently be 0, which means allowed, or ``ip_filter::blocked``, which
|
||||
means disallowed.
|
||||
|
||||
precondition:
|
||||
``first.is_v4() == last.is_v4() && first.is_v6() == last.is_v6()``
|
||||
|
||||
postcondition:
|
||||
``access(x) == flags`` for every ``x`` in the range [``first``, ``last``]
|
||||
|
||||
|
@ -1998,7 +2005,7 @@ access()
|
|||
|
||||
::
|
||||
|
||||
int access(address_v4 const& addr) const;
|
||||
int access(address const& addr) const;
|
||||
|
||||
Returns the access permissions for the given address (``addr``). The permission
|
||||
can currently be 0 or ``ip_filter::blocked``. The complexity of this operation
|
||||
|
@ -2011,13 +2018,17 @@ export_filter()
|
|||
|
||||
::
|
||||
|
||||
std::vector<ip_range> export_filter() const;
|
||||
boost::tuple<std::vector<ip_range<address_v4> >
|
||||
, std::vector<ip_range<address_v6> > > export_filter() const;
|
||||
|
||||
This function will return the current state of the filter in the minimum number of
|
||||
ranges possible. They are sorted from ranges in low addresses to high addresses. Each
|
||||
entry in the returned vector is a range with the access control specified in its
|
||||
``flags`` field.
|
||||
|
||||
The return value is a tuple containing two range-lists. One for IPv4 addresses
|
||||
and one for IPv6 addresses.
|
||||
|
||||
|
||||
big_number
|
||||
==========
|
||||
|
|
|
@ -33,6 +33,19 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
#ifndef TORRENT_IP_FILTER_HPP
|
||||
#define TORRENT_IP_FILTER_HPP
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(push, 1)
|
||||
#endif
|
||||
|
||||
#include <boost/limits.hpp>
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/tuple/tuple.hpp>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
|
||||
#include "libtorrent/config.hpp"
|
||||
#include "libtorrent/socket.hpp"
|
||||
#include <set>
|
||||
|
@ -47,6 +60,189 @@ inline bool operator<=(address const& lhs
|
|||
return lhs < rhs || lhs == rhs;
|
||||
}
|
||||
|
||||
template <class Addr>
|
||||
struct ip_range
|
||||
{
|
||||
Addr first;
|
||||
Addr last;
|
||||
int flags;
|
||||
};
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
// this is the generic implementation of
|
||||
// a filter for a specific address type.
|
||||
// it works with IPv4 and IPv6
|
||||
template<class Addr>
|
||||
class filter_impl
|
||||
{
|
||||
public:
|
||||
|
||||
filter_impl()
|
||||
{
|
||||
typename Addr::bytes_type zero;
|
||||
std::fill(zero.begin(), zero.end(), 0);
|
||||
// make the entire ip-range non-blocked
|
||||
m_access_list.insert(range(Addr(zero), 0));
|
||||
}
|
||||
|
||||
void add_rule(Addr first, Addr last, int flags)
|
||||
{
|
||||
using boost::next;
|
||||
using boost::prior;
|
||||
|
||||
assert(!m_access_list.empty());
|
||||
assert(first < last || first == last);
|
||||
|
||||
typename range_t::iterator i = m_access_list.upper_bound(first);
|
||||
typename range_t::iterator j = m_access_list.upper_bound(last);
|
||||
|
||||
if (i != m_access_list.begin()) --i;
|
||||
|
||||
assert(j != m_access_list.begin());
|
||||
assert(j != i);
|
||||
|
||||
int first_access = i->access;
|
||||
int last_access = prior(j)->access;
|
||||
|
||||
if (i->start != first && first_access != flags)
|
||||
{
|
||||
i = m_access_list.insert(i, range(first, flags));
|
||||
}
|
||||
else if (i != m_access_list.begin() && prior(i)->access == flags)
|
||||
{
|
||||
--i;
|
||||
first_access = i->access;
|
||||
}
|
||||
assert(!m_access_list.empty());
|
||||
assert(i != m_access_list.end());
|
||||
|
||||
if (i != j) m_access_list.erase(next(i), j);
|
||||
if (i->start == first)
|
||||
{
|
||||
// we can do this const-cast because we know that the new
|
||||
// start address will keep the set correctly ordered
|
||||
const_cast<Addr&>(i->start) = first;
|
||||
const_cast<int&>(i->access) = flags;
|
||||
}
|
||||
else if (first_access != flags)
|
||||
{
|
||||
m_access_list.insert(i, range(first, flags));
|
||||
}
|
||||
|
||||
if ((j != m_access_list.end()
|
||||
&& minus_one(j->start) != last)
|
||||
|| (j == m_access_list.end()
|
||||
&& last != max_addr()))
|
||||
{
|
||||
assert(j == m_access_list.end() || last < minus_one(j->start));
|
||||
if (last_access != flags)
|
||||
j = m_access_list.insert(j, range(plus_one(last), last_access));
|
||||
}
|
||||
|
||||
if (j != m_access_list.end() && j->access == flags) m_access_list.erase(j);
|
||||
assert(!m_access_list.empty());
|
||||
}
|
||||
|
||||
int access(Addr const& addr) const
|
||||
{
|
||||
assert(!m_access_list.empty());
|
||||
typename range_t::const_iterator i = m_access_list.upper_bound(addr);
|
||||
if (i != m_access_list.begin()) --i;
|
||||
assert(i != m_access_list.end());
|
||||
assert(i->start <= addr && (boost::next(i) == m_access_list.end()
|
||||
|| addr < boost::next(i)->start));
|
||||
return i->access;
|
||||
}
|
||||
|
||||
std::vector<ip_range<Addr> > export_filter() const
|
||||
{
|
||||
std::vector<ip_range<Addr> > ret;
|
||||
ret.reserve(m_access_list.size());
|
||||
|
||||
for (typename range_t::const_iterator i = m_access_list.begin()
|
||||
, end(m_access_list.end()); i != end;)
|
||||
{
|
||||
ip_range<Addr> r;
|
||||
r.first = i->start;
|
||||
r.flags = i->access;
|
||||
|
||||
++i;
|
||||
if (i == end)
|
||||
r.last = max_addr();
|
||||
else
|
||||
r.last = minus_one(i->start);
|
||||
|
||||
ret.push_back(r);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
Addr plus_one(Addr const& a) const
|
||||
{
|
||||
typename Addr::bytes_type tmp(a.to_bytes());
|
||||
typedef typename Addr::bytes_type::reverse_iterator iter;
|
||||
for (iter i = tmp.rbegin()
|
||||
, end(tmp.rend()); i != end; ++i)
|
||||
{
|
||||
if (*i < std::numeric_limits<typename iter::value_type>::max())
|
||||
{
|
||||
*i += 1;
|
||||
break;
|
||||
}
|
||||
*i = 0;
|
||||
}
|
||||
return Addr(tmp);
|
||||
}
|
||||
|
||||
Addr minus_one(Addr const& a) const
|
||||
{
|
||||
typename Addr::bytes_type tmp(a.to_bytes());
|
||||
typedef typename Addr::bytes_type::reverse_iterator iter;
|
||||
for (iter i = tmp.rbegin()
|
||||
, end(tmp.rend()); i != end; ++i)
|
||||
{
|
||||
if (*i > 0)
|
||||
{
|
||||
*i -= 1;
|
||||
break;
|
||||
}
|
||||
*i = std::numeric_limits<typename iter::value_type>::max();
|
||||
}
|
||||
return Addr(tmp);
|
||||
}
|
||||
|
||||
Addr max_addr() const
|
||||
{
|
||||
typename Addr::bytes_type tmp;
|
||||
std::fill(tmp.begin(), tmp.end()
|
||||
, std::numeric_limits<typename Addr::bytes_type::value_type>::max());
|
||||
return Addr(tmp);
|
||||
}
|
||||
|
||||
struct range
|
||||
{
|
||||
range(Addr addr, int access = 0): start(addr), access(access) {}
|
||||
bool operator<(range const& r) const
|
||||
{ return start < r.start; }
|
||||
bool operator<(Addr const& a) const
|
||||
{ return start < a; }
|
||||
Addr start;
|
||||
// the end of the range is implicit
|
||||
// and given by the next entry in the set
|
||||
int access;
|
||||
};
|
||||
|
||||
typedef std::set<range> range_t;
|
||||
range_t m_access_list;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class TORRENT_EXPORT ip_filter
|
||||
{
|
||||
public:
|
||||
|
@ -55,38 +251,23 @@ public:
|
|||
{
|
||||
blocked = 1
|
||||
};
|
||||
|
||||
ip_filter();
|
||||
void add_rule(address_v4 first, address_v4 last, int flags);
|
||||
int access(address_v4 const& addr) const;
|
||||
|
||||
struct ip_range
|
||||
{
|
||||
address_v4 first;
|
||||
address_v4 last;
|
||||
int flags;
|
||||
};
|
||||
|
||||
std::vector<ip_range> export_filter() const;
|
||||
// both addresses MUST be of the same type (i.e. both must
|
||||
// be either IPv4 or both must be IPv6)
|
||||
void add_rule(address first, address last, int flags);
|
||||
int access(address const& addr) const;
|
||||
|
||||
typedef boost::tuple<std::vector<ip_range<address_v4> >
|
||||
, std::vector<ip_range<address_v6> > > filter_tuple_t;
|
||||
|
||||
filter_tuple_t export_filter() const;
|
||||
|
||||
// void print() const;
|
||||
|
||||
private:
|
||||
struct range
|
||||
{
|
||||
range(address_v4 addr, int access = 0): start(addr), access(access) {}
|
||||
bool operator<(range const& r) const
|
||||
{ return start < r.start; }
|
||||
bool operator<(address const& a) const
|
||||
{ return start < a; }
|
||||
address_v4 start;
|
||||
// the end of the range is implicit
|
||||
// and given by the next entry in the set
|
||||
int access;
|
||||
};
|
||||
|
||||
typedef std::set<range> range_t;
|
||||
range_t m_access_list;
|
||||
detail::filter_impl<address_v4> m_filter4;
|
||||
detail::filter_impl<address_v6> m_filter6;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -37,103 +37,37 @@ POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace libtorrent
|
||||
{
|
||||
|
||||
ip_filter::ip_filter()
|
||||
void ip_filter::add_rule(address first, address last, int flags)
|
||||
{
|
||||
// make the entire ip-range non-blocked
|
||||
m_access_list.insert(range(address_v4(0UL), 0));
|
||||
if (first.is_v4())
|
||||
{
|
||||
assert(last.is_v4());
|
||||
m_filter4.add_rule(first.to_v4(), last.to_v4(), flags);
|
||||
}
|
||||
else if (first.is_v6())
|
||||
{
|
||||
assert(last.is_v6());
|
||||
m_filter6.add_rule(first.to_v6(), last.to_v6(), flags);
|
||||
}
|
||||
else
|
||||
assert(false);
|
||||
}
|
||||
|
||||
void ip_filter::add_rule(address_v4 first, address_v4 last, int flags)
|
||||
int ip_filter::access(address const& addr) const
|
||||
{
|
||||
using boost::next;
|
||||
using boost::prior;
|
||||
|
||||
assert(!m_access_list.empty());
|
||||
assert(first <= last);
|
||||
range_t::iterator i = m_access_list.upper_bound(first);
|
||||
range_t::iterator j = m_access_list.upper_bound(last);
|
||||
|
||||
if (i != m_access_list.begin()) --i;
|
||||
|
||||
assert(j != m_access_list.begin());
|
||||
assert(j != i);
|
||||
|
||||
int first_access = i->access;
|
||||
int last_access = prior(j)->access;
|
||||
|
||||
if (i->start != first && first_access != flags)
|
||||
{
|
||||
i = m_access_list.insert(i, range(first, flags));
|
||||
}
|
||||
else if (i != m_access_list.begin() && prior(i)->access == flags)
|
||||
{
|
||||
--i;
|
||||
first_access = i->access;
|
||||
}
|
||||
assert(!m_access_list.empty());
|
||||
assert(i != m_access_list.end());
|
||||
|
||||
if (i != j)
|
||||
m_access_list.erase(next(i), j);
|
||||
if (i->start == first)
|
||||
{
|
||||
// we can do this const-cast because we know that the new
|
||||
// start address will keep the set correctly ordered
|
||||
const_cast<address_v4&>(i->start) = first;
|
||||
const_cast<int&>(i->access) = flags;
|
||||
}
|
||||
else if (first_access != flags)
|
||||
{
|
||||
m_access_list.insert(i, range(first, flags));
|
||||
}
|
||||
|
||||
if ((j != m_access_list.end() && j->start.to_ulong() - 1 != last.to_ulong())
|
||||
|| (j == m_access_list.end() && last.to_ulong() != 0xffffffff))
|
||||
{
|
||||
assert(j == m_access_list.end() || last.to_ulong() < j->start.to_ulong() - 1);
|
||||
if (last_access != flags)
|
||||
j = m_access_list.insert(j, range(address_v4(last.to_ulong() + 1), last_access));
|
||||
}
|
||||
|
||||
if (j != m_access_list.end() && j->access == flags) m_access_list.erase(j);
|
||||
assert(!m_access_list.empty());
|
||||
if (addr.is_v4())
|
||||
return m_filter4.access(addr.to_v4());
|
||||
else if (addr.is_v6())
|
||||
return m_filter6.access(addr.to_v6());
|
||||
else
|
||||
assert(false);
|
||||
}
|
||||
|
||||
int ip_filter::access(address_v4 const& addr) const
|
||||
ip_filter::filter_tuple_t ip_filter::export_filter() const
|
||||
{
|
||||
assert(!m_access_list.empty());
|
||||
range_t::const_iterator i = m_access_list.upper_bound(addr);
|
||||
if (i != m_access_list.begin()) --i;
|
||||
assert(i != m_access_list.end());
|
||||
assert(i->start <= addr && (boost::next(i) == m_access_list.end()
|
||||
|| addr < boost::next(i)->start));
|
||||
return i->access;
|
||||
return boost::make_tuple(m_filter4.export_filter()
|
||||
, m_filter6.export_filter());
|
||||
}
|
||||
|
||||
|
||||
std::vector<ip_filter::ip_range> ip_filter::export_filter() const
|
||||
{
|
||||
std::vector<ip_range> ret;
|
||||
ret.reserve(m_access_list.size());
|
||||
|
||||
for (range_t::const_iterator i = m_access_list.begin()
|
||||
, end(m_access_list.end()); i != end;)
|
||||
{
|
||||
ip_range r;
|
||||
r.first = i->start;
|
||||
r.flags = i->access;
|
||||
|
||||
++i;
|
||||
if (i == end)
|
||||
r.last = address_v4(0xffffffff);
|
||||
else
|
||||
r.last = address_v4(i->start.to_ulong() - 1);
|
||||
|
||||
ret.push_back(r);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
void ip_filter::print() const
|
||||
|
|
|
@ -3,24 +3,35 @@
|
|||
|
||||
#include "test.hpp"
|
||||
|
||||
/*
|
||||
|
||||
Currently this test only tests that the filter can handle
|
||||
IPv4 addresses. Maybe it should be extended to IPv6 as well,
|
||||
but the actual code is just a template, so it is probably
|
||||
pretty safe to assume that as long as it works for IPv4 it
|
||||
also works for IPv6.
|
||||
|
||||
*/
|
||||
|
||||
using namespace libtorrent;
|
||||
|
||||
bool compare(ip_filter::ip_range const& lhs
|
||||
, ip_filter::ip_range const& rhs)
|
||||
template <class Addr>
|
||||
bool compare(ip_range<Addr> const& lhs
|
||||
, ip_range<Addr> const& rhs)
|
||||
{
|
||||
return lhs.first == rhs.first
|
||||
&& lhs.last == rhs.last
|
||||
&& lhs.flags == rhs.flags;
|
||||
}
|
||||
|
||||
void test_rules_invariant(std::vector<ip_filter::ip_range> const& r, ip_filter const& f)
|
||||
void test_rules_invariant(std::vector<ip_range<address_v4> > const& r, ip_filter const& f)
|
||||
{
|
||||
typedef std::vector<ip_filter::ip_range>::const_iterator iterator;
|
||||
typedef std::vector<ip_range<address_v4> >::const_iterator iterator;
|
||||
TEST_CHECK(!r.empty());
|
||||
if (r.empty()) return;
|
||||
|
||||
TEST_CHECK(r.front().first == address_v4::from_string("0.0.0.0"));
|
||||
TEST_CHECK(r.back().last == address_v4::from_string("255.255.255.255"));
|
||||
TEST_CHECK(r.front().first == address::from_string("0.0.0.0"));
|
||||
TEST_CHECK(r.back().last == address::from_string("255.255.255.255"));
|
||||
|
||||
iterator i = r.begin();
|
||||
iterator j = boost::next(i);
|
||||
|
@ -36,10 +47,11 @@ void test_rules_invariant(std::vector<ip_filter::ip_range> const& r, ip_filter c
|
|||
int test_main()
|
||||
{
|
||||
using namespace libtorrent;
|
||||
std::vector<ip_filter::ip_range> range;
|
||||
|
||||
std::vector<ip_range<address_v4> > range;
|
||||
|
||||
// **** test joining of ranges at the end ****
|
||||
ip_filter::ip_range expected1[] =
|
||||
ip_range<address_v4> expected1[] =
|
||||
{
|
||||
{address_v4::from_string("0.0.0.0"), address_v4::from_string("0.255.255.255"), 0}
|
||||
, {address_v4::from_string("1.0.0.0"), address_v4::from_string("3.0.0.0"), ip_filter::blocked}
|
||||
|
@ -48,28 +60,30 @@ int test_main()
|
|||
|
||||
{
|
||||
ip_filter f;
|
||||
f.add_rule(address_v4::from_string("1.0.0.0"), address_v4::from_string("2.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address_v4::from_string("2.0.0.1"), address_v4::from_string("3.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address::from_string("1.0.0.0"), address::from_string("2.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address::from_string("2.0.0.1"), address::from_string("3.0.0.0"), ip_filter::blocked);
|
||||
|
||||
range = f.export_filter();
|
||||
range = boost::get<0>(f.export_filter());
|
||||
test_rules_invariant(range, f);
|
||||
|
||||
TEST_CHECK(range.size() == 3);
|
||||
TEST_CHECK(std::equal(range.begin(), range.end(), expected1, &compare));
|
||||
TEST_CHECK(std::equal(range.begin(), range.end(), expected1, &compare<address_v4>));
|
||||
|
||||
}
|
||||
|
||||
// **** test joining of ranges at the start ****
|
||||
|
||||
{
|
||||
ip_filter f;
|
||||
f.add_rule(address_v4::from_string("2.0.0.1"), address_v4::from_string("3.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address_v4::from_string("1.0.0.0"), address_v4::from_string("2.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address::from_string("2.0.0.1"), address::from_string("3.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address::from_string("1.0.0.0"), address::from_string("2.0.0.0"), ip_filter::blocked);
|
||||
|
||||
range = f.export_filter();
|
||||
range = boost::get<0>(f.export_filter());
|
||||
test_rules_invariant(range, f);
|
||||
|
||||
TEST_CHECK(range.size() == 3);
|
||||
TEST_CHECK(std::equal(range.begin(), range.end(), expected1, &compare));
|
||||
TEST_CHECK(std::equal(range.begin(), range.end(), expected1, &compare<address_v4>));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -77,14 +91,15 @@ int test_main()
|
|||
|
||||
{
|
||||
ip_filter f;
|
||||
f.add_rule(address_v4::from_string("2.0.0.1"), address_v4::from_string("3.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address_v4::from_string("1.0.0.0"), address_v4::from_string("2.4.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address::from_string("2.0.0.1"), address::from_string("3.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address::from_string("1.0.0.0"), address::from_string("2.4.0.0"), ip_filter::blocked);
|
||||
|
||||
range = f.export_filter();
|
||||
range = boost::get<0>(f.export_filter());
|
||||
test_rules_invariant(range, f);
|
||||
|
||||
TEST_CHECK(range.size() == 3);
|
||||
TEST_CHECK(std::equal(range.begin(), range.end(), expected1, &compare));
|
||||
TEST_CHECK(std::equal(range.begin(), range.end(), expected1, &compare<address_v4>));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -92,14 +107,15 @@ int test_main()
|
|||
|
||||
{
|
||||
ip_filter f;
|
||||
f.add_rule(address_v4::from_string("1.0.0.0"), address_v4::from_string("2.4.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address_v4::from_string("2.0.0.1"), address_v4::from_string("3.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address::from_string("1.0.0.0"), address::from_string("2.4.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address::from_string("2.0.0.1"), address::from_string("3.0.0.0"), ip_filter::blocked);
|
||||
|
||||
range = f.export_filter();
|
||||
range = boost::get<0>(f.export_filter());
|
||||
test_rules_invariant(range, f);
|
||||
|
||||
TEST_CHECK(range.size() == 3);
|
||||
TEST_CHECK(std::equal(range.begin(), range.end(), expected1, &compare));
|
||||
TEST_CHECK(std::equal(range.begin(), range.end(), expected1, &compare<address_v4>));
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -107,50 +123,52 @@ int test_main()
|
|||
|
||||
{
|
||||
ip_filter f;
|
||||
f.add_rule(address_v4::from_string("1.0.0.0"), address_v4::from_string("2.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address_v4::from_string("3.0.0.0"), address_v4::from_string("4.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address_v4::from_string("5.0.0.0"), address_v4::from_string("6.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address_v4::from_string("7.0.0.0"), address_v4::from_string("8.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address::from_string("1.0.0.0"), address::from_string("2.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address::from_string("3.0.0.0"), address::from_string("4.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address::from_string("5.0.0.0"), address::from_string("6.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address::from_string("7.0.0.0"), address::from_string("8.0.0.0"), ip_filter::blocked);
|
||||
|
||||
f.add_rule(address_v4::from_string("1.0.1.0"), address_v4::from_string("9.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address::from_string("1.0.1.0"), address::from_string("9.0.0.0"), ip_filter::blocked);
|
||||
|
||||
range = f.export_filter();
|
||||
range = boost::get<0>(f.export_filter());
|
||||
test_rules_invariant(range, f);
|
||||
|
||||
TEST_CHECK(range.size() == 3);
|
||||
ip_filter::ip_range expected[] =
|
||||
ip_range<address_v4> expected[] =
|
||||
{
|
||||
{address_v4::from_string("0.0.0.0"), address_v4::from_string("0.255.255.255"), 0}
|
||||
, {address_v4::from_string("1.0.0.0"), address_v4::from_string("9.0.0.0"), ip_filter::blocked}
|
||||
, {address_v4::from_string("9.0.0.1"), address_v4::from_string("255.255.255.255"), 0}
|
||||
};
|
||||
|
||||
TEST_CHECK(std::equal(range.begin(), range.end(), expected, &compare));
|
||||
TEST_CHECK(std::equal(range.begin(), range.end(), expected, &compare<address_v4>));
|
||||
|
||||
}
|
||||
|
||||
// **** test joining of multiple overlapping ranges 2 ****
|
||||
|
||||
{
|
||||
ip_filter f;
|
||||
f.add_rule(address_v4::from_string("1.0.0.0"), address_v4::from_string("2.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address_v4::from_string("3.0.0.0"), address_v4::from_string("4.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address_v4::from_string("5.0.0.0"), address_v4::from_string("6.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address_v4::from_string("7.0.0.0"), address_v4::from_string("8.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address::from_string("1.0.0.0"), address::from_string("2.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address::from_string("3.0.0.0"), address::from_string("4.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address::from_string("5.0.0.0"), address::from_string("6.0.0.0"), ip_filter::blocked);
|
||||
f.add_rule(address::from_string("7.0.0.0"), address::from_string("8.0.0.0"), ip_filter::blocked);
|
||||
|
||||
f.add_rule(address_v4::from_string("0.0.1.0"), address_v4::from_string("7.0.4.0"), ip_filter::blocked);
|
||||
|
||||
range = f.export_filter();
|
||||
f.add_rule(address::from_string("0.0.1.0"), address::from_string("7.0.4.0"), ip_filter::blocked);
|
||||
|
||||
range = boost::get<0>(f.export_filter());
|
||||
test_rules_invariant(range, f);
|
||||
|
||||
TEST_CHECK(range.size() == 3);
|
||||
ip_filter::ip_range expected[] =
|
||||
ip_range<address_v4> expected[] =
|
||||
{
|
||||
{address_v4::from_string("0.0.0.0"), address_v4::from_string("0.0.0.255"), 0}
|
||||
, {address_v4::from_string("0.0.1.0"), address_v4::from_string("8.0.0.0"), ip_filter::blocked}
|
||||
, {address_v4::from_string("8.0.0.1"), address_v4::from_string("255.255.255.255"), 0}
|
||||
};
|
||||
|
||||
TEST_CHECK(std::equal(range.begin(), range.end(), expected, &compare));
|
||||
TEST_CHECK(std::equal(range.begin(), range.end(), expected, &compare<address_v4>));
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in New Issue