diff --git a/Jamfile b/Jamfile index ac7199c6b..759904b46 100755 --- a/Jamfile +++ b/Jamfile @@ -16,9 +16,72 @@ if ! $(BOOST_ROOT) "BOOST_ROOT must be set to your boost installation path." ; } - use-project /boost : $(BOOST_ROOT) ; + +feature logging : none default verbose : composite propagated symmetric link-incompatible ; +feature.compose none : ; +feature.compose default : TORRENT_LOGGING ; +feature.compose verbose : TORRENT_VERBOSE_LOGGING ; + +feature dht-support : on off logging : composite propagated symmetric link-incompatible ; +feature.compose on : ; +feature.compose off : TORRENT_DISABLE_DHT ; +feature.compose logging : TORRENT_DHT_VERBOSE_LOGGING ; + +SOURCES = + allocate_resources.cpp + alert.cpp + entry.cpp + escape_string.cpp + file.cpp + identify_client.cpp + ip_filter.cpp + peer_connection.cpp + bt_peer_connection.cpp + web_peer_connection.cpp + piece_picker.cpp + policy.cpp + session.cpp + stat.cpp + storage.cpp + torrent.cpp + torrent_handle.cpp + torrent_info.cpp + tracker_manager.cpp + http_tracker_connection.cpp + udp_tracker_connection.cpp + sha1.cpp + ; + +KADEMLIA_SOURCES = + kademlia/closest_nodes.cpp + kademlia/dht_tracker.cpp + kademlia/node.cpp + kademlia/refresh.cpp + kademlia/rpc_manager.cpp + kademlia/find_data.cpp + kademlia/node_id.cpp + kademlia/routing_table.cpp + kademlia/traversal_algorithm.cpp + ; + +ZLIB_SOURCES = + adler32.c + compress.c + crc32.c + deflate.c + gzio.c + infback.c + inffast.c + inflate.c + inftrees.c + trees.c + uncompr.c + zutil.c + ; + + project torrent : requirements @@ -50,6 +113,8 @@ project torrent # are exported (GCC 4 and msvc) shared:TORRENT_BUILDING_SHARED + shared:TORRENT_LINKING_SHARED + : usage-requirements ./include @@ -60,56 +125,6 @@ project torrent ; -SOURCES = - allocate_resources.cpp - alert.cpp - entry.cpp - escape_string.cpp - file.cpp - identify_client.cpp - ip_filter.cpp - peer_connection.cpp - bt_peer_connection.cpp - web_peer_connection.cpp - piece_picker.cpp - policy.cpp - session.cpp - stat.cpp - storage.cpp - torrent.cpp - torrent_handle.cpp - torrent_info.cpp - tracker_manager.cpp - http_tracker_connection.cpp - udp_tracker_connection.cpp - sha1.cpp - - kademlia/closest_nodes.cpp - kademlia/dht_tracker.cpp - kademlia/node.cpp - kademlia/refresh.cpp - kademlia/rpc_manager.cpp - kademlia/find_data.cpp - kademlia/node_id.cpp - kademlia/routing_table.cpp - kademlia/traversal_algorithm.cpp - ; - -ZLIB_SOURCES = - adler32.c - compress.c - crc32.c - deflate.c - gzio.c - infback.c - inffast.c - inflate.c - inftrees.c - trees.c - uncompr.c - zutil.c - ; - LIBS = ; # some windows specific settings @@ -120,21 +135,23 @@ LIBS = ; LIBS += wsock32 ; } -feature logging : none default verbose : composite propagated symmetric link-incompatible ; -feature.compose none : ; -feature.compose default : TORRENT_LOGGING ; -feature.compose verbose : TORRENT_VERBOSE_LOGGING ; - -feature dht-support : on off logging : composite propagated symmetric link-incompatible ; -feature.compose on : ; -feature.compose off : TORRENT_DISABLE_DHT ; -feature.compose logging : TORRENT_DHT_VERBOSE_LOGGING ; - lib torrent : src/$(SOURCES) + src/$(KADEMLIA_SOURCES) zlib/$(ZLIB_SOURCES) $(LIBS) ; +# if DHT support is disabled, don't include the kademlia sources +lib torrent + : + src/$(SOURCES) + zlib/$(ZLIB_SOURCES) + $(LIBS) + : + off + ; + + diff --git a/docs/building.html b/docs/building.html index 360dbc19b..0d47b5d29 100644 --- a/docs/building.html +++ b/docs/building.html @@ -190,8 +190,40 @@ logging of the DHT protocol traffic. +link +
    +
  • static - builds libtorrent as a static +library (.a / .lib)
  • +
  • shared - builds libtorrent as a shared +library (.so / .dll).
  • +
+ + +runtime-link +
    +
  • static - links statically against the +run-time library (if available on your +platform).
  • +
  • shared - link dynamically against the +run-time library (default).
  • +
+ + +variant +
    +
  • debug - builds libtorrent with debug +information and invariant checks.
  • +
  • release - builds libtorrent in release mode +without invariant checks and with optimization.
  • +
  • profile - builds libtorrent with profile +information.
  • +
+ + +

The variant feature is implicit, which means you don't need to specify +the name of the feature, just the value.

The logs created when building vlog or log mode are put in a directory called libtorrent_logs in the current working directory.

When building the example client on windows, you need to build with @@ -217,13 +249,14 @@ needs to be generated first. If you're building from a released tarball, you may skip directly to Step 2: Running configure.

Execute the following commands, in the given order, to generate the build system:

-
    -
  • aclocal -I m4
  • -
  • autoheader
  • -
  • libtoolize --copy --force
  • -
  • automake --add-missing --copy --gnu
  • -
  • autoconf
  • -
+
+aclocal -I m4
+autoheader
+libtoolize --copy --force
+automake --add-missing --copy --gnu
+autoconf
+
+

On darwin/OSX you have to run glibtoolize instead of libtoolize.

Step 2: Running configure

diff --git a/docs/building.rst b/docs/building.rst index 76dcb871a..b891463af 100644 --- a/docs/building.rst +++ b/docs/building.rst @@ -187,6 +187,27 @@ Build features: | | logging of the DHT protocol traffic. | | | * ``off`` - build without DHT support. | +------------------------+----------------------------------------------------+ +| ``link`` | * ``static`` - builds libtorrent as a static | +| | library (.a / .lib) | +| | * ``shared`` - builds libtorrent as a shared | +| | library (.so / .dll). | ++------------------------+----------------------------------------------------+ +| ``runtime-link`` | * ``static`` - links statically against the | +| | run-time library (if available on your | +| | platform). | +| | * ``shared`` - link dynamically against the | +| | run-time library (default). | ++------------------------+----------------------------------------------------+ +| ``variant`` | * ``debug`` - builds libtorrent with debug | +| | information and invariant checks. | +| | * ``release`` - builds libtorrent in release mode | +| | without invariant checks and with optimization. | +| | * ``profile`` - builds libtorrent with profile | +| | information. | ++------------------------+----------------------------------------------------+ + +The ``variant`` feature is *implicit*, which means you don't need to specify +the name of the feature, just the value. The logs created when building vlog or log mode are put in a directory called ``libtorrent_logs`` in the current working directory. @@ -219,14 +240,15 @@ needs to be generated first. If you're building from a released tarball, you may skip directly to `Step 2: Running configure`_. Execute the following commands, in the given order, to generate -the build system: +the build system:: -* aclocal -I m4 -* autoheader -* libtoolize --copy --force -* automake --add-missing --copy --gnu -* autoconf + aclocal -I m4 + autoheader + libtoolize --copy --force + automake --add-missing --copy --gnu + autoconf +On darwin/OSX you have to run ``glibtoolize`` instead of ``libtoolize``. Step 2: Running configure ~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/manual.html b/docs/manual.html index 9f05a1321..4348a3405 100755 --- a/docs/manual.html +++ b/docs/manual.html @@ -25,138 +25,139 @@

Table of contents

@@ -186,6 +187,26 @@ the session, it conta

Each class and function is described in this manual.

+
+

primitive network types

+

There are a few typedefs in the libtorrent namespace which pulls +in network types from the asio namespace. These are:

+
+typedef asio::ip::address address;
+typedef asio::ip::address_v4 address_v4;
+typedef asio::ip::address_v6 address_v6;
+using asio::ip::tcp;
+using asio::ip::udp;
+
+

These are declared in the <libtorrent/socket.hpp> header.

+

The using statements will give easy access to:

+
+tcp::endpoint
+udp::endpoint
+
+

Which are the endpoint types used in libtorrent. An endpoint is an address +with an associated port.

+

session

The session class has the following synopsis:

@@ -1903,13 +1924,13 @@ public: enum access_flags { blocked = 1 }; ip_filter(); - void add_rule(address first, address last, int flags); - int access(address const& addr) const; + void add_rule(address_v4 first, address_v4 last, int flags); + int access(address_v4 const& addr) const; struct ip_range { - address first; - address last; + address_v4 first; + address_v4 last; int flags; }; @@ -1932,7 +1953,7 @@ ip_filter()

add_rule()

-void add_rule(address first, address last, int flags);
+void add_rule(address_v4 first, address_v4 last, int flags);
 

Adds a rule to the filter. first and last defines a range of @@ -1948,7 +1969,7 @@ precedence.

access()

-int access(address const& addr) const;
+int access(address_v4 const& addr) const;
 

Returns the access permissions for the given address (addr). The permission @@ -2651,7 +2672,10 @@ layout:

ip -string, the ip address of the peer. +string, the ip address of the peer. This is +not a binary representation of the ip +address, but the string representation. It +may be an IPv6 string or an IPv4 string. port integer, the listen port of the peer diff --git a/docs/manual.rst b/docs/manual.rst index 71005616e..d608edb96 100755 --- a/docs/manual.rst +++ b/docs/manual.rst @@ -31,7 +31,27 @@ The basic usage is as follows: Each class and function is described in this manual. +primitive network types +======================= +There are a few typedefs in the ``libtorrent`` namespace which pulls +in network types from the ``asio`` namespace. These are:: + + typedef asio::ip::address address; + typedef asio::ip::address_v4 address_v4; + typedef asio::ip::address_v6 address_v6; + using asio::ip::tcp; + using asio::ip::udp; + +These are declared in the ```` header. + +The ``using`` statements will give easy access to:: + + tcp::endpoint + udp::endpoint + +Which are the endpoint types used in libtorrent. An endpoint is an address +with an associated port. session ======= @@ -1898,13 +1918,13 @@ accessed as ``libtorrent::address``. enum access_flags { blocked = 1 }; ip_filter(); - void add_rule(address first, address last, int flags); - int access(address const& addr) const; + void add_rule(address_v4 first, address_v4 last, int flags); + int access(address_v4 const& addr) const; struct ip_range { - address first; - address last; + address_v4 first; + address_v4 last; int flags; }; @@ -1930,7 +1950,7 @@ add_rule() :: - void add_rule(address first, address last, int flags); + void add_rule(address_v4 first, address_v4 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`` @@ -1949,7 +1969,7 @@ access() :: - int access(address const& addr) const; + int access(address_v4 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 @@ -2737,7 +2757,10 @@ The file format is a bencoded dictionary containing the following fields: | | layout: | | | | | | +----------+-----------------------------------------------+ | -| | | ``ip`` | string, the ip address of the peer. | | +| | | ``ip`` | string, the ip address of the peer. This is | | +| | | | not a binary representation of the ip | | +| | | | address, but the string representation. It | | +| | | | may be an IPv6 string or an IPv4 string. | | | | +----------+-----------------------------------------------+ | | | | ``port`` | integer, the listen port of the peer | | | | +----------+-----------------------------------------------+ | diff --git a/examples/client_test.cpp b/examples/client_test.cpp index 86cee60ba..061a3af30 100755 --- a/examples/client_test.cpp +++ b/examples/client_test.cpp @@ -566,6 +566,7 @@ int main(int ac, char* av[]) handles_t handles; session ses; +#ifndef TORRENT_DISABLE_DHT boost::filesystem::ifstream dht_state_file(".dht_state" , std::ios_base::binary); dht_state_file.unsetf(std::ios_base::skipws); @@ -582,6 +583,7 @@ int main(int ac, char* av[]) ses.add_dht_node(std::make_pair(std::string("router.bittorrent.com") , 6881)); } +#endif ses.set_max_half_open_connections(half_open_limit); ses.set_download_rate_limit(download_limit); @@ -631,9 +633,9 @@ int main(int ac, char* av[]) int a, b, c, d; char dummy; in >> a >> dummy >> b >> dummy >> c >> dummy >> d >> dummy; - address 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; - address last((a << 24) + (b << 16) + (c << 8) + d); + address_v4 last((a << 24) + (b << 16) + (c << 8) + d); int flags; in >> flags; if (flags <= 127) flags = ip_filter::blocked; @@ -932,11 +934,13 @@ int main(int ac, char* av[]) } } +#ifndef TORRENT_DISABLE_DHT entry dht_state = ses.dht_state(); boost::filesystem::ofstream out(".dht_state" , std::ios_base::binary); out.unsetf(std::ios_base::skipws); bencode(std::ostream_iterator(out), dht_state); +#endif } catch (std::exception& e) { diff --git a/include/libtorrent/ip_filter.hpp b/include/libtorrent/ip_filter.hpp index ed6b655fc..43229f181 100644 --- a/include/libtorrent/ip_filter.hpp +++ b/include/libtorrent/ip_filter.hpp @@ -57,13 +57,13 @@ public: }; ip_filter(); - void add_rule(address first, address last, int flags); - int access(address const& addr) const; + void add_rule(address_v4 first, address_v4 last, int flags); + int access(address_v4 const& addr) const; struct ip_range { - address first; - address last; + address_v4 first; + address_v4 last; int flags; }; @@ -74,12 +74,12 @@ public: private: struct range { - range(address addr, int access = 0): start(addr), access(access) {} + 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 start; + address_v4 start; // the end of the range is implicit // and given by the next entry in the set int access; diff --git a/include/libtorrent/socket.hpp b/include/libtorrent/socket.hpp index 4ab066e71..394c2a133 100755 --- a/include/libtorrent/socket.hpp +++ b/include/libtorrent/socket.hpp @@ -82,7 +82,9 @@ namespace libtorrent using asio::ip::tcp; using asio::ip::udp; typedef asio::ip::tcp::socket stream_socket; - typedef asio::ip::address_v4 address; + typedef asio::ip::address address; + typedef asio::ip::address_v4 address_v4; + typedef asio::ip::address_v6 address_v6; typedef asio::ip::udp::socket datagram_socket; typedef asio::ip::tcp::acceptor socket_acceptor; typedef asio::io_service demuxer; @@ -92,19 +94,60 @@ namespace libtorrent namespace detail { + template + void write_address(address const& a, OutIt& out) + { + if (a.is_v4()) + { + write_uint32(a.to_v4().to_ulong(), out); + } + else if (a.is_v6()) + { + asio::ip::address_v6::bytes_type bytes + = a.to_v6().to_bytes(); + std::copy(bytes.begin(), bytes.end(), out); + } + } + + template + address read_v4_address(InIt& in) + { + unsigned long ip = read_uint32(in); + return asio::ip::address_v4(ip); + } + + template + address read_v6_address(InIt& in) + { + typedef asio::ip::address_v6::bytes_type bytes_t; + bytes_t bytes; + for (bytes_t::iterator i = bytes.begin() + , end(bytes.end()); i != end; ++i) + *i = read_uint8(in); + return asio::ip::address_v6(bytes); + } + template void write_endpoint(Endpoint const& e, OutIt& out) { - write_uint32(e.address().to_v4().to_ulong(), out); + write_address(e.address(), out); write_uint16(e.port(), out); } template - Endpoint read_endpoint(InIt& in) + Endpoint read_v4_endpoint(InIt& in) { - unsigned int ip = read_uint32(in); + address addr = read_v4_address(in); int port = read_uint16(in); - return Endpoint(address(ip), port); + return Endpoint(addr, port); + } + + template + Endpoint read_v6_endpoint(InIt& in) + { + address addr = read_v6_address(in); + int port = read_uint16(in); + return Endpoint(addr, port); } } } diff --git a/src/ip_filter.cpp b/src/ip_filter.cpp index 899a11097..a6b3bde87 100644 --- a/src/ip_filter.cpp +++ b/src/ip_filter.cpp @@ -41,10 +41,10 @@ namespace libtorrent ip_filter::ip_filter() { // make the entire ip-range non-blocked - m_access_list.insert(range(address(0UL), 0)); + m_access_list.insert(range(address_v4(0UL), 0)); } - void ip_filter::add_rule(address first, address last, int flags) + void ip_filter::add_rule(address_v4 first, address_v4 last, int flags) { using boost::next; using boost::prior; @@ -80,7 +80,7 @@ namespace libtorrent { // we can do this const-cast because we know that the new // start address will keep the set correctly ordered - const_cast(i->start) = first; + const_cast(i->start) = first; const_cast(i->access) = flags; } else if (first_access != flags) @@ -93,14 +93,14 @@ namespace libtorrent { 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(last.to_ulong() + 1), last_access)); + 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()); } - int ip_filter::access(address const& addr) const + int ip_filter::access(address_v4 const& addr) const { assert(!m_access_list.empty()); range_t::const_iterator i = m_access_list.upper_bound(addr); @@ -126,9 +126,9 @@ namespace libtorrent ++i; if (i == end) - r.last = address(0xffffffff); + r.last = address_v4(0xffffffff); else - r.last = address(i->start.to_ulong() - 1); + r.last = address_v4(i->start.to_ulong() - 1); ret.push_back(r); } diff --git a/src/kademlia/dht_tracker.cpp b/src/kademlia/dht_tracker.cpp index ecf4491db..96df9a3cf 100644 --- a/src/kademlia/dht_tracker.cpp +++ b/src/kademlia/dht_tracker.cpp @@ -105,7 +105,6 @@ namespace } } - namespace libtorrent { namespace dht { #ifdef TORRENT_DHT_VERBOSE_LOGGING @@ -164,12 +163,20 @@ namespace libtorrent { namespace dht { if (entry const* nodes = bootstrap.find_key("nodes")) { - if (nodes->type() == entry::string_t) + if (nodes->type() == entry::list_t) { - std::string const& s = nodes->string(); - std::string::const_iterator in(s.begin()); - while (std::distance(in, s.end()) >= 6) - initial_nodes.push_back(read_endpoint(in)); + entry::list_type const& node_list = nodes->list(); + for (entry::list_type::const_iterator i = node_list.begin() + , end(node_list.end()); i != end; ++i) + { + if (i->type() != entry::string_t) continue; + std::string const& str = i->string(); + std::string::const_iterator in(str.begin()); + if (str.length() == 6) + initial_nodes.push_back(read_v4_endpoint(in)); + else if (str.length() == 18) + initial_nodes.push_back(read_v6_endpoint(in)); + } } } } @@ -430,7 +437,10 @@ namespace libtorrent { namespace dht std::string const& p = i->string(); if (p.size() < 6) continue; std::string::const_iterator in = p.begin(); - m.peers.push_back(read_endpoint(in)); + if (p.size() == 6) + m.peers.push_back(read_v4_endpoint(in)); + else if (p.size() == 18) + m.peers.push_back(read_v6_endpoint(in)); } #ifdef TORRENT_DHT_VERBOSE_LOGGING TORRENT_LOG(dht_tracker) << " peers: " << m.peers.size(); @@ -450,7 +460,7 @@ namespace libtorrent { namespace dht std::copy(i, i + 20, id.begin()); i += 20; m.nodes.push_back(libtorrent::dht::node_entry( - id, read_endpoint(i))); + id, read_v4_endpoint(i))); } #ifdef TORRENT_DHT_VERBOSE_LOGGING TORRENT_LOG(dht_tracker) << " nodes: " << m.nodes.size(); @@ -575,17 +585,26 @@ namespace libtorrent { namespace dht { entry ret(entry::dictionary_t); { - std::string nodes; - std::back_insert_iterator out(nodes); + entry nodes(entry::list_t); for (node_impl::iterator i(m_dht.begin()) , end(m_dht.end()); i != end; ++i) + { + std::string node; + std::back_insert_iterator out(node); write_endpoint(i->addr, out); + nodes.list().push_back(entry(node)); + } bucket_t cache; m_dht.replacement_cache(cache); for (bucket_t::iterator i(cache.begin()) , end(cache.end()); i != end; ++i) + { + std::string node; + std::back_insert_iterator out(node); write_endpoint(i->addr, out); - if (!nodes.empty()) + nodes.list().push_back(entry(node)); + } + if (!nodes.list().empty()) ret["nodes"] = nodes; } diff --git a/src/policy.cpp b/src/policy.cpp index f14a7c346..7e5fff49f 100755 --- a/src/policy.cpp +++ b/src/policy.cpp @@ -946,7 +946,7 @@ namespace libtorrent INVARIANT_CHECK; // just ignore the obviously invalid entries from the tracker - if(remote.address() == address(0) || remote.port() == 0) + if(remote.address() == address() || remote.port() == 0) return; try diff --git a/src/session.cpp b/src/session.cpp index 9eed09ff6..b408055a8 100755 --- a/src/session.cpp +++ b/src/session.cpp @@ -651,7 +651,8 @@ namespace libtorrent { namespace detail #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) (*m_logger) << endp << " <== INCOMING CONNECTION\n"; #endif - if (m_ip_filter.access(endp.address().to_v4()) & ip_filter::blocked) + if (endp.address().is_v4() + && (m_ip_filter.access(endp.address().to_v4()) & ip_filter::blocked)) { #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) (*m_logger) << "filtered blocked ip\n"; @@ -1153,8 +1154,9 @@ namespace libtorrent = m_impl.m_connections.begin(); i != m_impl.m_connections.end();) { tcp::endpoint sender = i->first->remote_endpoint(); - if (m_impl.m_ip_filter.access(sender.address().to_v4()) - & ip_filter::blocked) + if (sender.address().is_v4() + && (m_impl.m_ip_filter.access(sender.address().to_v4()) + & ip_filter::blocked)) { #if defined(TORRENT_VERBOSE_LOGGING) (*i->second->m_logger) << "*** CONNECTION FILTERED'\n"; diff --git a/src/torrent.cpp b/src/torrent.cpp index 5519cb2be..6ca22809d 100755 --- a/src/torrent.cpp +++ b/src/torrent.cpp @@ -549,7 +549,9 @@ namespace libtorrent tcp::endpoint a(address::from_string(i->ip), i->port); - if (m_ses.m_ip_filter.access(a.address().to_v4()) == ip_filter::blocked) + if (a.address().is_v4() + && (m_ses.m_ip_filter.access(a.address().to_v4()) + & ip_filter::blocked)) { #if defined(TORRENT_VERBOSE_LOGGING) || defined(TORRENT_LOGGING) debug_log("blocked ip from tracker: " + i->ip);