deleted file mode 100644
@@ -1,44 +0,0 @@
-From c2b119de0e66fb047bb20e445ac8e25824448858 Mon Sep 17 00:00:00 2001
-From: chros <chros@chrosGX620>
-Date: Sun, 30 Jul 2017 20:34:47 +0100
-Subject: [PATCH] Fix compilation issue with gcc v6.x and empty CXXFLAGS (See
- #10)
-
----
- configure.ac | 1 +
- scripts/rak_compiler.m4 | 13 +++++++++++++
- 2 files changed, 14 insertions(+)
-
-diff --git a/configure.ac b/configure.ac
-index 65e34872..2f29e3f9 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -28,6 +28,7 @@ AC_C_BIGENDIAN(
- AC_MSG_ERROR([Could not determine endianness])
- )
-
-+RAK_CHECK_CXXFLAGS
- RAK_ENABLE_DEBUG
- RAK_ENABLE_EXTRA_DEBUG
- RAK_ENABLE_WERROR
-diff --git a/scripts/rak_compiler.m4 b/scripts/rak_compiler.m4
-index 39bd19a7..87871abf 100644
---- a/scripts/rak_compiler.m4
-+++ b/scripts/rak_compiler.m4
-@@ -1,3 +1,16 @@
-+AC_DEFUN([RAK_CHECK_CXXFLAGS], [
-+
-+ AC_MSG_CHECKING([for user-defined CXXFLAGS])
-+
-+ if test -n "$CXXFLAGS"; then
-+ AC_MSG_RESULT([user-defined "$CXXFLAGS"])
-+ else
-+ CXXFLAGS="-O2"
-+ AC_MSG_RESULT([default "$CXXFLAGS"])
-+ fi
-+])
-+
-+
- AC_DEFUN([RAK_ENABLE_DEBUG], [
- AC_ARG_ENABLE(debug,
- AC_HELP_STRING([--enable-debug], [enable debug information [[default=yes]]]),
deleted file mode 100644
@@ -1,56 +0,0 @@
-From 8229218dff1105e9fb2bb2c7510910a0db98f3ef Mon Sep 17 00:00:00 2001
-From: chros <chros@chrosGX620>
-Date: Wed, 2 Aug 2017 12:48:27 +0100
-Subject: [PATCH] Modfiy gcc v6.x fix for empty CXXFLAGS (See #10)
-
----
- configure.ac | 1 +
- scripts/rak_compiler.m4 | 21 +++++++++++++++++----
- 2 files changed, 18 insertions(+), 4 deletions(-)
-
-diff --git a/configure.ac b/configure.ac
-index 2f29e3f9..a6df6b80 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -28,6 +28,7 @@ AC_C_BIGENDIAN(
- AC_MSG_ERROR([Could not determine endianness])
- )
-
-+RAK_CHECK_CFLAGS
- RAK_CHECK_CXXFLAGS
- RAK_ENABLE_DEBUG
- RAK_ENABLE_EXTRA_DEBUG
-diff --git a/scripts/rak_compiler.m4 b/scripts/rak_compiler.m4
-index 87871abf..9a361bed 100644
---- a/scripts/rak_compiler.m4
-+++ b/scripts/rak_compiler.m4
-@@ -1,12 +1,25 @@
-+AC_DEFUN([RAK_CHECK_CFLAGS], [
-+
-+ AC_MSG_CHECKING([for user-defined CFLAGS])
-+
-+ if test "$CFLAGS" = ""; then
-+ unset CFLAGS
-+ AC_MSG_RESULT([undefined])
-+ else
-+ AC_MSG_RESULT([user-defined "$CFLAGS"])
-+ fi
-+])
-+
-+
- AC_DEFUN([RAK_CHECK_CXXFLAGS], [
-
- AC_MSG_CHECKING([for user-defined CXXFLAGS])
-
-- if test -n "$CXXFLAGS"; then
-- AC_MSG_RESULT([user-defined "$CXXFLAGS"])
-+ if test "$CXXFLAGS" = ""; then
-+ unset CXXFLAGS
-+ AC_MSG_RESULT([undefined])
- else
-- CXXFLAGS="-O2"
-- AC_MSG_RESULT([default "$CXXFLAGS"])
-+ AC_MSG_RESULT([user-defined "$CXXFLAGS"])
- fi
- ])
-
deleted file mode 100644
@@ -1,27 +0,0 @@
-From 48635a0fdb06b8572809dc54c630109db1e6e85c Mon Sep 17 00:00:00 2001
-From: Matt Traudt <sirmatt@ksu.edu>
-Date: Mon, 20 Nov 2017 15:22:51 -0500
-Subject: [PATCH] Add space to fmt str in log_gz_file_write
-
-Without this space, the log level identifier ('D', 'I', etc.)
-would be right next to actual content.
-
-Before: <timestamp> Depoll->pcb(17): Open event.
-After: <timestamp> D epoll->pcb(17): Open event.
----
- src/torrent/utils/log.cc | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/torrent/utils/log.cc b/src/torrent/utils/log.cc
-index 646d36e3..58b563a6 100644
---- a/src/torrent/utils/log.cc
-+++ b/src/torrent/utils/log.cc
-@@ -381,7 +381,7 @@ log_gz_file_write(std::shared_ptr<log_gz_output>& outfile, const char* data, siz
-
- // Normal groups are nul-terminated strings.
- if (group >= 0) {
-- const char* fmt = (group >= LOG_NON_CASCADING) ? ("%" PRIi32 " ") : ("%" PRIi32 " %c");
-+ const char* fmt = (group >= LOG_NON_CASCADING) ? ("%" PRIi32 " ") : ("%" PRIi32 " %c ");
-
- int buffer_length = snprintf(buffer, 64, fmt,
- cachedTime.seconds(),
deleted file mode 100644
@@ -1,379 +0,0 @@
-From facd1b78071e315a2e5ee4992d3545dae4290e07 Mon Sep 17 00:00:00 2001
-From: chros <chros@chrosGX620>
-Date: Sun, 10 Dec 2017 18:51:32 +0000
-Subject: [PATCH] IPv4 filter enhancement #11IPv4 filter enhancement (Closes
- #11)
-
----
- src/torrent/peer/peer_list.cc | 23 ++-
- src/torrent/peer/peer_list.h | 2 +-
- src/torrent/utils/extents.h | 267 ++++++++++++++--------------------
- 3 files changed, 134 insertions(+), 158 deletions(-)
-
-diff --git a/src/torrent/peer/peer_list.cc b/src/torrent/peer/peer_list.cc
-index 23ca651a..aa60939a 100644
---- a/src/torrent/peer/peer_list.cc
-+++ b/src/torrent/peer/peer_list.cc
-@@ -146,7 +146,11 @@ PeerList::insert_address(const sockaddr* sa, int flags) {
-
- PeerInfo* peerInfo = new PeerInfo(sa);
- peerInfo->set_listen_port(address->port());
-- peerInfo->set_flags(m_ipv4_table.at(address->sa_inet()->address_h()) & PeerInfo::mask_ip_table);
-+ uint32_t host_byte_order_ipv4_addr = address->sa_inet()->address_h();
-+
-+ // IPv4 addresses stored in host byte order in ipv4_table so they are comparable. ntohl has been called
-+ if(m_ipv4_table.defined(host_byte_order_ipv4_addr))
-+ peerInfo->set_flags(m_ipv4_table.at(host_byte_order_ipv4_addr) & PeerInfo::mask_ip_table);
-
- manager->client_list()->retrieve_unknown(&peerInfo->mutable_client_info());
-
-@@ -264,12 +268,25 @@ PeerList::connected(const sockaddr* sa, int flags) {
- !socket_address_key::is_comparable_sockaddr(sa))
- return NULL;
-
-- int filter_value = m_ipv4_table.at(address->sa_inet()->address_h());
-+ uint32_t host_byte_order_ipv4_addr = address->sa_inet()->address_h();
-+ int filter_value = 0;
-+
-+ // IPv4 addresses stored in host byte order in ipv4_table so they are comparable. ntohl has been called
-+ if(m_ipv4_table.defined(host_byte_order_ipv4_addr))
-+ filter_value = m_ipv4_table.at(host_byte_order_ipv4_addr);
-
- // We should also remove any PeerInfo objects already for this
- // address.
-- if ((filter_value & PeerInfo::flag_unwanted))
-+ if ((filter_value & PeerInfo::flag_unwanted)) {
-+ char ipv4_str[INET_ADDRSTRLEN];
-+ uint32_t net_order_addr = htonl(host_byte_order_ipv4_addr);
-+
-+ inet_ntop(AF_INET, &net_order_addr, ipv4_str, INET_ADDRSTRLEN);
-+
-+ lt_log_print(LOG_PEER_INFO, "Peer %s is unwanted: preventing connection", ipv4_str);
-+
- return NULL;
-+ }
-
- PeerInfo* peerInfo;
- range_type range = base_type::equal_range(sock_key);
-diff --git a/src/torrent/peer/peer_list.h b/src/torrent/peer/peer_list.h
-index a3b409cb..4c2f707d 100644
---- a/src/torrent/peer/peer_list.h
-+++ b/src/torrent/peer/peer_list.h
-@@ -46,7 +46,7 @@ namespace torrent {
-
- class DownloadInfo;
-
--typedef extents<uint32_t, int, 32, 256, 8> ipv4_table;
-+typedef extents<uint32_t, int> ipv4_table;
-
- class LIBTORRENT_EXPORT PeerList : private std::multimap<socket_address_key, PeerInfo*> {
- public:
-diff --git a/src/torrent/utils/extents.h b/src/torrent/utils/extents.h
-index 8ec1e600..c2b887b1 100644
---- a/src/torrent/utils/extents.h
-+++ b/src/torrent/utils/extents.h
-@@ -37,191 +37,150 @@
- #ifndef LIBTORRENT_UTILS_EXTENTS_H
- #define LIBTORRENT_UTILS_EXTENTS_H
-
--#include lt_tr1_array
-
--#include <algorithm>
-+#include <map>
-+#include <stdexcept>
-
- namespace torrent {
-
--template <typename Key, typename Tp, unsigned int TableSize, unsigned int TableBits>
--struct extents_base {
-- typedef Key key_type;
-- typedef std::pair<Key, Key> range_type;
-- typedef std::pair<extents_base*, Tp> mapped_type;
-- typedef Tp mapped_value_type;
--
-- typedef std::array<mapped_type, TableSize> table_type;
--
-- extents_base(key_type pos, unsigned int mb, mapped_value_type val);
-- extents_base(extents_base* parent, typename table_type::const_iterator itr);
-- ~extents_base();
--
-- bool is_divisible(key_type key) const { return key % mask_bits == 0; }
-- bool is_leaf_branch() const { return mask_bits == 0; }
-- bool is_equal_range(key_type first, key_type last, const mapped_value_type& val) const;
--
-- unsigned int sizeof_data() const;
--
-- typename table_type::iterator partition_at(key_type key) { return table.begin() + ((key >> mask_bits) & (TableSize - 1)); }
-- typename table_type::const_iterator partition_at(key_type key) const { return table.begin() + ((key >> mask_bits) & (TableSize - 1)); }
--
-- unsigned int mask_distance(unsigned int mb) { return (~(~key_type() << mb) >> mask_bits); }
--
-- key_type partition_pos(typename table_type::const_iterator part) const { return position + (std::distance(table.begin(), part) << mask_bits); }
--
-- void insert(key_type pos, unsigned int mb, const mapped_value_type& val);
--
-- const mapped_value_type& at(key_type key) const;
--
-- unsigned int mask_bits;
-- key_type position;
-- table_type table;
--};
--
--template <typename Key, typename Tp, unsigned int MaskBits, unsigned int TableSize, unsigned int TableBits>
--class extents : private extents_base<Key, Tp, TableSize, TableBits> {
-+template <class Address, class Value, class Compare=std::less<Address> >
-+class extents {
- public:
-- typedef extents_base<Key, Tp, TableSize, TableBits> base_type;
--
-- typedef typename base_type::key_type key_type;
-- typedef base_type value_type;
-- typedef typename base_type::range_type range_type;
-- typedef typename base_type::mapped_type mapped_type;
-- typedef typename base_type::mapped_value_type mapped_value_type;
-- typedef typename base_type::table_type table_type;
--
-- static const key_type mask_bits = MaskBits;
-- static const key_type table_bits = TableBits;
-- static const key_type table_size = TableSize;
--
-- using base_type::at;
-- using base_type::sizeof_data;
-+ typedef Address key_type; // start address
-+ typedef Value mapped_value_type; // The value mapped to the ip range
-+ typedef std::pair<Address, Value> mapped_type; // End address, value mapped to ip range
-+ typedef std::map<key_type, mapped_type, Compare> range_map_type; // The map itself
-
- extents();
-+ ~extents();
-
-- bool is_equal_range(key_type first, key_type last, const mapped_value_type& val) const;
--
-- void insert(key_type pos, unsigned int mb, const mapped_value_type& val);
-+ void insert(key_type address_start, key_type address_end, mapped_value_type value);
-+ bool defined(key_type address_start, key_type address_end);
-+ bool defined(key_type address);
-+ key_type get_matching_key(key_type address_start, key_type address_end); // throws error on not defined. test with defined()
-+ mapped_value_type at(key_type address_start, key_type address_end); // throws error on not defined. test with defined()
-+ mapped_value_type at(key_type address); // throws error on not defined. test with defined()
-+ unsigned int sizeof_data() const;
-
-- base_type* data() { return this; }
-+ range_map_type range_map;
- };
-
--template <typename Key, typename Tp, unsigned int TableSize, unsigned int TableBits>
--extents_base<Key, Tp, TableSize, TableBits>::extents_base(key_type pos, unsigned int mb, mapped_value_type val) :
-- mask_bits(mb), position(pos) {
-- std::fill(table.begin(), table.end(), mapped_type(NULL, mapped_value_type()));
-+///////////////////////////////////////
-+// CONSTRUCTOR [PLACEHOLDER]
-+///////////////////////////////////////
-+template <class Address, class Value, class Compare >
-+extents<Address, Value, Compare>::extents() {
-+ //nothing to do
-+ return;
- }
-
--template <typename Key, typename Tp, unsigned int TableSize, unsigned int TableBits>
--extents_base<Key, Tp, TableSize, TableBits>::extents_base(extents_base* parent, typename table_type::const_iterator itr) :
-- mask_bits(parent->mask_bits - TableBits), position(parent->partition_pos(itr)) {
-- std::fill(table.begin(), table.end(), mapped_type(NULL, itr->second));
-+///////////////////////////////////////
-+// DESTRUCTOR [PLACEHOLDER]
-+///////////////////////////////////////
-+template <class Address, class Value, class Compare >
-+extents<Address, Value, Compare>::~extents() {
-+ //nothing to do. map destructor can handle cleanup.
-+ return;
- }
-
--template <typename Key, typename Tp, unsigned int MaskBits, unsigned int TableSize, unsigned int TableBits>
--extents<Key, Tp, MaskBits, TableSize, TableBits>::extents() :
-- base_type(key_type(), mask_bits - table_bits, mapped_value_type())
--{
--}
-+//////////////////////////////////////////////////////////////////////////////////
-+// INSERT O(log N) assuming no overlapping ranges
-+/////////////////////////////////////////////////////////////////////////////////
-+template <class Address, class Value, class Compare >
-+void extents<Address, Value, Compare>::insert(key_type address_start, key_type address_end, mapped_value_type value) {
-+ //we allow overlap ranges though not 100% overlap but only if mapped values are the same. first remove any overlap range that has a different value.
-+ typename range_map_type::iterator iter = range_map.upper_bound(address_start);
-+ if( iter != range_map.begin() ) { iter--; }
-+ bool ignore_due_to_total_overlap = false;
-+ while( iter->first <= address_end && iter != range_map.end() ) {
-+ key_type delete_key = iter->first;
-+ bool do_delete_due_to_overlap = iter->first <= address_end && (iter->second).first >= address_start && (iter->second).second != value;
-+ bool do_delete_due_to_total_overlap = address_start <= iter->first && address_end >= (iter->second).first;
-+ iter++;
-+ if(do_delete_due_to_overlap || do_delete_due_to_total_overlap) {
-+ range_map.erase (delete_key);
-+ }
-+ else {
-+ ignore_due_to_total_overlap = ignore_due_to_total_overlap || ( iter->first <= address_start && (iter->second).first >= address_end );
-+ }
-+ }
-
--template <typename Key, typename Tp, unsigned int TableSize, unsigned int TableBits>
--extents_base<Key, Tp, TableSize, TableBits>::~extents_base() {
-- for (typename table_type::const_iterator itr = table.begin(), last = table.end(); itr != last; itr++)
-- delete itr->first;
-+ if(!ignore_due_to_total_overlap) {
-+ mapped_type entry;
-+ entry.first = address_end;
-+ entry.second = value;
-+ range_map.insert( std::pair<key_type,mapped_type>(address_start, entry) );
-+ }
- }
-
--template <typename Key, typename Tp, unsigned int TableSize, unsigned int TableBits>
--unsigned int
--extents_base<Key, Tp, TableSize, TableBits>::sizeof_data() const {
-- unsigned int sum = sizeof(*this);
--
-- for (typename table_type::const_iterator itr = table.begin(), last = table.end(); itr != last; itr++)
-- if (itr->first != NULL)
-- sum += itr->first->sizeof_data();
--
-- return sum;
-+//////////////////////////////////////////////////////////////////////
-+// DEFINED O(log N) assuming no overlapping ranges
-+//////////////////////////////////////////////////////////////////////
-+template <class Address, class Value, class Compare >
-+bool extents<Address, Value, Compare>::defined(key_type address_start, key_type address_end) {
-+ bool defined = false;
-+ typename range_map_type::iterator iter = range_map.upper_bound(address_start);
-+ if( iter != range_map.begin() ) { iter--; }
-+ while( iter->first <= address_end && !defined && iter != range_map.end() ) {
-+ defined = iter->first <= address_end && (iter->second).first >= address_start;
-+ iter++;
-+ }
-+ return defined;
- }
--
--template <typename Key, typename Tp, unsigned int MaskBits, unsigned int TableSize, unsigned int TableBits>
--void
--extents<Key, Tp, MaskBits, TableSize, TableBits>::insert(key_type pos, unsigned int mb, const mapped_value_type& val) {
-- key_type mask = ~key_type() << mb;
--
-- base_type::insert(pos & mask, mb, val);
-+template <class Address, class Value, class Compare >
-+bool extents<Address, Value, Compare>::defined(key_type address) {
-+ return defined(address, address);
- }
-
--template <typename Key, typename Tp, unsigned int TableSize, unsigned int TableBits>
--void
--extents_base<Key, Tp, TableSize, TableBits>::insert(key_type pos, unsigned int mb, const mapped_value_type& val) {
-- // RESTRICTED
-- typename table_type::iterator first = partition_at(pos);
-- typename table_type::iterator last = partition_at(pos) + mask_distance(mb) + 1;
--
-- if (mb < mask_bits) {
-- if (first->first == NULL)
-- first->first = new extents_base(this, first);
-+//////////////////////////////////////////////////////////////////////
-+// GET_MATCHING_KEY O(log N) assuming no overlapping ranges
-+//////////////////////////////////////////////////////////////////////
-+template <class Address, class Value, class Compare >
-+typename extents<Address, Value, Compare>::key_type extents<Address, Value, Compare>::get_matching_key(key_type address_start, key_type address_end) {
-+ key_type key;
-+ bool defined = false;
-+ typename range_map_type::iterator iter = range_map.upper_bound(address_start);
-+ if( iter != range_map.begin() ) { iter--; }
-+ while( iter->first <= address_end && !defined && iter != range_map.end() ) {
-+ defined = iter->first <= address_end && (iter->second).first >= address_start;
-+ if(defined)
-+ key = iter->first;
-
-- first->first->insert(pos, mb, val);
-- return;
-+ iter++;
- }
--
-- while (first != last) {
-- if (first->first != NULL) {
-- delete first->first;
-- first->first = NULL;
-- }
--
-- (first++)->second = val;
-+ // this will cause exception to be thrown
-+ if(!defined) {
-+ std::out_of_range e("nothing defined for specified key");
-+ throw e;
- }
-+ return key;
- }
-
--template <typename Key, typename Tp, unsigned int MaskBits, unsigned int TableSize, unsigned int TableBits>
--bool
--extents<Key, Tp, MaskBits, TableSize, TableBits>::is_equal_range(key_type first, key_type last, const mapped_value_type& val) const {
-- // RESTRICTED
-- first = std::max(first, key_type());
-- last = std::min(last, key_type() + (~key_type() >> (sizeof(key_type) * 8 - MaskBits)));
--
-- if (first <= last)
-- return base_type::is_equal_range(first, last, val);
-- else
-- return true;
-+//////////////////////////////////////////////////////////////////////
-+// AT O(log N) assuming no overlapping ranges
-+//////////////////////////////////////////////////////////////////////
-+template <class Address, class Value, class Compare >
-+typename extents<Address, Value, Compare>::mapped_value_type extents<Address, Value, Compare>::at(key_type address_start, key_type address_end) {
-+ key_type key = get_matching_key(address_start, address_end);
-+ mapped_type entry = range_map.at(key);
-+ return entry.second;
- }
--
--template <typename Key, typename Tp, unsigned int TableSize, unsigned int TableBits>
--bool
--extents_base<Key, Tp, TableSize, TableBits>::is_equal_range(key_type key_first, key_type key_last, const mapped_value_type& val) const {
-- // RESTRICTED
-- typename table_type::const_iterator first = partition_at(key_first);
-- typename table_type::const_iterator last = partition_at(key_last) + 1;
--
-- do {
-- // std::cout << "shift_amount " << key_first << ' ' << key_last << std::endl;
--
-- if (first->first == NULL && val != first->second)
-- return false;
--
-- if (first->first != NULL && !first->first->is_equal_range(std::max(key_first, partition_pos(first)),
-- std::min(key_last, partition_pos(first + 1) - 1), val))
-- return false;
--
-- } while (++first != last);
--
-- return true;
-+template <class Address, class Value, class Compare >
-+typename extents<Address, Value, Compare>::mapped_value_type extents<Address, Value, Compare>::at(key_type address) {
-+ return at(address, address);
- }
-
--// Assumes 'key' is within the range of the range.
--template <typename Key, typename Tp, unsigned int TableSize, unsigned int TableBits>
--const typename extents_base<Key, Tp, TableSize, TableBits>::mapped_value_type&
--extents_base<Key, Tp, TableSize, TableBits>::at(key_type key) const {
-- typename table_type::const_iterator itr = partition_at(key);
--
-- while (itr->first != NULL)
-- itr = itr->first->partition_at(key);
--
-- return itr->second;
-+//////////////////////////////////////////////////////////////////////
-+// SIZEOF_DATA O(1)
-+//////////////////////////////////////////////////////////////////////
-+template <class Address, class Value, class Compare >
-+unsigned int extents<Address, Value, Compare>::sizeof_data() const {
-+ // we don't know overhead on map, so this won't be accurate. just estimate.
-+ unsigned int entry_size = sizeof(key_type) + sizeof(mapped_type);
-+ return entry_size * range_map.size();
- }
-
-+
- }
-
- #endif
deleted file mode 100644
@@ -1,47 +0,0 @@
-From 4a5ed3897e772c75929b376b08985d844898b619 Mon Sep 17 00:00:00 2001
-From: chros <chros@chrosGX620>
-Date: Tue, 12 Dec 2017 15:19:51 +0000
-Subject: [PATCH] Disable extents test to pass TravisCI (See #11)
-
----
- test/torrent/utils/test_extents.cc | 10 ++++++----
- 1 file changed, 6 insertions(+), 4 deletions(-)
-
-diff --git a/test/torrent/utils/test_extents.cc b/test/torrent/utils/test_extents.cc
-index 6ac5a57d..d6b8d11d 100644
---- a/test/torrent/utils/test_extents.cc
-+++ b/test/torrent/utils/test_extents.cc
-@@ -16,10 +16,11 @@ void
- ExtentsTest::tearDown() {
- }
-
--typedef torrent::extents<uint32_t, int, 8, 16, 4> extent_type_1;
-+//typedef torrent::extents<uint32_t, int, 8, 16, 4> extent_type_1;
-+typedef torrent::extents<uint32_t, int> extent_type_1;
-
- // typedef torrent::extents<uint32_t, int, 0, 256, 16> extent_type_3;
--
-+/*
- template <typename Extent>
- bool
- verify_extent_data(Extent& extent, const uint32_t* idx, const int* val) {
-@@ -46,11 +47,11 @@ static const int val_basic_1[] = {1, 0, 1};
-
- // static const uint32_t idx_basic_2[] = {0, 1, 16, 255, 256, 256};
- // static const int val_basic_2[] = {1, 0, 2, 1};
--
-+*/
- void
- ExtentsTest::test_basic() {
- extent_type_1 extent_1;
--
-+/*
- // Test empty.
- CPPUNIT_ASSERT(verify_extent_data(extent_1, idx_empty, val_empty));
-
-@@ -68,4 +69,5 @@ ExtentsTest::test_basic() {
- // extent_1.insert(38, 3, 2);
-
- // CPPUNIT_ASSERT(verify_extent_data(extent_1, idx_basic_2, val_basic_2));
-+*/
- }
deleted file mode 100644
@@ -1,30 +0,0 @@
-From da7db7db29a8488e29d3b0f02906c5db379d4b6d Mon Sep 17 00:00:00 2001
-From: rakshasa <sundell.software@gmail.com>
-Date: Thu, 7 Jun 2018 13:18:03 +0900
-Subject: [PATCH] Bumped version to 0.13.7.
-
----
- configure.ac | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
-diff --git a/configure.ac b/configure.ac
-index a6df6b80..5b1ea237 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -1,12 +1,12 @@
--AC_INIT(libtorrent, 0.13.6, sundell.software@gmail.com)
-+AC_INIT(libtorrent, 0.13.7, sundell.software@gmail.com)
-
- LT_INIT([disable-static])
-
- dnl Find a better way to do this
--AC_DEFINE(PEER_NAME, "-lt0D60-", Identifier that is part of the default peer id)
--AC_DEFINE(PEER_VERSION, "lt\x0D\x60", 4 byte client and version identifier for DHT)
-+AC_DEFINE(PEER_NAME, "-lt0D70-", Identifier that is part of the default peer id)
-+AC_DEFINE(PEER_VERSION, "lt\x0D\x70", 4 byte client and version identifier for DHT)
-
--LIBTORRENT_CURRENT=19
-+LIBTORRENT_CURRENT=20
- LIBTORRENT_REVISION=0
- LIBTORRENT_AGE=0
-
deleted file mode 100644
@@ -1,105 +0,0 @@
-From dbf6abfd6f905b9218465d15eebec7eedaaed6b0 Mon Sep 17 00:00:00 2001
-From: rakshasa <sundell.software@gmail.com>
-Date: Tue, 20 Dec 2016 19:51:02 +0900
-Subject: [PATCH] Added support for openssl 1.1.
-
----
- configure.ac | 4 ++++
- src/utils/diffie_hellman.cc | 36 ++++++++++++++++++++++++++++++++++--
- 2 files changed, 38 insertions(+), 2 deletions(-)
-
-diff --git a/configure.ac b/configure.ac
-index 5b1ea237..b885714d 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -71,12 +71,15 @@ AC_ARG_ENABLE(openssl,
- [ --disable-openssl Don't use OpenSSL's SHA1 implementation.],
- [
- if test "$enableval" = "yes"; then
-+dnl move to scripts.
- PKG_CHECK_MODULES(OPENSSL, libcrypto,
- CXXFLAGS="$CXXFLAGS $OPENSSL_CFLAGS";
- LIBS="$LIBS $OPENSSL_LIBS")
-
- AC_DEFINE(USE_OPENSSL, 1, Using OpenSSL.)
- AC_DEFINE(USE_OPENSSL_SHA, 1, Using OpenSSL's SHA1 implementation.)
-+ AC_CHECK_LIB([crypto], [DH_set0_pqg], [AC_DEFINE(USE_OPENSSL_1_1, 1, Using OpenSSL 1.1.)])
-+
- else
- AC_DEFINE(USE_NSS_SHA, 1, Using Mozilla's SHA1 implementation.)
- fi
-@@ -87,6 +90,7 @@ AC_ARG_ENABLE(openssl,
-
- AC_DEFINE(USE_OPENSSL, 1, Using OpenSSL.)
- AC_DEFINE(USE_OPENSSL_SHA, 1, Using OpenSSL's SHA1 implementation.)
-+ AC_CHECK_LIB([crypto], [DH_set0_pqg], [AC_DEFINE(USE_OPENSSL_1_1, 1, Using OpenSSL 1.1.)])
- ]
- )
-
-diff --git a/src/utils/diffie_hellman.cc b/src/utils/diffie_hellman.cc
-index aa653d45..7ec13165 100644
---- a/src/utils/diffie_hellman.cc
-+++ b/src/utils/diffie_hellman.cc
-@@ -54,11 +54,23 @@ DiffieHellman::DiffieHellman(const unsigned char *prime, int primeLength,
- m_secret(NULL), m_size(0) {
-
- #ifdef USE_OPENSSL
-+
- m_dh = DH_new();
-+
-+#ifdef USE_OPENSSL_1_1
-+ BIGNUM * const dh_p = BN_bin2bn(prime, primeLength, NULL);
-+ BIGNUM * const dh_g = BN_bin2bn(generator, generatorLength, NULL);
-+
-+ if (dh_p == NULL || dh_g == NULL ||
-+ !DH_set0_pqg(m_dh, dh_p, NULL, dh_g))
-+ throw internal_error("Could not generate Diffie-Hellman parameters");
-+#else
- m_dh->p = BN_bin2bn(prime, primeLength, NULL);
- m_dh->g = BN_bin2bn(generator, generatorLength, NULL);
-+#endif
-
- DH_generate_key(m_dh);
-+
- #else
- throw internal_error("Compiled without encryption support.");
- #endif
-@@ -74,7 +86,19 @@ DiffieHellman::~DiffieHellman() {
- bool
- DiffieHellman::is_valid() const {
- #ifdef USE_OPENSSL
-+ if (m_dh == NULL)
-+ return false;
-+
-+#ifdef USE_OPENSSL_1_1
-+ const BIGNUM *pub_key;
-+
-+ DH_get0_key(m_dh, &pub_key, NULL);
-+
-+ return pub_key != NULL;
-+#else
- return m_dh != NULL && m_dh->pub_key != NULL;
-+#endif
-+
- #else
- return false;
- #endif
-@@ -103,8 +127,16 @@ DiffieHellman::store_pub_key(unsigned char* dest, unsigned int length) {
- #ifdef USE_OPENSSL
- std::memset(dest, 0, length);
-
-- if ((int)length >= BN_num_bytes(m_dh->pub_key))
-- BN_bn2bin(m_dh->pub_key, dest + length - BN_num_bytes(m_dh->pub_key));
-+ const BIGNUM *pub_key;
-+
-+#ifdef USE_OPENSSL_1_1
-+ DH_get0_key(m_dh, &pub_key, NULL);
-+#else
-+ pub_key = m_dh->pub_key;
-+#endif
-+
-+ if ((int)length >= BN_num_bytes(pub_key))
-+ BN_bn2bin(pub_key, dest + length - BN_num_bytes(pub_key));
- #endif
- }
-
deleted file mode 100644
@@ -1,24 +0,0 @@
-From c2ec5e0fb8ce7a0df513b5f4086e23d92049ef0e Mon Sep 17 00:00:00 2001
-From: Stephen Shkardoon <ss23@ss23.geek.nz>
-Date: Mon, 25 Jun 2018 20:05:18 +1200
-Subject: [PATCH] Use AC_COMPILE instead of AC_RUN to check for execinfo.h
-
-This way enables cross compiling, since we don't need to run anything
-during the configure script.
----
- scripts/common.m4 | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/scripts/common.m4 b/scripts/common.m4
-index ff023928..b6d051f5 100644
---- a/scripts/common.m4
-+++ b/scripts/common.m4
-@@ -153,7 +153,7 @@ dnl Need to fix this so that it uses the stuff defined by the system.
- AC_DEFUN([TORRENT_CHECK_EXECINFO], [
- AC_MSG_CHECKING(for execinfo.h)
-
-- AC_RUN_IFELSE([AC_LANG_SOURCE([
-+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([
- #include <execinfo.h>
- int main() { backtrace((void**)0, 0); backtrace_symbols((char**)0, 0); return 0;}
- ])],
deleted file mode 100644
@@ -1,46 +0,0 @@
-From b0fb874a8921fa4ba2ea0923d779fae8f70c82b1 Mon Sep 17 00:00:00 2001
-From: Stephen Shkardoon <ss23@ss23.geek.nz>
-Date: Thu, 21 Jun 2018 14:38:30 +1200
-Subject: [PATCH] Modify configure to prevent unnecessary kqueue checks
-
-By only running the TORRENT_CHECK_KQUEUE_SOCKET_ONLY check if kqueue support
-is already detected, we increase the number of platforms that we can
-cross compile on.
-Otherwise, the cross compilation fails due to TORRENT_CHECK_KQUEUE_SOCKET_ONLY
-using AC_RUN_IFELSE, which fails during cross compilation.
----
- scripts/checks.m4 | 4 +---
- 1 file changed, 1 insertion(+), 3 deletions(-)
-
-diff --git a/scripts/checks.m4 b/scripts/checks.m4
-index 8d77fc5e..c9333561 100644
---- a/scripts/checks.m4
-+++ b/scripts/checks.m4
-@@ -88,6 +88,7 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE], [
- [
- AC_DEFINE(USE_KQUEUE, 1, Use kqueue.)
- AC_MSG_RESULT(yes)
-+ TORRENT_CHECK_KQUEUE_SOCKET_ONLY
- ], [
- AC_MSG_RESULT(no)
- ])
-@@ -137,7 +138,6 @@ AC_DEFUN([TORRENT_WITH_KQUEUE], [
- [
- if test "$withval" = "yes"; then
- TORRENT_CHECK_KQUEUE
-- TORRENT_CHECK_KQUEUE_SOCKET_ONLY
- fi
- ])
- ])
-@@ -149,11 +149,9 @@ AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [
- [
- if test "$withval" = "yes"; then
- TORRENT_CHECK_KQUEUE
-- TORRENT_CHECK_KQUEUE_SOCKET_ONLY
- fi
- ], [
- TORRENT_CHECK_KQUEUE
-- TORRENT_CHECK_KQUEUE_SOCKET_ONLY
- ])
- ])
-
deleted file mode 100644
@@ -1,58 +0,0 @@
-From 4ff83fc53b2c7462b02f804ee20414d85944e3c9 Mon Sep 17 00:00:00 2001
-From: chros <chros@chrosGX620>
-Date: Sun, 14 May 2017 19:36:09 +0100
-Subject: [PATCH] Display info on failed tracker bencode parsing (See #9)
-
----
- rak/string_manip.h | 20 ++++++++++++++++++++
- src/tracker/tracker_http.cc | 6 ++++--
- 2 files changed, 24 insertions(+), 2 deletions(-)
-
-diff --git a/rak/string_manip.h b/rak/string_manip.h
-index f8d3f590..68614d2a 100644
---- a/rak/string_manip.h
-+++ b/rak/string_manip.h
-@@ -371,6 +371,26 @@ is_all_name(const Sequence& src) {
- return is_all_name(src.begin(), src.end());
- }
-
-+template <typename Iterator>
-+std::string
-+sanitize(Iterator first, Iterator last) {
-+ std::string dest;
-+ for (; first != last; ++first) {
-+ if (std::isprint(*first) && *first != '\r' && *first != '\n' && *first != '\t')
-+ dest += *first;
-+ else
-+ dest += " ";
-+ }
-+
-+ return dest;
-+}
-+
-+template <typename Sequence>
-+std::string
-+sanitize(const Sequence& src) {
-+ return trim(sanitize(src.begin(), src.end()));
-+}
-+
- }
-
- #endif
-diff --git a/src/tracker/tracker_http.cc b/src/tracker/tracker_http.cc
-index 553f922c..b6d9e0ac 100644
---- a/src/tracker/tracker_http.cc
-+++ b/src/tracker/tracker_http.cc
-@@ -288,8 +288,10 @@ TrackerHttp::receive_done() {
- Object b;
- *m_data >> b;
-
-- if (m_data->fail())
-- return receive_failed("Could not parse bencoded data");
-+ if (m_data->fail()) {
-+ std::string dump = m_data->str();
-+ return receive_failed("Could not parse bencoded data: " + rak::sanitize(dump).substr(0,99));
-+ }
-
- if (!b.is_map())
- return receive_failed("Root not a bencoded map");
deleted file mode 100644
@@ -1,60 +0,0 @@
-From 2f197be69057f793d29272b90300f74d0b588d51 Mon Sep 17 00:00:00 2001
-From: chros <chros@chrosGX620>
-Date: Mon, 15 May 2017 19:24:33 +0100
-Subject: [PATCH] Strip tags also when displaying info on failed tracker
- bencode parsing (See #9)
-
----
- rak/string_manip.h | 25 +++++++++++++++++++++++++
- src/tracker/tracker_http.cc | 2 +-
- 2 files changed, 26 insertions(+), 1 deletion(-)
-
-diff --git a/rak/string_manip.h b/rak/string_manip.h
-index 68614d2a..ae867c98 100644
---- a/rak/string_manip.h
-+++ b/rak/string_manip.h
-@@ -391,6 +391,31 @@ sanitize(const Sequence& src) {
- return trim(sanitize(src.begin(), src.end()));
- }
-
-+template <typename Iterator>
-+std::string striptags(Iterator first, Iterator last) {
-+ bool copychar = true;
-+ std::string dest;
-+
-+ for (; first != last; ++first) {
-+ if (std::isprint(*first) && *first == '<') {
-+ copychar = false;
-+ } else if (std::isprint(*first) && *first == '>') {
-+ copychar = true;
-+ continue;
-+ }
-+
-+ if (copychar)
-+ dest += *first;
-+ }
-+
-+ return dest;
-+}
-+
-+template <typename Sequence>
-+std::string striptags(const Sequence& src) {
-+ return striptags(src.begin(), src.end());
-+}
-+
- }
-
- #endif
-diff --git a/src/tracker/tracker_http.cc b/src/tracker/tracker_http.cc
-index b6d9e0ac..eefe5a17 100644
---- a/src/tracker/tracker_http.cc
-+++ b/src/tracker/tracker_http.cc
-@@ -290,7 +290,7 @@ TrackerHttp::receive_done() {
-
- if (m_data->fail()) {
- std::string dump = m_data->str();
-- return receive_failed("Could not parse bencoded data: " + rak::sanitize(dump).substr(0,99));
-+ return receive_failed("Could not parse bencoded data: " + rak::sanitize(rak::striptags(dump)).substr(0,99));
- }
-
- if (!b.is_map())
deleted file mode 100644
@@ -1,45 +0,0 @@
-From 0e86289a8bb5672781e508683bb28aebf9995127 Mon Sep 17 00:00:00 2001
-From: lps-rocks <admin@lps.rocks>
-Date: Mon, 4 Mar 2019 05:03:47 -0500
-Subject: [PATCH] Switch to C++11 MRT RNG for random bytes
-
-Switching to a better RNG for generating strings will prevent the common peerID collisions the rTorrent client has been seeing for YEARS in #440 and #318.
----
- rak/string_manip.h | 12 +++++++++---
- 1 file changed, 9 insertions(+), 3 deletions(-)
-
-diff --git a/rak/string_manip.h b/rak/string_manip.h
-index ae867c98..1a09c377 100644
---- a/rak/string_manip.h
-+++ b/rak/string_manip.h
-@@ -39,9 +39,13 @@
-
- #include <algorithm>
- #include <cctype>
-+#include <climits>
- #include <cstdlib>
-+#include <functional>
- #include <iterator>
- #include <locale>
-+#include <random>
-+
-
- namespace rak {
-
-@@ -312,11 +316,13 @@ transform_hex_str(const Sequence& seq) {
- template <typename Sequence>
- Sequence
- generate_random(size_t length) {
-+ std::random_device rd;
-+ std::mt19937 mt(rd());
-+ using bytes_randomizer = std::independent_bits_engine<std::mt19937, CHAR_BIT, uint8_t>;
-+ bytes_randomizer bytes(mt);
- Sequence s;
- s.reserve(length);
--
-- std::generate_n(std::back_inserter(s), length, &::random);
--
-+ std::generate_n(std::back_inserter(s), length, std::ref(bytes));
- return s;
- }
-
deleted file mode 100644
@@ -1,45 +0,0 @@
-From bf35c5f3d4e458a671fdc3c382f4fa06ecaeb119 Mon Sep 17 00:00:00 2001
-From: Vladyslav Movchan <vladislav.movchan@gmail.com>
-Date: Sat, 3 Nov 2018 19:52:56 +0200
-Subject: [PATCH] Prevent loss of 'm_ipv6_socket' attribute which led to
- execution of setsockopt(..., IPPROTO_IP, IP_TOS, ...) on IPv6 socket
-
----
- src/net/socket_fd.cc | 4 ++--
- src/net/socket_fd.h | 1 +
- 2 files changed, 3 insertions(+), 2 deletions(-)
-
-diff --git a/src/net/socket_fd.cc b/src/net/socket_fd.cc
-index 54cb6ded..f04059f6 100644
---- a/src/net/socket_fd.cc
-+++ b/src/net/socket_fd.cc
-@@ -251,7 +251,7 @@ SocketFd::accept(rak::socket_address* sa) {
- socklen_t len = sizeof(rak::socket_address);
-
- if (sa == NULL) {
-- return SocketFd(::accept(m_fd, NULL, &len));
-+ return SocketFd(::accept(m_fd, NULL, &len), m_ipv6_socket);
- }
-
- int fd = ::accept(m_fd, sa->c_sockaddr(), &len);
-@@ -260,7 +260,7 @@ SocketFd::accept(rak::socket_address* sa) {
- *sa = sa->sa_inet6()->normalize_address();
- }
-
-- return SocketFd(fd);
-+ return SocketFd(fd, m_ipv6_socket);
- }
-
- // unsigned int
-diff --git a/src/net/socket_fd.h b/src/net/socket_fd.h
-index ca765e88..2329b4e9 100644
---- a/src/net/socket_fd.h
-+++ b/src/net/socket_fd.h
-@@ -51,6 +51,7 @@ public:
-
- SocketFd() : m_fd(-1) {}
- explicit SocketFd(int fd) : m_fd(fd) {}
-+ SocketFd(int fd, bool ipv6_socket) : m_fd(fd), m_ipv6_socket(ipv6_socket) {}
-
- bool is_valid() const { return m_fd >= 0; }
-
deleted file mode 100644
@@ -1,27 +0,0 @@
-From 1890bde5c051d932d1b2940e815d0c82964c474c Mon Sep 17 00:00:00 2001
-From: Gleb Smirnoff <glebius@FreeBSD.org>
-Date: Tue, 2 Oct 2018 18:57:43 -0700
-Subject: [PATCH] If during socket creation AF_INET6 failes initialize sockaddr
- as AF_INET. Otherwise any bind(2) would fail due to sockaddr address family
- not matching socket address family.
-
----
- src/net/listen.cc | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/src/net/listen.cc b/src/net/listen.cc
-index da1c2e84..d424e94c 100644
---- a/src/net/listen.cc
-+++ b/src/net/listen.cc
-@@ -75,7 +75,10 @@ Listen::open(uint16_t first, uint16_t last, int backlog, const rak::socket_addre
-
- // TODO: Temporary until we refactor:
- if (bindAddress->family() == 0) {
-- sa.sa_inet6()->clear();
-+ if (m_ipv6_socket)
-+ sa.sa_inet6()->clear();
-+ else
-+ sa.sa_inet()->clear();
- } else {
- sa.copy(*bindAddress, bindAddress->length());
- }
deleted file mode 100644
@@ -1,29 +0,0 @@
-From cbd946b6cad8c93b3d39ab4f338b3640f684cbfc Mon Sep 17 00:00:00 2001
-From: Adam Fontenot <adam.m.fontenot@gmail.com>
-Date: Sat, 7 Jul 2018 16:52:07 -0700
-Subject: [PATCH] Fixes https://github.com/rakshasa/rtorrent/issues/731
-
----
- src/tracker/tracker_http.cc | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/src/tracker/tracker_http.cc b/src/tracker/tracker_http.cc
-index eefe5a17..1bf94107 100644
---- a/src/tracker/tracker_http.cc
-+++ b/src/tracker/tracker_http.cc
-@@ -145,13 +145,13 @@ TrackerHttp::send_state(int state) {
- if (!localAddress->is_address_any())
- s << "&ip=" << localAddress->address_str();
-
-- if (localAddress->is_address_any() || localAddress->family() != rak::socket_address::pf_inet6) {
-+ if (localAddress->is_address_any() && localAddress->family() == rak::socket_address::pf_inet) {
- rak::socket_address local_v6;
- if (get_local_address(rak::socket_address::af_inet6, &local_v6))
- s << "&ipv6=" << rak::copy_escape_html(local_v6.address_str());
- }
-
-- if (localAddress->is_address_any() || localAddress->family() != rak::socket_address::pf_inet) {
-+ if (localAddress->is_address_any() && localAddress->family() == rak::socket_address::pf_inet6) {
- rak::socket_address local_v4;
- if (get_local_address(rak::socket_address::af_inet, &local_v4))
- s << "&ipv4=" << local_v4.address_str();
deleted file mode 100644
@@ -1,40 +0,0 @@
-From d49316117401cff4045b1d1194cec60909e45555 Mon Sep 17 00:00:00 2001
-From: chros <chros@chrosGX620>
-Date: Sun, 13 May 2018 11:34:33 +0100
-Subject: [PATCH] Fix honoring throttle.min_peers* settings in rtorrent (See
- #13)
-
----
- src/download/download_main.cc | 17 ++++++-----------
- 1 file changed, 6 insertions(+), 11 deletions(-)
-
-diff --git a/src/download/download_main.cc b/src/download/download_main.cc
-index 48222c38..efe91d66 100644
---- a/src/download/download_main.cc
-+++ b/src/download/download_main.cc
-@@ -355,19 +355,14 @@ DownloadMain::receive_tracker_success() {
-
- void
- DownloadMain::receive_tracker_request() {
-- bool should_stop = false;
-- bool should_start = false;
-+ if (info()->is_pex_enabled() && info()->size_pex() > 0
-+ || connection_list()->size() + peer_list()->available_list()->size() / 2 >= connection_list()->min_size()) {
-
-- if (info()->is_pex_enabled() && info()->size_pex() > 0)
-- should_stop = true;
--
-- if (connection_list()->size() + peer_list()->available_list()->size() / 2 < connection_list()->min_size())
-- should_start = true;
--
-- if (should_stop)
- m_tracker_controller->stop_requesting();
-- else if (should_start)
-- m_tracker_controller->start_requesting();
-+ return;
-+ }
-+
-+ m_tracker_controller->start_requesting();
- }
-
- struct SocketAddressCompact_less {
deleted file mode 100644
@@ -1,22 +0,0 @@
-From 9fd2f35f86397b9259e0c9b7c54444c0ec3c8965 Mon Sep 17 00:00:00 2001
-From: adam <adam@shinka.sh>
-Date: Mon, 26 Feb 2018 16:04:34 +0200
-Subject: [PATCH] increase piece length max
-
----
- src/download/download_constructor.cc | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/download/download_constructor.cc b/src/download/download_constructor.cc
-index 1bb261bd..67ef4276 100644
---- a/src/download/download_constructor.cc
-+++ b/src/download/download_constructor.cc
-@@ -157,7 +157,7 @@ DownloadConstructor::parse_info(const Object& b) {
- } else {
- chunkSize = b.get_key_value("piece length");
-
-- if (chunkSize <= (1 << 10) || chunkSize > (128 << 20))
-+ if (chunkSize <= (1 << 10) || chunkSize > (128 << 22))
- throw input_error("Torrent has an invalid \"piece length\".");
- }
-
deleted file mode 100644
@@ -1,22 +0,0 @@
-From b263b347f14b9d0ca54d04ca92367a98d791dc17 Mon Sep 17 00:00:00 2001
-From: Jari Sundell <sundell.software@gmail.com>
-Date: Sun, 9 Jun 2019 14:53:32 +0900
-Subject: [PATCH] Set max piece size 512mb.
-
----
- src/download/download_constructor.cc | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/download/download_constructor.cc b/src/download/download_constructor.cc
-index 67ef4276..1bf362fa 100644
---- a/src/download/download_constructor.cc
-+++ b/src/download/download_constructor.cc
-@@ -157,7 +157,7 @@ DownloadConstructor::parse_info(const Object& b) {
- } else {
- chunkSize = b.get_key_value("piece length");
-
-- if (chunkSize <= (1 << 10) || chunkSize > (128 << 22))
-+ if (chunkSize <= (1 << 10) || chunkSize > (512 << 20))
- throw input_error("Torrent has an invalid \"piece length\".");
- }
-
deleted file mode 100644
@@ -1,22 +0,0 @@
-From cdfb4381bedb278dabb8ca75c10858d16b895355 Mon Sep 17 00:00:00 2001
-From: Jari Sundell <sundell.software@gmail.com>
-Date: Sun, 9 Jun 2019 14:55:44 +0900
-Subject: [PATCH] Fixed compiler warning.
-
----
- src/download/download_main.cc | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/src/download/download_main.cc b/src/download/download_main.cc
-index efe91d66..9a3f9df2 100644
---- a/src/download/download_main.cc
-+++ b/src/download/download_main.cc
-@@ -355,7 +355,7 @@ DownloadMain::receive_tracker_success() {
-
- void
- DownloadMain::receive_tracker_request() {
-- if (info()->is_pex_enabled() && info()->size_pex() > 0
-+ if ((info()->is_pex_enabled() && info()->size_pex()) > 0
- || connection_list()->size() + peer_list()->available_list()->size() / 2 >= connection_list()->min_size()) {
-
- m_tracker_controller->stop_requesting();
deleted file mode 100644
@@ -1,74 +0,0 @@
-From 8934703edb5982661483eb8a29d76e6a726b5fe2 Mon Sep 17 00:00:00 2001
-From: rakshasa <sundell.software@gmail.com>
-Date: Mon, 8 Jul 2019 19:37:06 +0200
-Subject: [PATCH] Added _GNU_SOURCE to fallocate test. (neheb)
-
----
- scripts/checks.m4 | 10 ++++++----
- src/data/socket_file.cc | 1 +
- 2 files changed, 7 insertions(+), 4 deletions(-)
-
-diff --git a/scripts/checks.m4 b/scripts/checks.m4
-index c9333561..83be8461 100644
---- a/scripts/checks.m4
-+++ b/scripts/checks.m4
-@@ -88,7 +88,6 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE], [
- [
- AC_DEFINE(USE_KQUEUE, 1, Use kqueue.)
- AC_MSG_RESULT(yes)
-- TORRENT_CHECK_KQUEUE_SOCKET_ONLY
- ], [
- AC_MSG_RESULT(no)
- ])
-@@ -97,7 +96,7 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE], [
- AC_DEFUN([TORRENT_CHECK_KQUEUE_SOCKET_ONLY], [
- AC_MSG_CHECKING(whether kqueue supports pipes and ptys)
-
-- AC_RUN_IFELSE([AC_LANG_SOURCE([
-+ AC_LINK_IFELSE([AC_LANG_SOURCE([
- #include <fcntl.h>
- #include <stdlib.h>
- #include <unistd.h>
-@@ -138,6 +137,7 @@ AC_DEFUN([TORRENT_WITH_KQUEUE], [
- [
- if test "$withval" = "yes"; then
- TORRENT_CHECK_KQUEUE
-+ TORRENT_CHECK_KQUEUE_SOCKET_ONLY
- fi
- ])
- ])
-@@ -149,9 +149,11 @@ AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [
- [
- if test "$withval" = "yes"; then
- TORRENT_CHECK_KQUEUE
-+ TORRENT_CHECK_KQUEUE_SOCKET_ONLY
- fi
- ], [
- TORRENT_CHECK_KQUEUE
-+ TORRENT_CHECK_KQUEUE_SOCKET_ONLY
- ])
- ])
-
-@@ -172,8 +174,8 @@ AC_DEFUN([TORRENT_WITHOUT_VARIABLE_FDSET], [
- AC_DEFUN([TORRENT_CHECK_FALLOCATE], [
- AC_MSG_CHECKING(for fallocate)
-
-- AC_TRY_LINK([#include <fcntl.h>
-- #include <linux/falloc.h>
-+ AC_TRY_LINK([#define _GNU_SOURCE
-+ #include <fcntl.h>
- ],[ fallocate(0, FALLOC_FL_KEEP_SIZE, 0, 0); return 0;
- ],
- [
-diff --git a/src/data/socket_file.cc b/src/data/socket_file.cc
-index 4b4519ed..b359ef8e 100644
---- a/src/data/socket_file.cc
-+++ b/src/data/socket_file.cc
-@@ -48,6 +48,7 @@
- #include <sys/types.h>
-
- #ifdef HAVE_FALLOCATE
-+#define _GNU_SOURCE
- #include <linux/falloc.h>
- #endif
-
deleted file mode 100644
@@ -1,293 +0,0 @@
-From 856d42e2ca3c9810bf84a8bce219000e822540fa Mon Sep 17 00:00:00 2001
-From: rakshasa <sundell.software@gmail.com>
-Date: Fri, 12 Jul 2019 00:29:35 +0200
-Subject: [PATCH] Fixed diffie hellman implementation.
-
----
- src/utils/diffie_hellman.cc | 137 ++++++++++++------------------------
- src/utils/diffie_hellman.h | 67 ++++--------------
- 2 files changed, 59 insertions(+), 145 deletions(-)
-
-diff --git a/src/utils/diffie_hellman.cc b/src/utils/diffie_hellman.cc
-index 7ec13165..d53a857b 100644
---- a/src/utils/diffie_hellman.cc
-+++ b/src/utils/diffie_hellman.cc
-@@ -1,118 +1,79 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #include "config.h"
-
-+#include "diffie_hellman.h"
-+
-+#include "torrent/exceptions.h"
-+
- #include <cstring>
--#include <string>
-
- #ifdef USE_OPENSSL
-+#include <openssl/dh.h>
- #include <openssl/bn.h>
- #endif
-
--#include "diffie_hellman.h"
--#include "torrent/exceptions.h"
--
- namespace torrent {
-
--#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
--DiffieHellman::DiffieHellman(const unsigned char *prime, int primeLength,
-- const unsigned char *generator, int generatorLength) :
-- m_secret(NULL), m_size(0) {
--
- #ifdef USE_OPENSSL
-
-- m_dh = DH_new();
--
--#ifdef USE_OPENSSL_1_1
-- BIGNUM * const dh_p = BN_bin2bn(prime, primeLength, NULL);
-- BIGNUM * const dh_g = BN_bin2bn(generator, generatorLength, NULL);
-+static void dh_free(void* dh) { DH_free(reinterpret_cast<DH*>(dh)); }
-+static DiffieHellman::dh_ptr dh_new() { return DiffieHellman::dh_ptr(reinterpret_cast<void*>(DH_new()), &dh_free); }
-+static DH* dh_get(DiffieHellman::dh_ptr& dh) { return reinterpret_cast<DH*>(dh.get()); }
-
-- if (dh_p == NULL || dh_g == NULL ||
-- !DH_set0_pqg(m_dh, dh_p, NULL, dh_g))
-- throw internal_error("Could not generate Diffie-Hellman parameters");
-+static bool
-+dh_set_pg(DiffieHellman::dh_ptr& dh, BIGNUM* dh_p, BIGNUM* dh_g) {
-+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
-+ return DH_set0_pqg(reinterpret_cast<DH*>(dh.get()), dh_p, nullptr, dh_g);
- #else
-- m_dh->p = BN_bin2bn(prime, primeLength, NULL);
-- m_dh->g = BN_bin2bn(generator, generatorLength, NULL);
-+ reinterpret_cast<DH*>(dh.get())->p = dh_p;
-+ reinterpret_cast<DH*>(dh.get())->g = dh_g;
-+ return true;
- #endif
-+}
-
-- DH_generate_key(m_dh);
--
-+static const BIGNUM* dh_get_pub_key(const DiffieHellman::dh_ptr& dh) {
-+#if OPENSSL_VERSION_NUMBER >= 0x10100000L
-+ const BIGNUM *pub_key;
-+ DH_get0_key(reinterpret_cast<DH*>(dh.get()), &pub_key, nullptr);
-+ return pub_key;
- #else
-- throw internal_error("Compiled without encryption support.");
-+ return dh != nullptr ? reinterpret_cast<DH*>(dh.get())->pub_key : nullptr;
- #endif
--};
-+}
-
--DiffieHellman::~DiffieHellman() {
-- delete [] m_secret;
--#ifdef USE_OPENSSL
-- DH_free(m_dh);
-+#else
-+static DiffieHellman::dh_ptr dh_new() { throw internal_error("Compiled without encryption support."); }
-+static void dh_free(void* dh) {}
-+static void* dh_get_pub_key(const DiffieHellman::dh_ptr& dh) { return nullptr; }
- #endif
--};
-
--bool
--DiffieHellman::is_valid() const {
--#ifdef USE_OPENSSL
-- if (m_dh == NULL)
-- return false;
-+#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-+DiffieHellman::DiffieHellman(const unsigned char *prime, int primeLength,
-+ const unsigned char *generator, int generatorLength) :
-+ m_dh(dh_new()), m_size(0) {
-
--#ifdef USE_OPENSSL_1_1
-- const BIGNUM *pub_key;
-+#ifdef USE_OPENSSL
-+ BIGNUM* dh_p = BN_bin2bn(prime, primeLength, nullptr);
-+ BIGNUM* dh_g = BN_bin2bn(generator, generatorLength, nullptr);
-
-- DH_get0_key(m_dh, &pub_key, NULL);
-+ if (dh_p == nullptr || dh_g == nullptr || !dh_set_pg(m_dh, dh_p, dh_g))
-+ throw internal_error("Could not generate Diffie-Hellman parameters");
-
-- return pub_key != NULL;
--#else
-- return m_dh != NULL && m_dh->pub_key != NULL;
-+ DH_generate_key(dh_get(m_dh));
- #endif
-+};
-
--#else
-- return false;
--#endif
-+bool
-+DiffieHellman::is_valid() const {
-+ return dh_get_pub_key(m_dh) != nullptr;
- }
-
- bool
- DiffieHellman::compute_secret(const unsigned char *pubkey, unsigned int length) {
- #ifdef USE_OPENSSL
-- BIGNUM* k = BN_bin2bn(pubkey, length, NULL);
-+ BIGNUM* k = BN_bin2bn(pubkey, length, nullptr);
-
-- delete [] m_secret;
-- m_secret = new char[DH_size(m_dh)];
--
-- m_size = DH_compute_key((unsigned char*)m_secret, k, m_dh);
-+ m_secret.reset(new char[DH_size(dh_get(m_dh))]);
-+ m_size = DH_compute_key(reinterpret_cast<unsigned char*>(m_secret.get()), k, dh_get(m_dh));
-
- BN_free(k);
-
-@@ -124,16 +85,10 @@ DiffieHellman::compute_secret(const unsigned char *pubkey, unsigned int length)
-
- void
- DiffieHellman::store_pub_key(unsigned char* dest, unsigned int length) {
--#ifdef USE_OPENSSL
- std::memset(dest, 0, length);
-
-- const BIGNUM *pub_key;
--
--#ifdef USE_OPENSSL_1_1
-- DH_get0_key(m_dh, &pub_key, NULL);
--#else
-- pub_key = m_dh->pub_key;
--#endif
-+#ifdef USE_OPENSSL
-+ const BIGNUM *pub_key = dh_get_pub_key(m_dh);
-
- if ((int)length >= BN_num_bytes(pub_key))
- BN_bn2bin(pub_key, dest + length - BN_num_bytes(pub_key));
-diff --git a/src/utils/diffie_hellman.h b/src/utils/diffie_hellman.h
-index 432542be..2cec5bee 100644
---- a/src/utils/diffie_hellman.h
-+++ b/src/utils/diffie_hellman.h
-@@ -1,79 +1,38 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #ifndef LIBTORRENT_DIFFIE_HELLMAN_H
- #define LIBTORRENT_DIFFIE_HELLMAN_H
-
- #include "config.h"
-
-+#include <memory>
- #include <string>
-
--#ifdef USE_OPENSSL
--#include <openssl/dh.h>
--#endif
--
- namespace torrent {
-
- class DiffieHellman {
- public:
-+ typedef std::unique_ptr<char[]> secret_ptr;
-+ typedef std::unique_ptr<void, void (*)(void*)> dh_ptr;
-+
- DiffieHellman(const unsigned char prime[], int primeLength,
- const unsigned char generator[], int generatorLength);
-- ~DiffieHellman();
-
-- bool compute_secret(const unsigned char pubkey[], unsigned int length);
-- void store_pub_key(unsigned char* dest, unsigned int length);
-+ bool is_valid() const;
-
-- bool is_valid() const;
-+ bool compute_secret(const unsigned char pubkey[], unsigned int length);
-+ void store_pub_key(unsigned char* dest, unsigned int length);
-
-- unsigned int size() const { return m_size; }
-+ unsigned int size() const { return m_size; }
-
-- const char* c_str() const { return m_secret; }
-- std::string secret_str() const { return std::string(m_secret, m_size); }
-+ const char* c_str() const { return m_secret.get(); }
-+ std::string secret_str() const { return std::string(m_secret.get(), m_size); }
-
- private:
- DiffieHellman(const DiffieHellman& dh);
- DiffieHellman& operator = (const DiffieHellman& dh);
-
--#ifdef USE_OPENSSL
-- DH* m_dh;
--#else
-- void* m_void;
--#endif
-- char* m_secret;
-- unsigned int m_size;
-+ dh_ptr m_dh;
-+ secret_ptr m_secret;
-+ int m_size;
- };
-
- };
deleted file mode 100644
@@ -1,64 +0,0 @@
-From 660bbc17e32c518c2727607ee5b73039c7109207 Mon Sep 17 00:00:00 2001
-From: rakshasa <sundell.software@gmail.com>
-Date: Sat, 13 Jul 2019 00:07:43 +0200
-Subject: [PATCH] Increased max timeout for tracker requests.
-
----
- src/torrent/tracker.h | 40 ++--------------------------------------
- 1 file changed, 2 insertions(+), 38 deletions(-)
-
-diff --git a/src/torrent/tracker.h b/src/torrent/tracker.h
-index 2b00ad47..a528ef6a 100644
---- a/src/torrent/tracker.h
-+++ b/src/torrent/tracker.h
-@@ -1,39 +1,3 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #ifndef LIBTORRENT_TRACKER_H
- #define LIBTORRENT_TRACKER_H
-
-@@ -148,8 +112,8 @@ protected:
-
- void set_group(uint32_t v) { m_group = v; }
-
-- void set_normal_interval(int v) { m_normal_interval = std::min(std::max(600, v), 3600); }
-- void set_min_interval(int v) { m_min_interval = std::min(std::max(300, v), 1800); }
-+ void set_normal_interval(int v) { m_normal_interval = std::min(std::max(600, v), 8 * 3600); }
-+ void set_min_interval(int v) { m_min_interval = std::min(std::max(300, v), 4 * 3600); }
-
- int m_flags;
-
deleted file mode 100644
@@ -1,123 +0,0 @@
-From efc75948253c1a8db482daabf45d9eabaaf4b099 Mon Sep 17 00:00:00 2001
-From: rakshasa <sundell.software@gmail.com>
-Date: Wed, 17 Jul 2019 19:41:04 +0200
-Subject: [PATCH] Close log files when reusing a name.
-
----
- src/torrent/utils/log.cc | 20 ++++++++++++++++----
- src/torrent/utils/log.h | 7 +++++++
- test/torrent/tracker_timeout_test.cc | 8 ++++----
- test/torrent/utils/log_test.cc | 12 ++++++------
- 4 files changed, 33 insertions(+), 14 deletions(-)
-
-diff --git a/src/torrent/utils/log.cc b/src/torrent/utils/log.cc
-index 58b563a6..5169a730 100644
---- a/src/torrent/utils/log.cc
-+++ b/src/torrent/utils/log.cc
-@@ -294,12 +294,16 @@ log_open_output(const char* name, log_slot slot) {
- throw input_error("Cannot open more than 64 log output handlers.");
- }
-
-- if (log_find_output_name(name) != log_outputs.end()) {
-- pthread_mutex_unlock(&log_mutex);
-- throw input_error("Log name already used.");
-+ log_output_list::iterator itr = log_find_output_name(name);
-+
-+ if (itr == log_outputs.end()) {
-+ log_outputs.push_back(std::make_pair(name, slot));
-+ } else {
-+ // by replacing the "write" slot binding, the old file gets closed
-+ // (handles are shared pointers)
-+ itr->second = slot;
- }
-
-- log_outputs.push_back(std::make_pair(name, slot));
- log_rebuild_cache();
-
- pthread_mutex_unlock(&log_mutex);
-@@ -307,6 +311,14 @@ log_open_output(const char* name, log_slot slot) {
-
- void
- log_close_output(const char* name) {
-+ pthread_mutex_lock(&log_mutex);
-+
-+ log_output_list::iterator itr = log_find_output_name(name);
-+
-+ if (itr != log_outputs.end())
-+ log_outputs.erase(itr);
-+
-+ pthread_mutex_unlock(&log_mutex);
- }
-
- void
-diff --git a/src/torrent/utils/log.h b/src/torrent/utils/log.h
-index a053d6ec..430bda5e 100644
---- a/src/torrent/utils/log.h
-+++ b/src/torrent/utils/log.h
-@@ -229,6 +229,7 @@ void log_cleanup() LIBTORRENT_EXPORT;
-
- void log_open_output(const char* name, log_slot slot) LIBTORRENT_EXPORT;
- void log_close_output(const char* name) LIBTORRENT_EXPORT;
-+void log_close_output_str(const std::string name) LIBTORRENT_EXPORT;
-
- void log_add_group_output(int group, const char* name) LIBTORRENT_EXPORT;
- void log_remove_group_output(int group, const char* name) LIBTORRENT_EXPORT;
-@@ -240,6 +241,12 @@ void log_open_file_output(const char* name, const char* filename) LIBTORR
- void log_open_gz_file_output(const char* name, const char* filename) LIBTORRENT_EXPORT;
- log_buffer* log_open_log_buffer(const char* name) LIBTORRENT_EXPORT;
-
-+//
-+// Implementation:
-+//
-+
-+inline void log_close_output_str(const std::string name) { log_close_output(name.c_str()); }
-+
- }
-
- #endif
-diff --git a/test/torrent/tracker_timeout_test.cc b/test/torrent/tracker_timeout_test.cc
-index 081b9301..cd060006 100644
---- a/test/torrent/tracker_timeout_test.cc
-+++ b/test/torrent/tracker_timeout_test.cc
-@@ -29,13 +29,13 @@ tracker_timeout_test::test_set_timeout() {
-
- tracker.set_new_normal_interval(100);
- CPPUNIT_ASSERT(tracker.normal_interval() == 600);
-- tracker.set_new_normal_interval(4000);
-- CPPUNIT_ASSERT(tracker.normal_interval() == 3600);
-+ tracker.set_new_normal_interval(8 * 4000);
-+ CPPUNIT_ASSERT(tracker.normal_interval() == 8 * 3600);
-
- tracker.set_new_min_interval(100);
- CPPUNIT_ASSERT(tracker.min_interval() == 300);
-- tracker.set_new_min_interval(4000);
-- CPPUNIT_ASSERT(tracker.min_interval() == 1800);
-+ tracker.set_new_min_interval(4 * 4000);
-+ CPPUNIT_ASSERT(tracker.min_interval() == 4 * 3600);
- }
-
- void
-diff --git a/test/torrent/utils/log_test.cc b/test/torrent/utils/log_test.cc
-index 9b99c245..24c22b59 100644
---- a/test/torrent/utils/log_test.cc
-+++ b/test/torrent/utils/log_test.cc
-@@ -75,13 +75,13 @@ utils_log_test::test_output_open() {
- // Test inserting duplicate names, should catch.
- // CPPUNIT_ASSERT_THROW(torrent::log_open_output("test_output_1", torrent::log_slot());, torrent::input_error);
-
-- try {
-- torrent::log_open_output("test_output_1", torrent::log_slot());
-- } catch (torrent::input_error& e) {
-- return;
-- }
-+ // try {
-+ // torrent::log_open_output("test_output_1", torrent::log_slot());
-+ // } catch (torrent::input_error& e) {
-+ // return;
-+ // }
-
-- CPPUNIT_ASSERT(false);
-+ // CPPUNIT_ASSERT(false);
-
- // Test more than 64 entries.
- }
deleted file mode 100644
@@ -1,30 +0,0 @@
-From 7faa9c58ce098bbdeff83b6add72f3075b47881d Mon Sep 17 00:00:00 2001
-From: rakshasa <sundell.software@gmail.com>
-Date: Fri, 19 Jul 2019 13:38:12 +0200
-Subject: [PATCH] Bumped to version 0.13.8.
-
----
- configure.ac | 8 ++++----
- 1 file changed, 4 insertions(+), 4 deletions(-)
-
-diff --git a/configure.ac b/configure.ac
-index b885714d..4ed08124 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -1,12 +1,12 @@
--AC_INIT(libtorrent, 0.13.7, sundell.software@gmail.com)
-+AC_INIT(libtorrent, 0.13.8, sundell.software@gmail.com)
-
- LT_INIT([disable-static])
-
- dnl Find a better way to do this
--AC_DEFINE(PEER_NAME, "-lt0D70-", Identifier that is part of the default peer id)
--AC_DEFINE(PEER_VERSION, "lt\x0D\x70", 4 byte client and version identifier for DHT)
-+AC_DEFINE(PEER_NAME, "-lt0D80-", Identifier that is part of the default peer id)
-+AC_DEFINE(PEER_VERSION, "lt\x0D\x80", 4 byte client and version identifier for DHT)
-
--LIBTORRENT_CURRENT=20
-+LIBTORRENT_CURRENT=21
- LIBTORRENT_REVISION=0
- LIBTORRENT_AGE=0
-
deleted file mode 100644
@@ -1,109 +0,0 @@
-From 7667094274879fe158e718bf2765d35f82d924bd Mon Sep 17 00:00:00 2001
-From: nicholi <nschell@gmail.com>
-Date: Tue, 23 Jul 2019 23:59:16 -0700
-Subject: [PATCH] Allow logs to be appended rather than overwritten.
-
----
- src/torrent/utils/log.cc | 13 +++++++++++++
- src/torrent/utils/log.h | 1 +
- test/torrent/utils/log_test.cc | 35 ++++++++++++++++++++++++++++++++++
- test/torrent/utils/log_test.h | 2 ++
- 4 files changed, 51 insertions(+)
-
-diff --git a/src/torrent/utils/log.cc b/src/torrent/utils/log.cc
-index 5169a730..a900c109 100644
---- a/src/torrent/utils/log.cc
-+++ b/src/torrent/utils/log.cc
-@@ -428,6 +428,19 @@ log_open_file_output(const char* name, const char* filename) {
- std::placeholders::_3));
- }
-
-+void
-+log_open_file_output_append(const char* name, const char* filename) {
-+ std::shared_ptr<std::ofstream> outfile(new std::ofstream(filename, std::ofstream::out | std::ofstream::app));
-+
-+ if (!outfile->good())
-+ throw input_error("Could not open log file '" + std::string(filename) + "'.");
-+
-+ log_open_output(name, std::bind(&log_file_write, outfile,
-+ std::placeholders::_1,
-+ std::placeholders::_2,
-+ std::placeholders::_3));
-+}
-+
- void
- log_open_gz_file_output(const char* name, const char* filename) {
- std::shared_ptr<log_gz_output> outfile(new log_gz_output(filename));
-diff --git a/src/torrent/utils/log.h b/src/torrent/utils/log.h
-index 430bda5e..531c8565 100644
---- a/src/torrent/utils/log.h
-+++ b/src/torrent/utils/log.h
-@@ -238,6 +238,7 @@ void log_add_child(int group, int child) LIBTORRENT_EXPORT;
- void log_remove_child(int group, int child) LIBTORRENT_EXPORT;
-
- void log_open_file_output(const char* name, const char* filename) LIBTORRENT_EXPORT;
-+void log_open_file_output_append(const char* name, const char* filename) LIBTORRENT_EXPORT;
- void log_open_gz_file_output(const char* name, const char* filename) LIBTORRENT_EXPORT;
- log_buffer* log_open_log_buffer(const char* name) LIBTORRENT_EXPORT;
-
-diff --git a/test/torrent/utils/log_test.cc b/test/torrent/utils/log_test.cc
-index 24c22b59..aa13fff8 100644
---- a/test/torrent/utils/log_test.cc
-+++ b/test/torrent/utils/log_test.cc
-@@ -155,3 +155,38 @@ utils_log_test::test_file_output() {
-
- CPPUNIT_ASSERT_MESSAGE(buffer, std::string(buffer).find("test_file") != std::string::npos);
- }
-+
-+void
-+utils_log_test::test_file_output_append() {
-+ std::string filename = "utils_log_test.XXXXXX";
-+
-+ mktemp(&*filename.begin());
-+
-+ torrent::log_open_file_output_append("test_file", filename.c_str());
-+ torrent::log_add_group_output(GROUP_PARENT_1, "test_file");
-+
-+ lt_log_print(GROUP_PARENT_1, "test_line_1");
-+
-+ torrent::log_cleanup(); // To ensure we flush the buffers.
-+
-+ // re-open and write 2nd line
-+ torrent::log_open_file_output_append("test_file", filename.c_str());
-+ torrent::log_add_group_output(GROUP_PARENT_1, "test_file");
-+
-+ lt_log_print(GROUP_PARENT_1, "test_line_2");
-+
-+ torrent::log_cleanup(); // To ensure we flush the buffers.
-+
-+ std::ifstream temp_file(filename.c_str());
-+
-+ CPPUNIT_ASSERT(temp_file.good());
-+
-+ char buffer_line1[256];
-+ temp_file.getline(buffer_line1, 256);
-+
-+ char buffer_line2[256];
-+ temp_file.getline(buffer_line2, 256);
-+
-+ CPPUNIT_ASSERT_MESSAGE(buffer_line1, std::string(buffer_line1).find("test_line_1") != std::string::npos);
-+ CPPUNIT_ASSERT_MESSAGE(buffer_line2, std::string(buffer_line2).find("test_line_2") != std::string::npos);
-+}
-diff --git a/test/torrent/utils/log_test.h b/test/torrent/utils/log_test.h
-index 3a66cc24..d4cb3bc6 100644
---- a/test/torrent/utils/log_test.h
-+++ b/test/torrent/utils/log_test.h
-@@ -10,6 +10,7 @@ class utils_log_test : public CppUnit::TestFixture {
- CPPUNIT_TEST(test_print);
- CPPUNIT_TEST(test_children);
- CPPUNIT_TEST(test_file_output);
-+ CPPUNIT_TEST(test_file_output_append);
- CPPUNIT_TEST_SUITE_END();
-
- public:
-@@ -22,4 +23,5 @@ public:
- void test_print();
- void test_children();
- void test_file_output();
-+ void test_file_output_append();
- };
deleted file mode 100644
@@ -1,101 +0,0 @@
-From df54913c34c8b584d6d2072a65ad1590766780c5 Mon Sep 17 00:00:00 2001
-From: nicholi <nschell@gmail.com>
-Date: Fri, 26 Jul 2019 00:50:52 -0700
-Subject: [PATCH] Removed log append function. Added append parameter with
- default value (false) to log_open_file functions.
-
----
- src/torrent/utils/log.cc | 26 ++++++++------------------
- src/torrent/utils/log.h | 5 ++---
- test/torrent/utils/log_test.cc | 4 ++--
- 3 files changed, 12 insertions(+), 23 deletions(-)
-
-diff --git a/src/torrent/utils/log.cc b/src/torrent/utils/log.cc
-index a900c109..6c605474 100644
---- a/src/torrent/utils/log.cc
-+++ b/src/torrent/utils/log.cc
-@@ -73,7 +73,7 @@ struct log_cache_entry {
- };
-
- struct log_gz_output {
-- log_gz_output(const char* filename) { gz_file = gzopen(filename, "w"); }
-+ log_gz_output(const char* filename, bool append) { gz_file = gzopen(filename, append ? "a" : "w"); }
- ~log_gz_output() { if (gz_file != NULL) gzclose(gz_file); }
-
- bool is_valid() { return gz_file != Z_NULL; }
-@@ -416,8 +416,11 @@ log_gz_file_write(std::shared_ptr<log_gz_output>& outfile, const char* data, siz
- }
-
- void
--log_open_file_output(const char* name, const char* filename) {
-- std::shared_ptr<std::ofstream> outfile(new std::ofstream(filename));
-+log_open_file_output(const char* name, const char* filename, bool append) {
-+ std::ios_base::openmode mode = std::ofstream::out;
-+ if (append)
-+ mode |= std::ofstream::app;
-+ std::shared_ptr<std::ofstream> outfile(new std::ofstream(filename, mode));
-
- if (!outfile->good())
- throw input_error("Could not open log file '" + std::string(filename) + "'.");
-@@ -429,21 +432,8 @@ log_open_file_output(const char* name, const char* filename) {
- }
-
- void
--log_open_file_output_append(const char* name, const char* filename) {
-- std::shared_ptr<std::ofstream> outfile(new std::ofstream(filename, std::ofstream::out | std::ofstream::app));
--
-- if (!outfile->good())
-- throw input_error("Could not open log file '" + std::string(filename) + "'.");
--
-- log_open_output(name, std::bind(&log_file_write, outfile,
-- std::placeholders::_1,
-- std::placeholders::_2,
-- std::placeholders::_3));
--}
--
--void
--log_open_gz_file_output(const char* name, const char* filename) {
-- std::shared_ptr<log_gz_output> outfile(new log_gz_output(filename));
-+log_open_gz_file_output(const char* name, const char* filename, bool append) {
-+ std::shared_ptr<log_gz_output> outfile(new log_gz_output(filename, append));
-
- if (!outfile->is_valid())
- throw input_error("Could not open log gzip file '" + std::string(filename) + "'.");
-diff --git a/src/torrent/utils/log.h b/src/torrent/utils/log.h
-index 531c8565..0dfdc86b 100644
---- a/src/torrent/utils/log.h
-+++ b/src/torrent/utils/log.h
-@@ -237,9 +237,8 @@ void log_remove_group_output(int group, const char* name) LIBTORRENT_EXPORT;
- void log_add_child(int group, int child) LIBTORRENT_EXPORT;
- void log_remove_child(int group, int child) LIBTORRENT_EXPORT;
-
--void log_open_file_output(const char* name, const char* filename) LIBTORRENT_EXPORT;
--void log_open_file_output_append(const char* name, const char* filename) LIBTORRENT_EXPORT;
--void log_open_gz_file_output(const char* name, const char* filename) LIBTORRENT_EXPORT;
-+void log_open_file_output(const char* name, const char* filename, bool append = false) LIBTORRENT_EXPORT;
-+void log_open_gz_file_output(const char* name, const char* filename, bool append = false) LIBTORRENT_EXPORT;
- log_buffer* log_open_log_buffer(const char* name) LIBTORRENT_EXPORT;
-
- //
-diff --git a/test/torrent/utils/log_test.cc b/test/torrent/utils/log_test.cc
-index aa13fff8..9f975636 100644
---- a/test/torrent/utils/log_test.cc
-+++ b/test/torrent/utils/log_test.cc
-@@ -162,7 +162,7 @@ utils_log_test::test_file_output_append() {
-
- mktemp(&*filename.begin());
-
-- torrent::log_open_file_output_append("test_file", filename.c_str());
-+ torrent::log_open_file_output("test_file", filename.c_str(), false);
- torrent::log_add_group_output(GROUP_PARENT_1, "test_file");
-
- lt_log_print(GROUP_PARENT_1, "test_line_1");
-@@ -170,7 +170,7 @@ utils_log_test::test_file_output_append() {
- torrent::log_cleanup(); // To ensure we flush the buffers.
-
- // re-open and write 2nd line
-- torrent::log_open_file_output_append("test_file", filename.c_str());
-+ torrent::log_open_file_output("test_file", filename.c_str(), true);
- torrent::log_add_group_output(GROUP_PARENT_1, "test_file");
-
- lt_log_print(GROUP_PARENT_1, "test_line_2");
deleted file mode 100644
@@ -1,7365 +0,0 @@
-From b0f945e11d6afe43c917b58291c6fbcf5468a908 Mon Sep 17 00:00:00 2001
-From: Jari Sundell <sundell.software@gmail.com>
-Date: Fri, 23 Aug 2019 23:23:48 +0900
-Subject: [PATCH] Backport changes from feature-bind. (#200)
-
----
- .dir-locals.el | 7 +
- Makefile.am | 1 +
- configure.ac | 40 +-
- extra/corrupt_file.cc | 2 +-
- rak/file_stat.h | 2 +-
- rak/fs_stat.h | 2 +-
- rak/partial_queue.h | 2 +-
- rak/path.h | 2 +-
- rak/priority_queue_default.h | 2 +-
- rak/socket_address.h | 49 +-
- rak/timer.h | 2 +-
- scripts/checks.m4 | 4 +-
- scripts/rak_cxx.m4 | 47 --
- scripts/ssl.m4 | 38 ++
- src/data/chunk_list.cc | 2 -
- src/data/chunk_list.h | 2 +-
- src/data/chunk_list_node.h | 2 +-
- src/data/hash_check_queue.h | 2 +-
- src/data/hash_queue.cc | 2 -
- src/data/hash_queue.h | 2 +-
- src/data/hash_queue_node.h | 4 +-
- src/data/hash_torrent.cc | 2 -
- src/data/hash_torrent.h | 4 +-
- src/data/memory_chunk.h | 2 +-
- src/data/socket_file.h | 2 +-
- src/dht/dht_hash_map.h | 57 +-
- src/download/chunk_selector.h | 2 +-
- src/download/chunk_statistics.h | 2 +-
- src/download/delegator.cc | 2 +-
- src/download/delegator.h | 2 +-
- src/download/download_constructor.h | 2 +-
- src/globals.cc | 15 +-
- src/globals.h | 36 --
- src/manager.cc | 36 --
- src/net/Makefile.am | 2 +
- src/net/data_buffer.h | 2 +-
- src/net/listen.cc | 40 +-
- src/net/listen.h | 4 +-
- src/net/protocol_buffer.h | 2 +-
- src/net/socket_base.h | 2 +-
- src/net/socket_fd.cc | 10 +
- src/net/socket_fd.h | 6 +
- src/net/socket_listen.cc | 137 +++++
- src/net/socket_listen.h | 46 ++
- src/net/socket_set.h | 2 +-
- src/net/throttle_node.h | 2 +-
- src/protocol/handshake.cc | 13 +-
- src/protocol/handshake_manager.cc | 56 +-
- src/protocol/handshake_manager.h | 40 +-
- src/protocol/peer_connection_base.cc | 2 -
- src/protocol/request_list.cc | 38 +-
- src/torrent/Makefile.am | 1 +
- src/torrent/common.h | 5 +-
- src/torrent/connection_manager.h | 2 +-
- src/torrent/data/download_data.h | 2 +-
- src/torrent/data/file_list.cc | 2 -
- src/torrent/data/transfer_list.h | 3 +-
- src/torrent/download.cc | 4 +-
- src/torrent/download/choke_group.cc | 2 +-
- src/torrent/download/choke_group.h | 2 +-
- src/torrent/download/choke_queue.cc | 3 +-
- src/torrent/download/choke_queue.h | 5 +-
- src/torrent/download/group_entry.h | 3 +-
- src/torrent/download/resource_manager.cc | 1 -
- src/torrent/download/resource_manager.h | 2 +-
- src/torrent/download_info.h | 4 +-
- src/torrent/error.cc | 6 +-
- src/torrent/error.h | 7 +-
- src/torrent/event.cc | 19 +
- src/torrent/event.h | 82 ++-
- src/torrent/http.h | 2 +-
- src/torrent/net/Makefile.am | 18 +-
- src/torrent/net/address_info.cc | 43 ++
- src/torrent/net/address_info.h | 69 +++
- src/torrent/net/fd.cc | 209 +++++++
- src/torrent/net/fd.h | 63 ++
- src/torrent/net/socket_address.cc | 559 ++++++++++++++++++
- src/torrent/net/socket_address.h | 229 +++++++
- src/torrent/net/socket_address_key.h | 2 +-
- src/torrent/net/socket_event.cc | 29 +
- src/torrent/net/socket_event.h | 31 +
- src/torrent/net/types.h | 33 ++
- src/torrent/object.h | 21 +-
- src/torrent/peer/client_list.cc | 2 +-
- src/torrent/peer/connection_list.h | 3 +-
- src/torrent/peer/peer_list.cc | 7 +-
- src/torrent/poll.h | 3 +-
- src/torrent/torrent.cc | 42 +-
- src/torrent/torrent.h | 11 +-
- src/torrent/tracker.h | 2 +-
- src/torrent/tracker_controller.h | 3 +-
- src/torrent/tracker_list.h | 2 +-
- src/torrent/utils/Makefile.am | 5 +-
- src/torrent/utils/directory_events.h | 3 +-
- src/torrent/utils/log.cc | 66 +--
- src/torrent/utils/log.h | 98 ++-
- src/torrent/utils/log_buffer.cc | 55 +-
- src/torrent/utils/log_buffer.h | 52 +-
- src/torrent/utils/net.cc | 72 ---
- src/torrent/utils/net.h | 56 --
- src/torrent/utils/option_strings.cc | 63 +-
- src/torrent/utils/option_strings.h | 7 +-
- src/torrent/utils/random.cc | 29 +
- src/torrent/utils/random.h | 15 +
- src/torrent/utils/ranges.h | 1 -
- src/torrent/utils/resume.cc | 2 -
- src/torrent/utils/signal_bitfield.h | 3 +-
- src/torrent/utils/thread_base.h | 3 +-
- src/utils/instrumentation.cc | 2 -
- src/utils/instrumentation.h | 3 +-
- src/utils/queue_buckets.h | 4 +-
- src/utils/sha_fast.h | 2 +-
- test/Makefile.am | 29 +-
- test/data/hash_check_queue_test.cc | 2 +-
- test/data/hash_queue_test.cc | 2 +-
- test/helpers/expect_fd.h | 107 ++++
- test/helpers/expect_utils.h | 13 +
- test/helpers/mock_compare.h | 96 +++
- test/helpers/mock_function.cc | 170 ++++++
- test/helpers/mock_function.h | 133 +++++
- test/helpers/network.h | 182 ++++++
- test/helpers/progress_listener.cc | 63 ++
- test/helpers/progress_listener.h | 47 ++
- test/helpers/test_fixture.cc | 18 +
- test/helpers/test_fixture.h | 14 +
- test/helpers/utils.h | 60 ++
- test/main.cc | 82 ++-
- test/net/test_socket_listen.cc | 398 +++++++++++++
- test/net/test_socket_listen.h | 44 ++
- test/torrent/net/test_address_info.cc | 62 ++
- test/torrent/net/test_address_info.h | 19 +
- test/torrent/net/test_fd.cc | 24 +
- test/torrent/net/test_fd.h | 12 +
- test/torrent/net/test_socket_address.cc | 383 ++++++++++++
- test/torrent/net/test_socket_address.h | 43 ++
- test/torrent/net/test_socket_address_key.cc | 87 ---
- test/torrent/object_stream_test.cc | 4 +-
- test/torrent/tracker_controller_features.cc | 2 +-
- test/torrent/tracker_controller_requesting.cc | 2 +-
- test/torrent/tracker_controller_test.cc | 2 +-
- test/torrent/tracker_list_features_test.cc | 2 +-
- test/torrent/utils/directory_events_test.cc | 4 +-
- test/torrent/utils/log_buffer_test.h | 17 -
- test/torrent/utils/log_test.cc | 4 +-
- test/torrent/utils/net_test.cc | 32 -
- test/torrent/utils/net_test.h | 15 -
- test/torrent/utils/option_strings_test.cc | 3 +-
- test/torrent/utils/test_extents.cc | 2 +-
- ...{log_buffer_test.cc => test_log_buffer.cc} | 14 +-
- test/torrent/utils/test_log_buffer.h | 17 +
- test/torrent/utils/test_uri_parser.cc | 2 +-
- test/torrent/utils/thread_base_test.cc | 3 +-
- 152 files changed, 3968 insertions(+), 1110 deletions(-)
- create mode 100644 .dir-locals.el
- create mode 100644 scripts/ssl.m4
- create mode 100644 src/net/socket_listen.cc
- create mode 100644 src/net/socket_listen.h
- create mode 100644 src/torrent/event.cc
- create mode 100644 src/torrent/net/address_info.cc
- create mode 100644 src/torrent/net/address_info.h
- create mode 100644 src/torrent/net/fd.cc
- create mode 100644 src/torrent/net/fd.h
- create mode 100644 src/torrent/net/socket_address.cc
- create mode 100644 src/torrent/net/socket_address.h
- create mode 100644 src/torrent/net/socket_event.cc
- create mode 100644 src/torrent/net/socket_event.h
- create mode 100644 src/torrent/net/types.h
- delete mode 100644 src/torrent/utils/net.cc
- delete mode 100644 src/torrent/utils/net.h
- create mode 100644 src/torrent/utils/random.cc
- create mode 100644 src/torrent/utils/random.h
- create mode 100644 test/helpers/expect_fd.h
- create mode 100644 test/helpers/expect_utils.h
- create mode 100644 test/helpers/mock_compare.h
- create mode 100644 test/helpers/mock_function.cc
- create mode 100644 test/helpers/mock_function.h
- create mode 100644 test/helpers/network.h
- create mode 100644 test/helpers/progress_listener.cc
- create mode 100644 test/helpers/progress_listener.h
- create mode 100644 test/helpers/test_fixture.cc
- create mode 100644 test/helpers/test_fixture.h
- create mode 100644 test/helpers/utils.h
- create mode 100644 test/net/test_socket_listen.cc
- create mode 100644 test/net/test_socket_listen.h
- create mode 100644 test/torrent/net/test_address_info.cc
- create mode 100644 test/torrent/net/test_address_info.h
- create mode 100644 test/torrent/net/test_fd.cc
- create mode 100644 test/torrent/net/test_fd.h
- create mode 100644 test/torrent/net/test_socket_address.cc
- create mode 100644 test/torrent/net/test_socket_address.h
- delete mode 100644 test/torrent/net/test_socket_address_key.cc
- delete mode 100644 test/torrent/utils/log_buffer_test.h
- delete mode 100644 test/torrent/utils/net_test.cc
- delete mode 100644 test/torrent/utils/net_test.h
- rename test/torrent/utils/{log_buffer_test.cc => test_log_buffer.cc} (86%)
- create mode 100644 test/torrent/utils/test_log_buffer.h
-
-diff --git a/.dir-locals.el b/.dir-locals.el
-new file mode 100644
-index 00000000..af1189f2
---- /dev/null
-+++ b/.dir-locals.el
-@@ -0,0 +1,7 @@
-+;;; Directory Local Variables
-+;;; For more information see (info "(emacs) Directory Variables")
-+
-+((c++-mode
-+ (flycheck-clang-language-standard . "c++11")
-+ (flycheck-gcc-language-standard . "c++11")))
-+
-diff --git a/Makefile.am b/Makefile.am
-index f175e634..9507b9ea 100644
---- a/Makefile.am
-+++ b/Makefile.am
-@@ -8,6 +8,7 @@ EXTRA_DIST= \
- scripts/checks.m4 \
- scripts/common.m4 \
- scripts/attributes.m4 \
-+ scripts/ssl.m4 \
- doc/main.xml \
- doc/http.xml \
- doc/torrent.xml \
-diff --git a/configure.ac b/configure.ac
-index 4ed08124..620ca552 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -17,7 +17,7 @@ AC_SUBST(LIBTORRENT_CURRENT)
- AC_SUBST(LIBTORRENT_INTERFACE_VERSION_INFO)
- AC_SUBST(LIBTORRENT_INTERFACE_VERSION_NO)
-
--AM_INIT_AUTOMAKE
-+AM_INIT_AUTOMAKE([serial-tests])
- AC_CONFIG_HEADERS(config.h)
-
- AC_PROG_CXX
-@@ -35,7 +35,6 @@ RAK_ENABLE_EXTRA_DEBUG
- RAK_ENABLE_WERROR
-
- RAK_CHECK_CXX11
--RAK_CHECK_TR1_LIB
-
- AC_SYS_LARGEFILE
-
-@@ -67,41 +66,8 @@ CFLAGS="$PTHREAD_CFLAGS $CPPUNIT_CFLAGS $CFLAGS"
- CXXFLAGS="$PTHREAD_CFLAGS $CPPUNIT_CFLAGS $CXXFLAGS"
- LIBS="$PTHREAD_LIBS $CPPUNIT_LIBS $LIBS"
-
--AC_ARG_ENABLE(openssl,
-- [ --disable-openssl Don't use OpenSSL's SHA1 implementation.],
-- [
-- if test "$enableval" = "yes"; then
--dnl move to scripts.
-- PKG_CHECK_MODULES(OPENSSL, libcrypto,
-- CXXFLAGS="$CXXFLAGS $OPENSSL_CFLAGS";
-- LIBS="$LIBS $OPENSSL_LIBS")
--
-- AC_DEFINE(USE_OPENSSL, 1, Using OpenSSL.)
-- AC_DEFINE(USE_OPENSSL_SHA, 1, Using OpenSSL's SHA1 implementation.)
-- AC_CHECK_LIB([crypto], [DH_set0_pqg], [AC_DEFINE(USE_OPENSSL_1_1, 1, Using OpenSSL 1.1.)])
--
-- else
-- AC_DEFINE(USE_NSS_SHA, 1, Using Mozilla's SHA1 implementation.)
-- fi
-- ],[
-- PKG_CHECK_MODULES(OPENSSL, libcrypto,
-- CXXFLAGS="$CXXFLAGS $OPENSSL_CFLAGS";
-- LIBS="$LIBS $OPENSSL_LIBS")
--
-- AC_DEFINE(USE_OPENSSL, 1, Using OpenSSL.)
-- AC_DEFINE(USE_OPENSSL_SHA, 1, Using OpenSSL's SHA1 implementation.)
-- AC_CHECK_LIB([crypto], [DH_set0_pqg], [AC_DEFINE(USE_OPENSSL_1_1, 1, Using OpenSSL 1.1.)])
-- ]
--)
--
--AC_ARG_ENABLE(cyrus-rc4,
-- [ --enable-cyrus-rc4=PFX Use Cyrus RC4 implementation.],
-- [
-- CXXFLAGS="$CXXFLAGS -I${enableval}/include";
-- LIBS="$LIBS -lrc4 -L${enableval}/lib"
-- AC_DEFINE(USE_CYRUS_RC4, 1, Using Cyrus RC4 implementation.)
-- ]
--)
-+TORRENT_ARG_OPENSSL
-+TORRENT_ARG_CYRUS_RC4
-
- AC_CHECK_FUNCS(posix_memalign)
-
-diff --git a/extra/corrupt_file.cc b/extra/corrupt_file.cc
-index 2a818cc7..7ae906e6 100644
---- a/extra/corrupt_file.cc
-+++ b/extra/corrupt_file.cc
-@@ -1,6 +1,6 @@
- #include <iostream>
- #include <stdexcept>
--#include <inttypes.h>
-+#include <cinttypes>
- #include <stdio.h>
- #include <stdlib.h>
- #include <fcntl.h>
-diff --git a/rak/file_stat.h b/rak/file_stat.h
-index 5ad45e8f..f1ad8c2b 100644
---- a/rak/file_stat.h
-+++ b/rak/file_stat.h
-@@ -38,7 +38,7 @@
- #define RAK_FILE_STAT_H
-
- #include <string>
--#include <inttypes.h>
-+#include <cinttypes>
- #include <sys/stat.h>
-
- namespace rak {
-diff --git a/rak/fs_stat.h b/rak/fs_stat.h
-index 5e844277..2d73ff1b 100644
---- a/rak/fs_stat.h
-+++ b/rak/fs_stat.h
-@@ -38,7 +38,7 @@
- #define RAK_FS_STAT_H
-
- #include <string>
--#include <inttypes.h>
-+#include <cinttypes>
-
- #include <rak/error_number.h>
-
-diff --git a/rak/partial_queue.h b/rak/partial_queue.h
-index 6650a633..1abfdddf 100644
---- a/rak/partial_queue.h
-+++ b/rak/partial_queue.h
-@@ -39,7 +39,7 @@
-
- #include <cstring>
- #include <stdexcept>
--#include <inttypes.h>
-+#include <cinttypes>
-
- namespace rak {
-
-diff --git a/rak/path.h b/rak/path.h
-index bfe8ccc1..64daf355 100644
---- a/rak/path.h
-+++ b/rak/path.h
-@@ -99,7 +99,7 @@ path_expand(const char* src, char* first, char* last) {
- src++;
- }
-
-- return std::max(first + strlcpy(first, src, std::distance(first, last)), last);
-+ return std::min(first + strlcpy(first, src, std::distance(first, last)), last);
- }
-
- }
-diff --git a/rak/priority_queue_default.h b/rak/priority_queue_default.h
-index 01a0070e..a7bba0ce 100644
---- a/rak/priority_queue_default.h
-+++ b/rak/priority_queue_default.h
-@@ -37,7 +37,7 @@
- #ifndef RAK_PRIORITY_QUEUE_DEFAULT_H
- #define RAK_PRIORITY_QUEUE_DEFAULT_H
-
--#include lt_tr1_functional
-+#include <functional>
- #include <rak/allocators.h>
- #include <rak/priority_queue.h>
- #include <rak/timer.h>
-diff --git a/rak/socket_address.h b/rak/socket_address.h
-index 961c53b2..8eb60116 100644
---- a/rak/socket_address.h
-+++ b/rak/socket_address.h
-@@ -47,9 +47,12 @@
- #ifndef RAK_SOCKET_ADDRESS_H
- #define RAK_SOCKET_ADDRESS_H
-
-+#include <cinttypes>
-+#include <cstdint>
- #include <cstring>
--#include <string>
- #include <stdexcept>
-+#include <string>
-+
- #include <arpa/inet.h>
- #include <netinet/in.h>
- #include <sys/types.h>
-@@ -84,7 +87,6 @@ public:
-
- bool is_valid_inet_class() const { return family() == af_inet || family() == af_inet6; }
-
-- // Should we need to set AF_UNSPEC?
- void clear() { std::memset(this, 0, sizeof(socket_address)); set_family(); }
-
- sa_family_t family() const { return m_sockaddr.sa_family; }
-@@ -124,6 +126,7 @@ public:
- // extranous bytes and ensure it does not go beyond the size of this
- // struct.
- void copy(const socket_address& src, size_t length);
-+ void copy_sockaddr(const sockaddr* src);
-
- static socket_address* cast_from(sockaddr* sa) { return reinterpret_cast<socket_address*>(sa); }
- static const socket_address* cast_from(const sockaddr* sa) { return reinterpret_cast<const socket_address*>(sa); }
-@@ -220,6 +223,8 @@ public:
-
- void set_address_any() { set_port(0); set_address(in6addr_any); }
-
-+ std::string pretty_address_str() const;
-+
- sa_family_t family() const { return m_sockaddr.sin6_family; }
- void set_family() { m_sockaddr.sin6_family = AF_INET6; }
-
-@@ -340,7 +345,7 @@ socket_address::pretty_address_str() const {
- case af_inet:
- return sa_inet()->address_str();
- case af_inet6:
-- return sa_inet6()->address_str();
-+ return sa_inet6()->pretty_address_str();
- case af_unspec:
- return std::string("unspec");
- default:
-@@ -380,13 +385,16 @@ socket_address::length() const {
- inline void
- socket_address::copy(const socket_address& src, size_t length) {
- length = std::min(length, sizeof(socket_address));
--
-- // Does this get properly optimized?
-+
- std::memset(this, 0, sizeof(socket_address));
- std::memcpy(this, &src, length);
- }
-
--// Should we be able to compare af_unspec?
-+inline void
-+socket_address::copy_sockaddr(const sockaddr* src) {
-+ std::memset(this, 0, sizeof(socket_address));
-+ std::memcpy(this, src, socket_address::cast_from(src)->length());
-+}
-
- inline bool
- socket_address::operator == (const socket_address& rhs) const {
-@@ -488,6 +496,35 @@ socket_address_inet6::set_address_c_str(const char* a) {
- return inet_pton(AF_INET6, a, &m_sockaddr.sin6_addr);
- }
-
-+inline std::string
-+socket_address_inet6::pretty_address_str() const {
-+ char buf[INET6_ADDRSTRLEN + 2 + 6];
-+
-+ if (inet_ntop(family(), &m_sockaddr.sin6_addr, buf + 1, INET6_ADDRSTRLEN) == NULL)
-+ return std::string();
-+
-+ buf[0] = '[';
-+
-+ char* last_char = (char*)std::memchr(buf + 1, 0, INET6_ADDRSTRLEN);
-+
-+ // TODO: Throw exception here.
-+
-+ if (last_char == NULL || last_char >= buf + 1 + INET6_ADDRSTRLEN)
-+ throw std::logic_error("inet_ntop for inet6 returned bad buffer");
-+
-+ *(last_char++) = ']';
-+
-+ if (!is_port_any()) {
-+ if (snprintf(last_char, 7, ":%" PRIu16, port()) == -1)
-+ return std::string("error"); // TODO: Throw here.
-+
-+ } else {
-+ *last_char = '\0';
-+ }
-+
-+ return std::string(buf);
-+}
-+
- inline socket_address
- socket_address_inet6::normalize_address() const {
- const uint32_t *addr32 = reinterpret_cast<const uint32_t *>(m_sockaddr.sin6_addr.s6_addr);
-diff --git a/rak/timer.h b/rak/timer.h
-index e25ad2e6..842a2e53 100644
---- a/rak/timer.h
-+++ b/rak/timer.h
-@@ -38,7 +38,7 @@
- #define RAK_TIMER_H
-
- #include <limits>
--#include <inttypes.h>
-+#include <cinttypes>
- #include <sys/time.h>
-
- namespace rak {
-diff --git a/scripts/checks.m4 b/scripts/checks.m4
-index 83be8461..98ef17f8 100644
---- a/scripts/checks.m4
-+++ b/scripts/checks.m4
-@@ -88,6 +88,7 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE], [
- [
- AC_DEFINE(USE_KQUEUE, 1, Use kqueue.)
- AC_MSG_RESULT(yes)
-+ TORRENT_CHECK_KQUEUE_SOCKET_ONLY
- ], [
- AC_MSG_RESULT(no)
- ])
-@@ -137,7 +138,6 @@ AC_DEFUN([TORRENT_WITH_KQUEUE], [
- [
- if test "$withval" = "yes"; then
- TORRENT_CHECK_KQUEUE
-- TORRENT_CHECK_KQUEUE_SOCKET_ONLY
- fi
- ])
- ])
-@@ -149,11 +149,9 @@ AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [
- [
- if test "$withval" = "yes"; then
- TORRENT_CHECK_KQUEUE
-- TORRENT_CHECK_KQUEUE_SOCKET_ONLY
- fi
- ], [
- TORRENT_CHECK_KQUEUE
-- TORRENT_CHECK_KQUEUE_SOCKET_ONLY
- ])
- ])
-
-diff --git a/scripts/rak_cxx.m4 b/scripts/rak_cxx.m4
-index 3660f3a7..0db61b83 100644
---- a/scripts/rak_cxx.m4
-+++ b/scripts/rak_cxx.m4
-@@ -12,50 +12,3 @@ AC_DEFUN([RAK_CHECK_CXX11], [
- ]
- )
- ])
--
--AC_DEFUN([RAK_CHECK_TR1_LIB], [
-- AC_LANG_PUSH(C++)
-- AC_MSG_CHECKING(should use TR1 headers)
--
-- AC_COMPILE_IFELSE([AC_LANG_SOURCE([
-- #include <unordered_map>
-- class Foo; typedef std::unordered_map<Foo*, int> Bar;
-- Bar b1;
-- ])
-- ], [
-- AC_MSG_RESULT(no)
-- AC_DEFINE(USE_TR1_LIB, 0, Define to 1 if you need to use TR1 containers.)
--
-- AC_DEFINE([lt_tr1_array], [<array>], [TR1 array])
-- AC_DEFINE([lt_tr1_functional], [<functional>], [TR1 functional])
-- AC_DEFINE([lt_tr1_memory], [<memory>], [TR1 memory])
-- AC_DEFINE([lt_tr1_unordered_map], [<unordered_map>], [TR1 unordered_map])
--
-- ], [
-- AC_COMPILE_IFELSE([AC_LANG_SOURCE([
-- #include <tr1/unordered_map>
-- class Foo; typedef std::tr1::unordered_map<Foo*, int> Bar;
-- Bar b1;
-- ])
-- ], [
-- AC_MSG_RESULT([yes])
-- AC_DEFINE(USE_TR1_LIB, 1, Define to 1 if you need to use TR1 containers.)
--
-- AC_DEFINE([lt_tr1_array], [<tr1/array>], [TR1 array])
-- AC_DEFINE([lt_tr1_functional], [<tr1/functional>], [TR1 functional])
-- AC_DEFINE([lt_tr1_memory], [<tr1/memory>], [TR1 memory])
-- AC_DEFINE([lt_tr1_unordered_map], [<tr1/unordered_map>], [TR1 unordered_map])
--
-- ], [
-- AC_MSG_ERROR([No support for C++11 standard library nor TR1 extensions found.])
-- ])
-- ])
--
-- AH_VERBATIM(lt_tr1_zzz, [
--#if USE_TR1_LIB == 1
--namespace std { namespace tr1 {} using namespace tr1; }
--#endif
--])
--
-- AC_LANG_POP(C++)
--])
-diff --git a/scripts/ssl.m4 b/scripts/ssl.m4
-new file mode 100644
-index 00000000..f07349a1
---- /dev/null
-+++ b/scripts/ssl.m4
-@@ -0,0 +1,38 @@
-+AC_DEFUN([TORRENT_CHECK_OPENSSL],
-+ [
-+ PKG_CHECK_MODULES(OPENSSL, libcrypto,
-+ CXXFLAGS="$CXXFLAGS $OPENSSL_CFLAGS";
-+ LIBS="$LIBS $OPENSSL_LIBS")
-+
-+ AC_DEFINE(USE_OPENSSL, 1, Using OpenSSL.)
-+ AC_DEFINE(USE_OPENSSL_SHA, 1, Using OpenSSL's SHA1 implementation.)
-+ ]
-+)
-+
-+AC_DEFUN([TORRENT_ARG_OPENSSL],
-+ [
-+ AC_ARG_ENABLE(openssl,
-+ [ --disable-openssl Don't use OpenSSL's SHA1 implementation.],
-+ [
-+ if test "$enableval" = "yes"; then
-+ TORRENT_CHECK_OPENSSL
-+ else
-+ AC_DEFINE(USE_NSS_SHA, 1, Using Mozilla's SHA1 implementation.)
-+ fi
-+ ],[
-+ TORRENT_CHECK_OPENSSL
-+ ])
-+ ]
-+)
-+
-+AC_DEFUN([TORRENT_ARG_CYRUS_RC4],
-+ [
-+ AC_ARG_ENABLE(cyrus-rc4,
-+ [ --enable-cyrus-rc4=PFX Use Cyrus RC4 implementation.],
-+ [
-+ CXXFLAGS="$CXXFLAGS -I${enableval}/include";
-+ LIBS="$LIBS -lrc4 -L${enableval}/lib"
-+ AC_DEFINE(USE_CYRUS_RC4, 1, Using Cyrus RC4 implementation.)
-+ ])
-+ ]
-+)
-diff --git a/src/data/chunk_list.cc b/src/data/chunk_list.cc
-index 00abbc2a..7622b825 100644
---- a/src/data/chunk_list.cc
-+++ b/src/data/chunk_list.cc
-@@ -36,8 +36,6 @@
-
- #include "config.h"
-
--#define __STDC_FORMAT_MACROS
--
- #include <rak/error_number.h>
- #include <rak/functional.h>
-
-diff --git a/src/data/chunk_list.h b/src/data/chunk_list.h
-index b6ff4cdb..4b40dc42 100644
---- a/src/data/chunk_list.h
-+++ b/src/data/chunk_list.h
-@@ -37,9 +37,9 @@
- #ifndef LIBTORRENT_DATA_CHUNK_LIST_H
- #define LIBTORRENT_DATA_CHUNK_LIST_H
-
-+#include <functional>
- #include <string>
- #include <vector>
--#include lt_tr1_functional
-
- #include "chunk.h"
- #include "chunk_handle.h"
-diff --git a/src/data/chunk_list_node.h b/src/data/chunk_list_node.h
-index 76de6671..95e4ed4f 100644
---- a/src/data/chunk_list_node.h
-+++ b/src/data/chunk_list_node.h
-@@ -37,7 +37,7 @@
- #ifndef LIBTORRENT_DATA_CHUNK_LIST_NODE_H
- #define LIBTORRENT_DATA_CHUNK_LIST_NODE_H
-
--#include <inttypes.h>
-+#include <cinttypes>
- #include <rak/timer.h>
-
- namespace torrent {
-diff --git a/src/data/hash_check_queue.h b/src/data/hash_check_queue.h
-index b933f137..9f28c118 100644
---- a/src/data/hash_check_queue.h
-+++ b/src/data/hash_check_queue.h
-@@ -38,8 +38,8 @@
- #define LIBTORRENT_DATA_HASH_CHECK_QUEUE_H
-
- #include <deque>
-+#include <functional>
- #include <pthread.h>
--#include lt_tr1_functional
-
- #include "rak/allocators.h"
-
-diff --git a/src/data/hash_queue.cc b/src/data/hash_queue.cc
-index 7dffaee4..3f54892b 100644
---- a/src/data/hash_queue.cc
-+++ b/src/data/hash_queue.cc
-@@ -36,8 +36,6 @@
-
- #include "config.h"
-
--#define __STDC_FORMAT_MACROS
--
- #include <functional>
- #include <rak/functional.h>
- #include <unistd.h>
-diff --git a/src/data/hash_queue.h b/src/data/hash_queue.h
-index 6885a383..3a841967 100644
---- a/src/data/hash_queue.h
-+++ b/src/data/hash_queue.h
-@@ -38,9 +38,9 @@
- #define LIBTORRENT_DATA_HASH_QUEUE_H
-
- #include <deque>
-+#include <functional>
- #include <map>
- #include <pthread.h>
--#include lt_tr1_functional
-
- #include "torrent/hash_string.h"
- #include "hash_queue_node.h"
-diff --git a/src/data/hash_queue_node.h b/src/data/hash_queue_node.h
-index aa59a062..c8367b7c 100644
---- a/src/data/hash_queue_node.h
-+++ b/src/data/hash_queue_node.h
-@@ -37,9 +37,9 @@
- #ifndef LIBTORRENT_DATA_HASH_QUEUE_NODE_H
- #define LIBTORRENT_DATA_HASH_QUEUE_NODE_H
-
-+#include <cinttypes>
-+#include <functional>
- #include <string>
--#include lt_tr1_functional
--#include <inttypes.h>
-
- #include "chunk_handle.h"
- #include "hash_chunk.h"
-diff --git a/src/data/hash_torrent.cc b/src/data/hash_torrent.cc
-index 758a10fa..e803f1cb 100644
---- a/src/data/hash_torrent.cc
-+++ b/src/data/hash_torrent.cc
-@@ -36,8 +36,6 @@
-
- #include "config.h"
-
--#define __STDC_FORMAT_MACROS
--
- #include "data/chunk_list.h"
- #include "torrent/exceptions.h"
- #include "torrent/data/download_data.h"
-diff --git a/src/data/hash_torrent.h b/src/data/hash_torrent.h
-index 6af643f2..9ce2f100 100644
---- a/src/data/hash_torrent.h
-+++ b/src/data/hash_torrent.h
-@@ -37,9 +37,9 @@
- #ifndef LIBTORRENT_DATA_HASH_TORRENT_H
- #define LIBTORRENT_DATA_HASH_TORRENT_H
-
-+#include <cinttypes>
-+#include <functional>
- #include <string>
--#include <inttypes.h>
--#include lt_tr1_functional
- #include <rak/priority_queue_default.h>
-
- #include "data/chunk_handle.h"
-diff --git a/src/data/memory_chunk.h b/src/data/memory_chunk.h
-index cc32eff1..d2b5565d 100644
---- a/src/data/memory_chunk.h
-+++ b/src/data/memory_chunk.h
-@@ -38,7 +38,7 @@
- #define LIBTORRENT_DATA_MEMORY_CHUNK_H
-
- #include <algorithm>
--#include <inttypes.h>
-+#include <cinttypes>
- #include <sys/mman.h>
- #include <cstddef>
-
-diff --git a/src/data/socket_file.h b/src/data/socket_file.h
-index 7b27af8c..d25c4a44 100644
---- a/src/data/socket_file.h
-+++ b/src/data/socket_file.h
-@@ -38,7 +38,7 @@
- #define LIBTORRENT_SOCKET_FILE_H
-
- #include <string>
--#include <inttypes.h>
-+#include <cinttypes>
- #include <fcntl.h>
- #include <sys/types.h>
-
-diff --git a/src/dht/dht_hash_map.h b/src/dht/dht_hash_map.h
-index 140f070b..1506db56 100644
---- a/src/dht/dht_hash_map.h
-+++ b/src/dht/dht_hash_map.h
-@@ -39,20 +39,14 @@
-
- #include "config.h"
-
--#if HAVE_TR1
--#include <lt_tr1_unordered_map>
--#else
--#include <map>
--#endif
--
--#include "torrent/hash_string.h"
-+#include <unordered_map>
-
- #include "dht_node.h"
- #include "dht_tracker.h"
-+#include "torrent/hash_string.h"
-
- namespace torrent {
-
--#if HAVE_TR1
- // Hash functions for HashString keys, and dereferencing HashString pointers.
-
- // Since the first few bits are very similar if not identical (since the IDs
-@@ -142,53 +136,6 @@ public:
-
- };
-
--#else
--
--// Compare HashString pointers by dereferencing them.
--struct hashstring_ptr_less : public std::binary_function<const HashString*, const HashString*, bool> {
-- size_t operator () (const HashString* one, const HashString* two) const
-- { return *one < *two; }
--};
--
--class DhtNodeList : public std::map<const HashString*, DhtNode*, hashstring_ptr_less> {
--public:
-- typedef std::map<const HashString*, DhtNode*, hashstring_ptr_less> base_type;
--
-- // Define accessor iterator with more convenient access to the key and
-- // element values. Allows changing the map definition more easily if needed.
-- template<typename T>
-- struct accessor_wrapper : public T {
-- accessor_wrapper(const T& itr) : T(itr) { }
--
-- const HashString& id() const { return *(**this).first; }
-- DhtNode* node() const { return (**this).second; }
-- };
--
-- typedef accessor_wrapper<const_iterator> const_accessor;
-- typedef accessor_wrapper<iterator> accessor;
--
-- DhtNode* add_node(DhtNode* n);
--
--};
--
--class DhtTrackerList : public std::map<HashString, DhtTracker*> {
--public:
-- typedef std::map<HashString, DhtTracker*> base_type;
--
-- template<typename T>
-- struct accessor_wrapper : public T {
-- accessor_wrapper(const T& itr) : T(itr) { }
--
-- const HashString& id() const { return (**this).first; }
-- DhtTracker* tracker() const { return (**this).second; }
-- };
--
-- typedef accessor_wrapper<const_iterator> const_accessor;
-- typedef accessor_wrapper<iterator> accessor;
--
--};
--#endif // HAVE_TR1
--
- inline
- DhtNode* DhtNodeList::add_node(DhtNode* n) {
- insert(std::make_pair((const HashString*)n, (DhtNode*)n));
-diff --git a/src/download/chunk_selector.h b/src/download/chunk_selector.h
-index 52c31fd5..ab1b8c17 100644
---- a/src/download/chunk_selector.h
-+++ b/src/download/chunk_selector.h
-@@ -37,7 +37,7 @@
- #ifndef LIBTORRENT_DOWNLOAD_CHUNK_SELECTOR_H
- #define LIBTORRENT_DOWNLOAD_CHUNK_SELECTOR_H
-
--#include <inttypes.h>
-+#include <cinttypes>
- #include <rak/partial_queue.h>
-
- #include "torrent/bitfield.h"
-diff --git a/src/download/chunk_statistics.h b/src/download/chunk_statistics.h
-index 816ec6c9..62f76c5a 100644
---- a/src/download/chunk_statistics.h
-+++ b/src/download/chunk_statistics.h
-@@ -37,7 +37,7 @@
- #ifndef LIBTORRENT_DOWNLOAD_CHUNK_STATISTICS_H
- #define LIBTORRENT_DOWNLOAD_CHUNK_STATISTICS_H
-
--#include <inttypes.h>
-+#include <cinttypes>
- #include <vector>
-
- namespace torrent {
-diff --git a/src/download/delegator.cc b/src/download/delegator.cc
-index 711cd461..27ae42ec 100644
---- a/src/download/delegator.cc
-+++ b/src/download/delegator.cc
-@@ -39,7 +39,7 @@
- #include "config.h"
-
- #include <algorithm>
--#include <inttypes.h>
-+#include <cinttypes>
-
- #include "torrent/exceptions.h"
- #include "torrent/bitfield.h"
-diff --git a/src/download/delegator.h b/src/download/delegator.h
-index 3b997b81..b75d4c2a 100644
---- a/src/download/delegator.h
-+++ b/src/download/delegator.h
-@@ -37,9 +37,9 @@
- #ifndef LIBTORRENT_DELEGATOR_H
- #define LIBTORRENT_DELEGATOR_H
-
-+#include <functional>
- #include <string>
- #include <vector>
--#include lt_tr1_functional
-
- #include "torrent/data/transfer_list.h"
-
-diff --git a/src/download/download_constructor.h b/src/download/download_constructor.h
-index 7d43aba3..6a09b7f1 100644
---- a/src/download/download_constructor.h
-+++ b/src/download/download_constructor.h
-@@ -39,7 +39,7 @@
-
- #include <list>
- #include <string>
--#include <inttypes.h>
-+#include <cinttypes>
-
- namespace torrent {
-
-diff --git a/src/globals.cc b/src/globals.cc
-index 88130c19..20644fbd 100644
---- a/src/globals.cc
-+++ b/src/globals.cc
-@@ -37,11 +37,24 @@
- #include "config.h"
-
- #include "globals.h"
--#include "torrent/common.h"
-+#include "manager.h"
-+#include "torrent/connection_manager.h"
-+#include "torrent/event.h"
-+#include "torrent/poll.h"
-
- namespace torrent {
-
- LIBTORRENT_EXPORT rak::priority_queue_default taskScheduler;
- LIBTORRENT_EXPORT rak::timer cachedTime;
-
-+void poll_event_open(Event* event) { manager->poll()->open(event); manager->connection_manager()->inc_socket_count(); }
-+void poll_event_close(Event* event) { manager->poll()->close(event); manager->connection_manager()->dec_socket_count(); }
-+void poll_event_closed(Event* event) { manager->poll()->closed(event); manager->connection_manager()->dec_socket_count(); }
-+void poll_event_insert_read(Event* event) { manager->poll()->insert_read(event); }
-+void poll_event_insert_write(Event* event) { manager->poll()->insert_write(event); }
-+void poll_event_insert_error(Event* event) { manager->poll()->insert_error(event); }
-+void poll_event_remove_read(Event* event) { manager->poll()->remove_read(event); }
-+void poll_event_remove_write(Event* event) { manager->poll()->remove_write(event); }
-+void poll_event_remove_error(Event* event) { manager->poll()->remove_error(event); }
-+
- }
-diff --git a/src/globals.h b/src/globals.h
-index 564ac86d..e9fe1177 100644
---- a/src/globals.h
-+++ b/src/globals.h
-@@ -1,39 +1,3 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #ifndef LIBTORRENT_GLOBALS_H
- #define LIBTORRENT_GLOBALS_H
-
-diff --git a/src/manager.cc b/src/manager.cc
-index c503974d..11ef4b0f 100644
---- a/src/manager.cc
-+++ b/src/manager.cc
-@@ -1,39 +1,3 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #include "config.h"
-
- #include "torrent/exceptions.h"
-diff --git a/src/net/Makefile.am b/src/net/Makefile.am
-index fb4da4f3..e3a8c7e1 100644
---- a/src/net/Makefile.am
-+++ b/src/net/Makefile.am
-@@ -15,6 +15,8 @@ libsub_net_la_SOURCES = \
- socket_datagram.h \
- socket_fd.cc \
- socket_fd.h \
-+ socket_listen.cc \
-+ socket_listen.h \
- socket_set.cc \
- socket_set.h \
- socket_stream.cc \
-diff --git a/src/net/data_buffer.h b/src/net/data_buffer.h
-index d35cdc48..5dd0cb30 100644
---- a/src/net/data_buffer.h
-+++ b/src/net/data_buffer.h
-@@ -38,7 +38,7 @@
- #define LIBTORRENT_NET_DATA_BUFFER_H
-
- #include <memory>
--#include <inttypes.h>
-+#include <cinttypes>
-
- namespace torrent {
-
-diff --git a/src/net/listen.cc b/src/net/listen.cc
-index d424e94c..61fedbf8 100644
---- a/src/net/listen.cc
-+++ b/src/net/listen.cc
-@@ -1,39 +1,3 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #include "config.h"
-
- #define __STDC_FORMAT_MACROS
-@@ -95,7 +59,7 @@ Listen::open(uint16_t first, uint16_t last, int backlog, const rak::socket_addre
- manager->poll()->insert_read(this);
- manager->poll()->insert_error(this);
-
-- lt_log_print(LOG_CONNECTION_INFO, "listen port %" PRIu16 " opened with backlog set to %i",
-+ lt_log_print(LOG_CONNECTION_LISTEN, "listen port %" PRIu16 " opened with backlog set to %i",
- m_port, backlog);
-
- return true;
-@@ -107,7 +71,7 @@ Listen::open(uint16_t first, uint16_t last, int backlog, const rak::socket_addre
- get_fd().close();
- get_fd().clear();
-
-- lt_log_print(LOG_CONNECTION_INFO, "failed to open listen port");
-+ lt_log_print(LOG_CONNECTION_LISTEN, "failed to open listen port");
-
- return false;
- }
-diff --git a/src/net/listen.h b/src/net/listen.h
-index b3c845aa..58c06c7e 100644
---- a/src/net/listen.h
-+++ b/src/net/listen.h
-@@ -37,8 +37,8 @@
- #ifndef LIBTORRENT_LISTEN_H
- #define LIBTORRENT_LISTEN_H
-
--#include <inttypes.h>
--#include lt_tr1_functional
-+#include <cinttypes>
-+#include <functional>
- #include <rak/socket_address.h>
-
- #include "socket_base.h"
-diff --git a/src/net/protocol_buffer.h b/src/net/protocol_buffer.h
-index b64d47ea..f9711ded 100644
---- a/src/net/protocol_buffer.h
-+++ b/src/net/protocol_buffer.h
-@@ -38,7 +38,7 @@
- #define LIBTORRENT_NET_PROTOCOL_BUFFER_H
-
- #include <memory>
--#include <inttypes.h>
-+#include <cinttypes>
- #include <netinet/in.h>
-
- #include "torrent/exceptions.h"
-diff --git a/src/net/socket_base.h b/src/net/socket_base.h
-index 02c9497d..20ae1d9f 100644
---- a/src/net/socket_base.h
-+++ b/src/net/socket_base.h
-@@ -38,7 +38,7 @@
- #define LIBTORRENT_NET_SOCKET_BASE_H
-
- #include <list>
--#include <inttypes.h>
-+#include <cinttypes>
-
- #include "torrent/event.h"
- #include "socket_fd.h"
-diff --git a/src/net/socket_fd.cc b/src/net/socket_fd.cc
-index f04059f6..c36ff4b9 100644
---- a/src/net/socket_fd.cc
-+++ b/src/net/socket_fd.cc
-@@ -210,6 +210,11 @@ SocketFd::bind(const rak::socket_address& sa, unsigned int length) {
- return !::bind(m_fd, sa.c_sockaddr(), length);
- }
-
-+bool
-+SocketFd::bind_sa(const sockaddr* sa) {
-+ return bind(*rak::socket_address::cast_from(sa));
-+}
-+
- bool
- SocketFd::connect(const rak::socket_address& sa) {
- check_valid();
-@@ -222,6 +227,11 @@ SocketFd::connect(const rak::socket_address& sa) {
- return !::connect(m_fd, sa.c_sockaddr(), sa.length()) || errno == EINPROGRESS;
- }
-
-+bool
-+SocketFd::connect_sa(const sockaddr* sa) {
-+ return connect(*rak::socket_address::cast_from(sa));
-+}
-+
- bool
- SocketFd::getsockname(rak::socket_address *sa) {
- check_valid();
-diff --git a/src/net/socket_fd.h b/src/net/socket_fd.h
-index 2329b4e9..4db0087b 100644
---- a/src/net/socket_fd.h
-+++ b/src/net/socket_fd.h
-@@ -39,6 +39,8 @@
-
- #include <unistd.h>
-
-+struct sockaddr;
-+
- namespace rak {
- class socket_address;
- }
-@@ -80,7 +82,11 @@ public:
-
- bool bind(const rak::socket_address& sa);
- bool bind(const rak::socket_address& sa, unsigned int length);
-+ bool bind_sa(const sockaddr* sa);
-+
- bool connect(const rak::socket_address& sa);
-+ bool connect_sa(const sockaddr* sa);
-+
- bool getsockname(rak::socket_address* sa);
-
- bool listen(int size);
-diff --git a/src/net/socket_listen.cc b/src/net/socket_listen.cc
-new file mode 100644
-index 00000000..97f006e0
---- /dev/null
-+++ b/src/net/socket_listen.cc
-@@ -0,0 +1,137 @@
-+#include "config.h"
-+
-+#include "socket_listen.h"
-+
-+#include <algorithm>
-+
-+#include "torrent/connection_manager.h"
-+#include "torrent/exceptions.h"
-+#include "torrent/utils/log.h"
-+#include "torrent/utils/random.h"
-+
-+#define LT_LOG_SAP(log_fmt, sap, ...) \
-+ lt_log_print(LOG_CONNECTION_LISTEN, "listen->%s: " log_fmt, sap_pretty_str(sap).c_str(), __VA_ARGS__);
-+
-+namespace torrent {
-+
-+socket_listen::socket_listen() : m_backlog(SOMAXCONN) {
-+}
-+
-+void
-+socket_listen::set_backlog(int backlog) {
-+ if (backlog < 0 || backlog > SOMAXCONN)
-+ throw internal_error("Could not set socket_listen backlog, out-of-range value.");
-+
-+ m_backlog = backlog;
-+}
-+
-+bool
-+socket_listen::open(sa_unique_ptr&& sap, uint16_t first_port, uint16_t last_port, uint16_t start_port, fd_flags open_flags) {
-+ if (is_open())
-+ throw internal_error("socket_listen::open: already open");
-+
-+ if (!(sap_is_inet(sap) || sap_is_inet6(sap)) || sap_is_v4mapped(sap) || !sap_is_port_any(sap) || sap_is_broadcast(sap))
-+ throw internal_error("socket_listen::open: socket address must be inet/inet6 with no port, and not v4mapped nor broadcast: " + sap_pretty_str(sap));
-+
-+ if (sap_is_inet(sap) && !(open_flags & fd_flag_v4only))
-+ throw internal_error("socket_listen::open: socket address is inet without v4only flag");
-+
-+ if (first_port == 0 || last_port == 0 || start_port == 0 ||
-+ !(first_port <= last_port && first_port <= start_port && start_port <= last_port))
-+ throw internal_error("socket_listen::open: port range not valid");
-+
-+ int fd = fd_open(open_flags);
-+
-+ if (fd == -1) {
-+ LT_LOG_SAP("open failed (flags:0x%x errno:%i message:'%s')", sap, open_flags, errno, std::strerror(errno));
-+ return false;
-+ }
-+
-+ uint16_t p = start_port;
-+
-+ do {
-+ if (m_open_port(fd, sap, p))
-+ return is_open();
-+
-+ if (p == last_port)
-+ p = first_port;
-+ else
-+ p++;
-+ } while (p != start_port);
-+
-+ LT_LOG_SAP("listen ports exhausted (fd:%i first_port:%" PRIu16 " last_port:%" PRIu16 ")",
-+ sap, fd, first_port, last_port);
-+ fd_close(fd);
-+ return false;
-+}
-+
-+bool
-+socket_listen::open_randomize(sa_unique_ptr&& sap, uint16_t first_port, uint16_t last_port, fd_flags open_flags) {
-+ if (last_port < first_port)
-+ throw internal_error("socket_listen::open_randomize: port range not valid");
-+
-+ return open(std::move(sap), first_port, last_port, random_uniform_uint16(first_port, last_port), open_flags);
-+}
-+
-+bool
-+socket_listen::open_sequential(sa_unique_ptr&& sap, uint16_t first_port, uint16_t last_port, fd_flags open_flags) {
-+ return open(std::move(sap), first_port, last_port, first_port, open_flags);
-+}
-+
-+void
-+socket_listen::close() {
-+ if (!is_open())
-+ return;
-+
-+ torrent::poll_event_closed(this);
-+
-+ fd_close(file_descriptor());
-+ set_file_descriptor(-1);
-+ m_socket_address.reset();
-+}
-+
-+void
-+socket_listen::event_read() {
-+}
-+
-+void
-+socket_listen::event_error() {
-+}
-+
-+// Returns true if open is successful or if we cannot bind to the
-+// address, returns false if other ports can be used.
-+bool
-+socket_listen::m_open_port(int fd, sa_unique_ptr& sap, uint16_t port) {
-+ sap_set_port(sap, port);
-+
-+ if (!fd_bind(fd, sap.get())) {
-+ if (errno == EADDRNOTAVAIL || errno == EAFNOSUPPORT) {
-+ LT_LOG_SAP("listen address not usable (fd:%i errno:%i message:'%s')",
-+ sap, fd, errno, std::strerror(errno));
-+ fd_close(fd);
-+ return true;
-+ }
-+
-+ return false;
-+ }
-+
-+ if (!fd_listen(fd, m_backlog)) {
-+ LT_LOG_SAP("call to listen failed (fd:%i backlog:%i errno:%i message:'%s')",
-+ sap, fd, m_backlog, errno, std::strerror(errno));
-+ fd_close(fd);
-+ return true;
-+ }
-+
-+ LT_LOG_SAP("open listen port success (fd:%i backlog:%i)", sap, fd, m_backlog);
-+
-+ m_fileDesc = fd;
-+ m_socket_address.swap(sap);
-+
-+ torrent::poll_event_open(this);
-+ torrent::poll_event_insert_read(this);
-+ torrent::poll_event_insert_error(this);
-+
-+ return true;
-+}
-+
-+}
-diff --git a/src/net/socket_listen.h b/src/net/socket_listen.h
-new file mode 100644
-index 00000000..817d5fa5
---- /dev/null
-+++ b/src/net/socket_listen.h
-@@ -0,0 +1,46 @@
-+#ifndef LIBTORRENT_SOCKET_LISTEN_H
-+#define LIBTORRENT_SOCKET_LISTEN_H
-+
-+#include <cinttypes>
-+#include <functional>
-+
-+#include "torrent/net/fd.h"
-+#include "torrent/net/socket_address.h"
-+#include "torrent/net/socket_event.h"
-+
-+namespace torrent {
-+
-+class socket_listen : public socket_event {
-+public:
-+ typedef std::function<void (int, sa_unique_ptr)> accepted_ftor;
-+
-+ socket_listen();
-+
-+ int backlog() const;
-+
-+ void set_backlog(int backlog);
-+ void set_slot_accepted(accepted_ftor&& ftor);
-+
-+ bool open(sa_unique_ptr&& sap, uint16_t first_port, uint16_t last_port, uint16_t start_port, fd_flags open_flags);
-+ bool open_randomize(sa_unique_ptr&& sap, uint16_t first_port, uint16_t last_port, fd_flags open_flags);
-+ bool open_sequential(sa_unique_ptr&& sap, uint16_t first_port, uint16_t last_port, fd_flags open_flags);
-+ void close();
-+
-+ void event_read() override;
-+ void event_error() override;
-+
-+ const char* type_name() const override { return "socket_listen"; }
-+
-+private:
-+ bool m_open_port(int fd, sa_unique_ptr& sap, uint16_t port);
-+
-+ int m_backlog;
-+ accepted_ftor m_slot_accepted;
-+};
-+
-+inline int socket_listen::backlog() const { return m_backlog; }
-+inline void socket_listen::set_slot_accepted(accepted_ftor&& ftor) { m_slot_accepted = ftor; }
-+
-+}
-+
-+#endif
-diff --git a/src/net/socket_set.h b/src/net/socket_set.h
-index 9264edf7..78443c88 100644
---- a/src/net/socket_set.h
-+++ b/src/net/socket_set.h
-@@ -39,7 +39,7 @@
-
- #include <list>
- #include <vector>
--#include <inttypes.h>
-+#include <cinttypes>
- #include <rak/allocators.h>
-
- #include "torrent/exceptions.h"
-diff --git a/src/net/throttle_node.h b/src/net/throttle_node.h
-index 77cb6cc7..5af27a22 100644
---- a/src/net/throttle_node.h
-+++ b/src/net/throttle_node.h
-@@ -37,7 +37,7 @@
- #ifndef LIBTORRENT_NET_THROTTLE_NODE_H
- #define LIBTORRENT_NET_THROTTLE_NODE_H
-
--#include lt_tr1_functional
-+#include <functional>
-
- #include "torrent/rate.h"
-
-diff --git a/src/protocol/handshake.cc b/src/protocol/handshake.cc
-index 6b41bbe3..1b877c7a 100644
---- a/src/protocol/handshake.cc
-+++ b/src/protocol/handshake.cc
-@@ -46,6 +46,7 @@
- #include "torrent/error.h"
- #include "torrent/poll.h"
- #include "torrent/throttle.h"
-+#include "torrent/utils/log.h"
- #include "utils/diffie_hellman.h"
-
- #include "globals.h"
-@@ -55,6 +56,10 @@
- #include "handshake.h"
- #include "handshake_manager.h"
-
-+#define LT_LOG(log_fmt, ...) \
-+ lt_log_print(LOG_CONNECTION_HANDSHAKE, "handshake->%s: " log_fmt, \
-+ m_address.pretty_address_str().c_str(), __VA_ARGS__);
-+
- namespace torrent {
-
- const char* Handshake::m_protocol = "BitTorrent protocol";
-@@ -862,7 +867,7 @@ restart:
- m_manager->receive_failed(this, e.type(), e.error());
-
- } catch (network_error& e) {
-- m_manager->receive_failed(this, ConnectionManager::handshake_failed, e_handshake_network_error);
-+ m_manager->receive_failed(this, ConnectionManager::handshake_failed, e_handshake_network_read_error);
- }
- }
-
-@@ -969,7 +974,7 @@ Handshake::event_write() {
- m_manager->receive_failed(this, e.type(), e.error());
-
- } catch (network_error& e) {
-- m_manager->receive_failed(this, ConnectionManager::handshake_failed, e_handshake_network_error);
-+ m_manager->receive_failed(this, ConnectionManager::handshake_failed, e_handshake_network_write_error);
- }
- }
-
-@@ -1070,7 +1075,7 @@ Handshake::prepare_peer_info() {
- m_peerInfo = m_download->peer_list()->connected(m_address.c_sockaddr(), PeerList::connect_incoming);
-
- if (m_peerInfo == NULL)
-- throw handshake_error(ConnectionManager::handshake_failed, e_handshake_network_error);
-+ throw handshake_error(ConnectionManager::handshake_failed, e_handshake_no_peer_info);
-
- if (m_peerInfo->failed_counter() > m_manager->max_failed)
- throw handshake_error(ConnectionManager::handshake_dropped, e_handshake_toomanyfailed);
-@@ -1221,7 +1226,7 @@ Handshake::event_error() {
- if (m_state == INACTIVE)
- throw internal_error("Handshake::event_error() called on an inactive handshake.");
-
-- m_manager->receive_failed(this, ConnectionManager::handshake_failed, e_handshake_network_error);
-+ m_manager->receive_failed(this, ConnectionManager::handshake_failed, e_handshake_network_socket_error);
- }
-
- }
-diff --git a/src/protocol/handshake_manager.cc b/src/protocol/handshake_manager.cc
-index b52c8d4e..99592ba8 100644
---- a/src/protocol/handshake_manager.cc
-+++ b/src/protocol/handshake_manager.cc
-@@ -1,39 +1,3 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #include "config.h"
-
- #include <rak/socket_address.h>
-@@ -54,10 +18,10 @@
-
- #include "manager.h"
-
--#define LT_LOG_SA(log_level, sa, log_fmt, ...) \
-- lt_log_print(LOG_CONNECTION_##log_level, "handshake_manager->%s: " log_fmt, (sa)->address_str().c_str(), __VA_ARGS__);
--#define LT_LOG_SA_C(log_level, sa, log_fmt, ...) \
-- lt_log_print(LOG_CONNECTION_##log_level, "handshake_manager->%s: " log_fmt, \
-+#define LT_LOG_SA(sa, log_fmt, ...) \
-+ lt_log_print(LOG_CONNECTION_HANDSHAKE, "handshake_manager->%s: " log_fmt, (sa)->address_str().c_str(), __VA_ARGS__);
-+#define LT_LOG_SA_C(sa, log_fmt, ...) \
-+ lt_log_print(LOG_CONNECTION_HANDSHAKE, "handshake_manager->%s: " log_fmt, \
- reinterpret_cast<const rak::socket_address*>(sa)->address_str().c_str(), __VA_ARGS__);
-
- namespace torrent {
-@@ -122,7 +86,7 @@ HandshakeManager::add_incoming(SocketFd fd, const rak::socket_address& sa) {
- return;
- }
-
-- LT_LOG_SA(INFO, &sa, "Adding incoming connection: fd:%i.", fd.get_fd());
-+ LT_LOG_SA(&sa, "Adding incoming connection: fd:%i.", fd.get_fd());
-
- manager->connection_manager()->inc_socket_count();
-
-@@ -183,7 +147,7 @@ HandshakeManager::create_outgoing(const rak::socket_address& sa, DownloadMain* d
- else
- message = ConnectionManager::handshake_outgoing;
-
-- LT_LOG_SA(INFO, &sa, "Adding outcoming connection: encryption:%x message:%x.", encryptionOptions, message);
-+ LT_LOG_SA(&sa, "Adding outcoming connection: encryption:%x message:%x.", encryptionOptions, message);
- manager->connection_manager()->inc_socket_count();
-
- Handshake* handshake = new Handshake(fd, this, encryptionOptions);
-@@ -213,7 +177,7 @@ HandshakeManager::receive_succeeded(Handshake* handshake) {
- handshake->extensions())) != NULL) {
-
- manager->client_list()->retrieve_id(&handshake->peer_info()->mutable_client_info(), handshake->peer_info()->id());
-- LT_LOG_SA_C(INFO, handshake->peer_info()->socket_address(), "Handshake success.", 0);
-+ LT_LOG_SA_C(handshake->peer_info()->socket_address(), "Handshake success.", 0);
-
- pcb->peer_chunks()->set_have_timer(handshake->initialized_time());
-
-@@ -237,7 +201,7 @@ HandshakeManager::receive_succeeded(Handshake* handshake) {
- else
- reason = e_handshake_duplicate;
-
-- LT_LOG_SA_C(INFO, handshake->peer_info()->socket_address(), "Handshake dropped: %s.", strerror(reason));
-+ LT_LOG_SA_C(handshake->peer_info()->socket_address(), "Handshake dropped: %s.", strerror(reason));
- handshake->destroy_connection();
- }
-
-@@ -255,13 +219,13 @@ HandshakeManager::receive_failed(Handshake* handshake, int message, int error) {
- handshake->deactivate_connection();
- handshake->destroy_connection();
-
-- LT_LOG_SA(INFO, sa, "Received error: message:%x %s.", message, strerror(error));
-+ LT_LOG_SA(sa, "Received error: message:%x %s.", message, strerror(error));
-
- if (handshake->encryption()->should_retry()) {
- int retry_options = handshake->retry_options() | ConnectionManager::encryption_retrying;
- DownloadMain* download = handshake->download();
-
-- LT_LOG_SA(INFO, sa, "Retrying %s.",
-+ LT_LOG_SA(sa, "Retrying %s.",
- retry_options & ConnectionManager::encryption_try_outgoing ? "encrypted" : "plaintext");
-
- create_outgoing(*sa, download, retry_options);
-diff --git a/src/protocol/handshake_manager.h b/src/protocol/handshake_manager.h
-index cfd52aa0..dc398e3e 100644
---- a/src/protocol/handshake_manager.h
-+++ b/src/protocol/handshake_manager.h
-@@ -1,45 +1,9 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #ifndef LIBTORRENT_NET_HANDSHAKE_MANAGER_H
- #define LIBTORRENT_NET_HANDSHAKE_MANAGER_H
-
--#include <string>
-+#include <functional>
- #include <inttypes.h>
--#include lt_tr1_functional
-+#include <string>
- #include <rak/functional.h>
- #include <rak/unordered_vector.h>
- #include <rak/socket_address.h>
-diff --git a/src/protocol/peer_connection_base.cc b/src/protocol/peer_connection_base.cc
-index c02998fb..bd870425 100644
---- a/src/protocol/peer_connection_base.cc
-+++ b/src/protocol/peer_connection_base.cc
-@@ -36,8 +36,6 @@
-
- #include "config.h"
-
--#define __STDC_FORMAT_MACROS
--
- #include <cstdio>
- #include <fcntl.h>
- #include <rak/error_number.h>
-diff --git a/src/protocol/request_list.cc b/src/protocol/request_list.cc
-index a4338bcb..ea5d388a 100644
---- a/src/protocol/request_list.cc
-+++ b/src/protocol/request_list.cc
-@@ -1,44 +1,8 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #include "config.h"
-
- #include <algorithm>
- #include <functional>
--#include <inttypes.h>
-+#include <cinttypes>
- #include <rak/functional.h>
-
- #include "torrent/data/block.h"
-diff --git a/src/torrent/Makefile.am b/src/torrent/Makefile.am
-index 1bdfde3d..8cd26ce7 100644
---- a/src/torrent/Makefile.am
-+++ b/src/torrent/Makefile.am
-@@ -22,6 +22,7 @@ libsub_torrent_la_SOURCES = \
- download_info.h \
- error.cc \
- error.h \
-+ event.cc \
- event.h \
- exceptions.cc \
- exceptions.h \
-diff --git a/src/torrent/common.h b/src/torrent/common.h
-index 3363143d..42cc3246 100644
---- a/src/torrent/common.h
-+++ b/src/torrent/common.h
-@@ -37,10 +37,13 @@
- #ifndef LIBTORRENT_COMMON_H
- #define LIBTORRENT_COMMON_H
-
--#include <inttypes.h>
-+#include <cinttypes>
- #include <cstddef>
-
- struct sockaddr;
-+struct sockaddr_in;
-+struct sockaddr_in6;
-+struct sockaddr_un;
-
- namespace torrent {
-
-diff --git a/src/torrent/connection_manager.h b/src/torrent/connection_manager.h
-index 2dcf2b37..cf43b0bf 100644
---- a/src/torrent/connection_manager.h
-+++ b/src/torrent/connection_manager.h
-@@ -39,13 +39,13 @@
- #ifndef LIBTORRENT_CONNECTION_MANAGER_H
- #define LIBTORRENT_CONNECTION_MANAGER_H
-
-+#include <functional>
- #include <list>
- #include <arpa/inet.h>
- #include <netinet/in.h>
- #include <netinet/in_systm.h>
- #include <netinet/ip.h>
- #include <sys/socket.h>
--#include lt_tr1_functional
- #include <torrent/common.h>
-
- namespace torrent {
-diff --git a/src/torrent/data/download_data.h b/src/torrent/data/download_data.h
-index 2b9c9412..fc212047 100644
---- a/src/torrent/data/download_data.h
-+++ b/src/torrent/data/download_data.h
-@@ -37,7 +37,7 @@
- #ifndef LIBTORRENT_DATA_DOWNLOAD_DATA_H
- #define LIBTORRENT_DATA_DOWNLOAD_DATA_H
-
--#include lt_tr1_functional
-+#include <functional>
-
- #include <torrent/common.h>
- #include <torrent/bitfield.h>
-diff --git a/src/torrent/data/file_list.cc b/src/torrent/data/file_list.cc
-index 4721bdbd..2e334fa8 100644
---- a/src/torrent/data/file_list.cc
-+++ b/src/torrent/data/file_list.cc
-@@ -36,8 +36,6 @@
-
- #include "config.h"
-
--#define __STDC_FORMAT_MACROS
--
- #include <algorithm>
- #include <cstring>
- #include <functional>
-diff --git a/src/torrent/data/transfer_list.h b/src/torrent/data/transfer_list.h
-index 0a359b5e..9813af12 100644
---- a/src/torrent/data/transfer_list.h
-+++ b/src/torrent/data/transfer_list.h
-@@ -37,9 +37,10 @@
- #ifndef LIBTORRENT_TRANSFER_LIST_H
- #define LIBTORRENT_TRANSFER_LIST_H
-
-+#include <functional>
- #include <vector>
-+
- #include <torrent/common.h>
--#include lt_tr1_functional
-
- namespace torrent {
-
-diff --git a/src/torrent/download.cc b/src/torrent/download.cc
-index edddedfb..f72c9351 100644
---- a/src/torrent/download.cc
-+++ b/src/torrent/download.cc
-@@ -36,9 +36,7 @@
-
- #include "config.h"
-
--#define __STDC_FORMAT_MACROS
--
--#include <inttypes.h>
-+#include <cinttypes>
-
- #include "data/block.h"
- #include "data/block_list.h"
-diff --git a/src/torrent/download/choke_group.cc b/src/torrent/download/choke_group.cc
-index a1540fc1..d9b25a9c 100644
---- a/src/torrent/download/choke_group.cc
-+++ b/src/torrent/download/choke_group.cc
-@@ -37,7 +37,7 @@
- #include "config.h"
-
- #include <algorithm>
--#include lt_tr1_functional
-+#include <functional>
-
- #include "choke_group.h"
- #include "choke_queue.h"
-diff --git a/src/torrent/download/choke_group.h b/src/torrent/download/choke_group.h
-index 93fd1d02..50804b3e 100644
---- a/src/torrent/download/choke_group.h
-+++ b/src/torrent/download/choke_group.h
-@@ -39,7 +39,7 @@
-
- #include <string>
- #include <vector>
--#include <inttypes.h>
-+#include <cinttypes>
- #include <torrent/common.h>
- #include <torrent/download/choke_queue.h>
-
-diff --git a/src/torrent/download/choke_queue.cc b/src/torrent/download/choke_queue.cc
-index 3827e25e..7c00b686 100644
---- a/src/torrent/download/choke_queue.cc
-+++ b/src/torrent/download/choke_queue.cc
-@@ -37,10 +37,9 @@
- #include "config.h"
-
- #include <algorithm>
-+#include <cstdlib>
- #include <functional>
- #include <numeric>
--#include <cstdlib>
--#include lt_tr1_functional
- #include <rak/functional.h>
-
- #include "protocol/peer_connection_base.h"
-diff --git a/src/torrent/download/choke_queue.h b/src/torrent/download/choke_queue.h
-index 973f6522..5e274a99 100644
---- a/src/torrent/download/choke_queue.h
-+++ b/src/torrent/download/choke_queue.h
-@@ -39,10 +39,11 @@
-
- #include <torrent/common.h>
-
-+#include <cinttypes>
-+#include <functional>
- #include <list>
- #include <vector>
--#include <inttypes.h>
--#include lt_tr1_functional
-+
- #include <torrent/download/group_entry.h>
-
- namespace torrent {
-diff --git a/src/torrent/download/group_entry.h b/src/torrent/download/group_entry.h
-index e167ecbb..a7c9e429 100644
---- a/src/torrent/download/group_entry.h
-+++ b/src/torrent/download/group_entry.h
-@@ -38,8 +38,9 @@
- #define LIBTORRENT_DOWNLOAD_GROUP_ENTRY_H
-
- #include <algorithm>
-+#include <functional>
- #include <vector>
--#include lt_tr1_functional
-+
- #include <torrent/common.h>
- #include <torrent/exceptions.h>
-
-diff --git a/src/torrent/download/resource_manager.cc b/src/torrent/download/resource_manager.cc
-index bc6374d2..51434c91 100644
---- a/src/torrent/download/resource_manager.cc
-+++ b/src/torrent/download/resource_manager.cc
-@@ -38,7 +38,6 @@
-
- #include <algorithm>
- #include <functional>
--#include lt_tr1_functional
- #include <limits>
- #include <numeric>
- #include <rak/functional.h>
-diff --git a/src/torrent/download/resource_manager.h b/src/torrent/download/resource_manager.h
-index b2f861af..ba61b45f 100644
---- a/src/torrent/download/resource_manager.h
-+++ b/src/torrent/download/resource_manager.h
-@@ -39,7 +39,7 @@
-
- #include <string>
- #include <vector>
--#include <inttypes.h>
-+#include <cinttypes>
- #include <torrent/common.h>
-
- namespace torrent {
-diff --git a/src/torrent/download_info.h b/src/torrent/download_info.h
-index 341e4c25..2c4dbaf2 100644
---- a/src/torrent/download_info.h
-+++ b/src/torrent/download_info.h
-@@ -37,10 +37,10 @@
- #ifndef LIBTORRENT_DOWNLOAD_INFO_H
- #define LIBTORRENT_DOWNLOAD_INFO_H
-
-+#include <cinttypes>
-+#include <functional>
- #include <list>
- #include <string>
--#include <inttypes.h>
--#include lt_tr1_functional
-
- #include <torrent/rate.h>
- #include <torrent/hash_string.h>
-diff --git a/src/torrent/error.cc b/src/torrent/error.cc
-index 5010c803..eea9bb83 100644
---- a/src/torrent/error.cc
-+++ b/src/torrent/error.cc
-@@ -54,11 +54,15 @@ static const char* errorStrings[e_last + 1] = {
- "unencrypted connection rejected", // eh_unencrypted_rejected
- "invalid encryption method", // eh_invalid_encryption
- "encryption sync failed", // eh_encryption_sync_failed
-- "network error", // eh_network_error
-+ "<deprecated>", // eh_
- "network unreachable", // eh_network_unreachable
- "network timeout", // eh_network_timeout
- "invalid message order", // eh_invalid_order
- "too many failed chunks", // eh_toomanyfailed
-+ "no peer info", // eh_no_peer_info
-+ "network socket error", // eh_network_socket_error
-+ "network read error", // eh_network_read_error
-+ "network write error", // eh_network_write_error
-
- // "", // e_handshake_incoming
- // "", // e_handshake_outgoing
-diff --git a/src/torrent/error.h b/src/torrent/error.h
-index f3fac463..295a595b 100644
---- a/src/torrent/error.h
-+++ b/src/torrent/error.h
-@@ -55,11 +55,14 @@ const int e_handshake_invalid_value = 8;
- const int e_handshake_unencrypted_rejected = 9;
- const int e_handshake_invalid_encryption = 10;
- const int e_handshake_encryption_sync_failed = 11;
--const int e_handshake_network_error = 12;
- const int e_handshake_network_unreachable = 13;
- const int e_handshake_network_timeout = 14;
- const int e_handshake_invalid_order = 15;
- const int e_handshake_toomanyfailed = 16;
-+const int e_handshake_no_peer_info = 17;
-+const int e_handshake_network_socket_error = 18;
-+const int e_handshake_network_read_error = 19;
-+const int e_handshake_network_write_error = 20;
-
- // const int e_handshake_incoming = 13;
- // const int e_handshake_outgoing = 14;
-@@ -69,7 +72,7 @@ const int e_handshake_toomanyfailed = 16;
- // const int e_handshake_retry_plaintext = 18;
- // const int e_handshake_retry_encrypted = 19;
-
--const int e_last = 16;
-+const int e_last = 20;
-
- const char* strerror(int err) LIBTORRENT_EXPORT;
-
-diff --git a/src/torrent/event.cc b/src/torrent/event.cc
-new file mode 100644
-index 00000000..e68974ea
---- /dev/null
-+++ b/src/torrent/event.cc
-@@ -0,0 +1,19 @@
-+#include "config.h"
-+
-+#include "event.h"
-+
-+#include "torrent/exceptions.h"
-+#include "torrent/net/fd.h"
-+
-+namespace torrent {
-+
-+void
-+Event::close_file_descriptor() {
-+ if (!is_open())
-+ throw internal_error("Tried to close already closed file descriptor on event type " + std::string(type_name()));
-+
-+ fd_close(m_fileDesc);
-+ m_fileDesc = -1;
-+}
-+
-+}
-diff --git a/src/torrent/event.h b/src/torrent/event.h
-index f3549762..73f87e46 100644
---- a/src/torrent/event.h
-+++ b/src/torrent/event.h
-@@ -1,39 +1,3 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #ifndef LIBTORRENT_TORRENT_EVENT_H
- #define LIBTORRENT_TORRENT_EVENT_H
-
-@@ -43,26 +7,48 @@ namespace torrent {
-
- class LIBTORRENT_EXPORT Event {
- public:
-- virtual ~Event() {}
-+ Event();
-+ virtual ~Event();
-
-- // These are not virtual as the fd is heavily used in select based
-- // polling, thus fast access is critical to performance.
-- int file_descriptor() const { return m_fileDesc; }
-+ // TODO: Disable override.
-+ bool is_open() const;
-
-- virtual void event_read() = 0;
-- virtual void event_write() = 0;
-- virtual void event_error() = 0;
-+ int file_descriptor() const;
-
-- // Require all event types to define this function.
-- virtual const char* type_name() const { return "default"; }
-+ virtual void event_read() = 0;
-+ virtual void event_write() = 0;
-+ virtual void event_error() = 0;
-
-- // Event closed?
-+ // TODO: Require all to define their ownh typename.
-+ virtual const char* type_name() const { return "default"; }
-
- protected:
-- int m_fileDesc;
-- bool m_ipv6_socket;
-+ void close_file_descriptor();
-+ void set_file_descriptor(int fd);
-+
-+ int m_fileDesc;
-+
-+ // TODO: Deprecate.
-+ bool m_ipv6_socket;
- };
-
-+inline Event::Event() : m_fileDesc(-1), m_ipv6_socket(false) {}
-+inline Event::~Event() {}
-+inline bool Event::is_open() const { return file_descriptor() != -1; }
-+inline int Event::file_descriptor() const { return m_fileDesc; }
-+inline void Event::set_file_descriptor(int fd) { m_fileDesc = fd; }
-+
-+// Defined in 'src/globals.cc'.
-+[[gnu::weak]] void poll_event_open(Event* event) LIBTORRENT_EXPORT;
-+[[gnu::weak]] void poll_event_close(Event* event) LIBTORRENT_EXPORT;
-+[[gnu::weak]] void poll_event_closed(Event* event) LIBTORRENT_EXPORT;
-+[[gnu::weak]] void poll_event_insert_read(Event* event) LIBTORRENT_EXPORT;
-+[[gnu::weak]] void poll_event_insert_write(Event* event) LIBTORRENT_EXPORT;
-+[[gnu::weak]] void poll_event_insert_error(Event* event) LIBTORRENT_EXPORT;
-+[[gnu::weak]] void poll_event_remove_read(Event* event) LIBTORRENT_EXPORT;
-+[[gnu::weak]] void poll_event_remove_write(Event* event) LIBTORRENT_EXPORT;
-+[[gnu::weak]] void poll_event_remove_error(Event* event) LIBTORRENT_EXPORT;
-+
- }
-
- #endif
-diff --git a/src/torrent/http.h b/src/torrent/http.h
-index c68d3933..c605afa5 100644
---- a/src/torrent/http.h
-+++ b/src/torrent/http.h
-@@ -38,9 +38,9 @@
- #define LIBTORRENT_HTTP_H
-
- #include <string>
-+#include <functional>
- #include <iosfwd>
- #include <list>
--#include lt_tr1_functional
- #include <torrent/common.h>
-
- namespace torrent {
-diff --git a/src/torrent/net/Makefile.am b/src/torrent/net/Makefile.am
-index 51999d19..35dd4774 100644
---- a/src/torrent/net/Makefile.am
-+++ b/src/torrent/net/Makefile.am
-@@ -1,11 +1,25 @@
- noinst_LTLIBRARIES = libsub_torrentnet.la
-
- libsub_torrentnet_la_SOURCES = \
-+ address_info.cc \
-+ address_info.h \
-+ fd.cc \
-+ fd.h \
-+ socket_address.cc \
-+ socket_address.h \
- socket_address_key.cc \
-- socket_address_key.h
-+ socket_address_key.h \
-+ socket_event.cc \
-+ socket_event.h \
-+ types.h
-
- AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../.. -I$(top_srcdir)
-
- libtorrentincludedir = $(includedir)/torrent/net
- libtorrentinclude_HEADERS = \
-- socket_address_key.h
-+ address_info.h \
-+ fd.h \
-+ socket_address.h \
-+ socket_address_key.h \
-+ socket_event.h \
-+ types.h
-diff --git a/src/torrent/net/address_info.cc b/src/torrent/net/address_info.cc
-new file mode 100644
-index 00000000..25a51ebd
---- /dev/null
-+++ b/src/torrent/net/address_info.cc
-@@ -0,0 +1,43 @@
-+#include "config.h"
-+
-+#include "address_info.h"
-+
-+namespace torrent {
-+
-+int
-+ai_get_addrinfo(const char* nodename, const char* servname, const addrinfo* hints, ai_unique_ptr& res) {
-+ addrinfo* ai;
-+ int err = ::getaddrinfo(nodename, servname, hints, &ai);
-+
-+ if (err != 0)
-+ return err;
-+
-+ res.reset(ai);
-+ return 0;
-+}
-+
-+sa_unique_ptr
-+ai_get_first_sa(const char* nodename, const char* servname, const addrinfo* hints) {
-+ ai_unique_ptr aip;
-+
-+ if (ai_get_addrinfo(nodename, servname, hints, aip) != 0)
-+ return nullptr;
-+
-+ return sa_copy(aip->ai_addr);
-+}
-+
-+int
-+ai_each_inet_inet6_first(const char* nodename, ai_sockaddr_func lambda) {
-+ int err;
-+ ai_unique_ptr ai;
-+
-+ // TODO: Change to a single call using hints with both inet/inet6.
-+ if ((err = ai_get_addrinfo(nodename, NULL, ai_make_hint(0, PF_INET, SOCK_STREAM).get(), ai)) != 0 &&
-+ (err = ai_get_addrinfo(nodename, NULL, ai_make_hint(0, PF_INET6, SOCK_STREAM).get(), ai)) != 0)
-+ return err;
-+
-+ lambda(ai->ai_addr);
-+ return 0;
-+}
-+
-+}
-diff --git a/src/torrent/net/address_info.h b/src/torrent/net/address_info.h
-new file mode 100644
-index 00000000..c0b1c082
---- /dev/null
-+++ b/src/torrent/net/address_info.h
-@@ -0,0 +1,69 @@
-+#ifndef LIBTORRENT_NET_ADDRESS_INFO_H
-+#define LIBTORRENT_NET_ADDRESS_INFO_H
-+
-+#include <cstring>
-+#include <functional>
-+#include <memory>
-+#include <string>
-+#include <netdb.h>
-+#include <torrent/common.h>
-+#include <torrent/net/socket_address.h>
-+
-+namespace torrent {
-+
-+struct ai_deleter {
-+ void operator()(addrinfo* ai) const { freeaddrinfo(ai); }
-+};
-+
-+typedef std::unique_ptr<addrinfo, ai_deleter> ai_unique_ptr;
-+typedef std::unique_ptr<const addrinfo, ai_deleter> c_ai_unique_ptr;
-+typedef std::function<void (const sockaddr*)> ai_sockaddr_func;
-+
-+inline void ai_clear(addrinfo* ai);
-+inline ai_unique_ptr ai_make_hint(int flags, int family, int socktype);
-+
-+int ai_get_addrinfo(const char* nodename, const char* servname, const addrinfo* hints, ai_unique_ptr& res) LIBTORRENT_EXPORT;
-+
-+// Helper functions:
-+
-+// TODO: Consider servname "0".
-+// TODO: ai_get_first_sa_err that returns a tuple?
-+sa_unique_ptr ai_get_first_sa(const char* nodename, const char* servname = nullptr, const addrinfo* hints = nullptr) LIBTORRENT_EXPORT;
-+
-+int ai_each_inet_inet6_first(const char* nodename, ai_sockaddr_func lambda) LIBTORRENT_EXPORT;
-+
-+// Get all addrinfo's, iterate, etc.
-+
-+//
-+// Safe conversion from unique_ptr arguments:
-+//
-+
-+inline void aip_clear(ai_unique_ptr& aip) { return ai_clear(aip.get()); }
-+
-+inline int aip_get_addrinfo(const char* nodename, const char* servname, const ai_unique_ptr& hints, ai_unique_ptr& res) { return ai_get_addrinfo(nodename, servname, hints.get(), res); }
-+inline int aip_get_addrinfo(const char* nodename, const char* servname, const c_ai_unique_ptr& hints, ai_unique_ptr& res) { return ai_get_addrinfo(nodename, servname, hints.get(), res); }
-+
-+//
-+// Implementations:
-+//
-+
-+inline void
-+ai_clear(addrinfo* ai) {
-+ std::memset(ai, 0, sizeof(addrinfo));
-+}
-+
-+inline ai_unique_ptr
-+ai_make_hint(int flags, int family, int socktype) {
-+ ai_unique_ptr aip(new addrinfo);
-+
-+ aip_clear(aip);
-+ aip->ai_flags = flags;
-+ aip->ai_family = family;
-+ aip->ai_socktype = socktype;
-+
-+ return aip;
-+}
-+
-+}
-+
-+#endif
-diff --git a/src/torrent/net/fd.cc b/src/torrent/net/fd.cc
-new file mode 100644
-index 00000000..07c91779
---- /dev/null
-+++ b/src/torrent/net/fd.cc
-@@ -0,0 +1,209 @@
-+#include "config.h"
-+
-+#include "fd.h"
-+
-+#include <cerrno>
-+#include <fcntl.h>
-+#include <unistd.h>
-+#include <netinet/in.h>
-+#include <netinet/in_systm.h>
-+#include <netinet/ip.h>
-+
-+#include "torrent/exceptions.h"
-+#include "torrent/net/socket_address.h"
-+#include "torrent/utils/log.h"
-+
-+#define LT_LOG(log_fmt, ...) \
-+ lt_log_print(LOG_CONNECTION_FD, "fd: " log_fmt, __VA_ARGS__);
-+#define LT_LOG_FLAG(log_fmt) \
-+ lt_log_print(LOG_CONNECTION_FD, "fd: " log_fmt " (flags:0x%x)", flags);
-+#define LT_LOG_FLAG_ERROR(log_fmt) \
-+ lt_log_print(LOG_CONNECTION_FD, "fd: " log_fmt " (flags:0x%x errno:%i message:'%s')", \
-+ flags, errno, std::strerror(errno));
-+#define LT_LOG_FD(log_fmt) \
-+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt, fd);
-+#define LT_LOG_FD_ERROR(log_fmt) \
-+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (errno:%i message:'%s')", \
-+ fd, errno, std::strerror(errno));
-+#define LT_LOG_FD_SOCKADDR(log_fmt) \
-+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (address:%s)", \
-+ fd, sa_pretty_str(sa).c_str());
-+#define LT_LOG_FD_SOCKADDR_ERROR(log_fmt) \
-+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (address:%s errno:%i message:'%s')", \
-+ fd, sa_pretty_str(sa).c_str(), errno, std::strerror(errno));
-+#define LT_LOG_FD_FLAG(log_fmt) \
-+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (flags:0x%x)", fd, flags);
-+#define LT_LOG_FD_FLAG_ERROR(log_fmt) \
-+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (flags:0x%x errno:%i message:'%s')", \
-+ fd, flags, errno, std::strerror(errno));
-+#define LT_LOG_FD_VALUE(log_fmt, value) \
-+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (value:%i)", fd, (int)value);
-+#define LT_LOG_FD_VALUE_ERROR(log_fmt, value) \
-+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (value:%i errno:%i message:'%s')", \
-+ fd, (int)value, errno, std::strerror(errno));
-+
-+namespace torrent {
-+
-+int fd__accept(int socket, sockaddr *address, socklen_t *address_len) { return ::accept(socket, address, address_len); }
-+int fd__bind(int socket, const sockaddr *address, socklen_t address_len) { return ::bind(socket, address, address_len); }
-+int fd__close(int fildes) { return ::close(fildes); }
-+int fd__connect(int socket, const sockaddr *address, socklen_t address_len) { return ::connect(socket, address, address_len); }
-+int fd__fcntl_int(int fildes, int cmd, int arg) { return ::fcntl(fildes, cmd, arg); }
-+int fd__listen(int socket, int backlog) { return ::listen(socket, backlog); }
-+int fd__setsockopt_int(int socket, int level, int option_name, int option_value) { return ::setsockopt(socket, level, option_name, &option_value, sizeof(int)); }
-+int fd__socket(int domain, int type, int protocol) { return ::socket(domain, type, protocol); }
-+
-+int
-+fd_open(fd_flags flags) {
-+ int domain;
-+ int protocol;
-+
-+ if (!fd_valid_flags(flags))
-+ throw internal_error("torrent::fd_open failed: invalid fd_flags");
-+
-+ if ((flags & fd_flag_stream)) {
-+ domain = SOCK_STREAM;
-+ protocol = IPPROTO_TCP;
-+ } else {
-+ LT_LOG_FLAG("fd_open missing socket type");
-+ errno = EINVAL;
-+ return -1;
-+ }
-+
-+ int fd = -1;
-+
-+ if (fd == -1 && !(flags & fd_flag_v4only)) {
-+ LT_LOG_FLAG("fd_open opening ipv6 socket");
-+ fd = fd__socket(PF_INET6, domain, protocol);
-+ }
-+
-+ if (fd == -1 && !(flags & fd_flag_v6only)) {
-+ LT_LOG_FLAG("fd_open opening ipv4 socket");
-+ fd = fd__socket(PF_INET, domain, protocol);
-+ }
-+
-+ if (fd == -1) {
-+ LT_LOG_FLAG_ERROR("fd_open failed to open socket");
-+ return -1;
-+ }
-+
-+ if ((flags & fd_flag_v6only) && !fd_set_v6only(fd, true)) {
-+ LT_LOG_FD_FLAG_ERROR("fd_open failed to set v6only");
-+ fd_close(fd);
-+ return -1;
-+ }
-+
-+ if ((flags & fd_flag_nonblock) && !fd_set_nonblock(fd)) {
-+ LT_LOG_FD_FLAG_ERROR("fd_open failed to set nonblock");
-+ fd_close(fd);
-+ return -1;
-+ }
-+
-+ if ((flags & fd_flag_reuse_address) && !fd_set_reuse_address(fd, true)) {
-+ LT_LOG_FD_FLAG_ERROR("fd_open failed to set reuse_address");
-+ fd_close(fd);
-+ return -1;
-+ }
-+
-+ LT_LOG_FD_FLAG("fd_open succeeded");
-+ return fd;
-+}
-+
-+void
-+fd_close(int fd) {
-+ if (fd == STDIN_FILENO || fd == STDOUT_FILENO || fd == STDERR_FILENO)
-+ throw internal_error("torrent::fd_close: tried to close stdin/out/err");
-+
-+ if (fd__close(fd) == -1)
-+ throw internal_error("torrent::fd_close: " + std::string(strerror(errno)));
-+
-+ LT_LOG_FD("fd_close succeeded");
-+}
-+
-+fd_sap_tuple
-+fd_accept(int fd) {
-+ sa_unique_ptr sap = sa_make_inet6();
-+ socklen_t socklen = sap_length(sap);
-+
-+ int accept_fd = fd__accept(fd, sap.get(), &socklen);
-+
-+ if (accept_fd == -1) {
-+ LT_LOG_FD_ERROR("fd_accept failed");
-+ return fd_sap_tuple{-1, nullptr};
-+ }
-+
-+ return fd_sap_tuple{accept_fd, std::move(sap)};
-+}
-+
-+bool
-+fd_bind(int fd, const sockaddr* sa) {
-+ if (fd__bind(fd, sa, sa_length(sa)) == -1) {
-+ LT_LOG_FD_SOCKADDR_ERROR("fd_bind failed");
-+ return false;
-+ }
-+
-+ LT_LOG_FD_SOCKADDR("fd_bind succeeded");
-+ return true;
-+}
-+
-+bool
-+fd_connect(int fd, const sockaddr* sa) {
-+ if (fd__connect(fd, sa, sa_length(sa)) == 0) {
-+ LT_LOG_FD_SOCKADDR("fd_connect succeeded");
-+ return true;
-+ }
-+
-+ if (errno == EINPROGRESS) {
-+ LT_LOG_FD_SOCKADDR("fd_connect succeeded and in progress");
-+ return true;
-+ }
-+
-+ LT_LOG_FD_SOCKADDR_ERROR("fd_connect failed");
-+ return false;
-+}
-+
-+bool
-+fd_listen(int fd, int backlog) {
-+ if (fd__listen(fd, backlog) == -1) {
-+ LT_LOG_FD_VALUE_ERROR("fd_listen failed", backlog);
-+ return false;
-+ }
-+
-+ LT_LOG_FD_VALUE("fd_listen succeeded", backlog);
-+ return true;
-+}
-+
-+bool
-+fd_set_nonblock(int fd) {
-+ if (fd__fcntl_int(fd, F_SETFL, O_NONBLOCK) == -1) {
-+ LT_LOG_FD_ERROR("fd_set_nonblock failed");
-+ return false;
-+ }
-+
-+ LT_LOG_FD("fd_set_nonblock succeeded");
-+ return true;
-+}
-+
-+bool
-+fd_set_reuse_address(int fd, bool state) {
-+ if (fd__setsockopt_int(fd, SOL_SOCKET, SO_REUSEADDR, state) == -1) {
-+ LT_LOG_FD_VALUE_ERROR("fd_set_reuse_address failed", state);
-+ return false;
-+ }
-+
-+ LT_LOG_FD_VALUE("fd_set_reuse_address succeeded", state);
-+ return true;
-+}
-+
-+bool
-+fd_set_v6only(int fd, bool state) {
-+ if (fd__setsockopt_int(fd, IPPROTO_IPV6, IPV6_V6ONLY, state) == -1) {
-+ LT_LOG_FD_VALUE_ERROR("fd_set_v6only failed", state);
-+ return false;
-+ }
-+
-+ LT_LOG_FD_VALUE("fd_set_v6only succeeded", state);
-+ return true;
-+}
-+
-+}
-diff --git a/src/torrent/net/fd.h b/src/torrent/net/fd.h
-new file mode 100644
-index 00000000..a7094646
---- /dev/null
-+++ b/src/torrent/net/fd.h
-@@ -0,0 +1,63 @@
-+#ifndef LIBTORRENT_NET_FD_H
-+#define LIBTORRENT_NET_FD_H
-+
-+#include <string>
-+#include <torrent/common.h>
-+#include <torrent/net/types.h>
-+
-+namespace torrent {
-+
-+enum fd_flags : int {
-+ fd_flag_stream = 0x1,
-+ fd_flag_nonblock = 0x10,
-+ fd_flag_reuse_address = 0x20,
-+ fd_flag_v4only = 0x40,
-+ fd_flag_v6only = 0x80,
-+ fd_flag_all = 0xff,
-+};
-+
-+constexpr bool fd_valid_flags(fd_flags flags);
-+
-+int fd_open(fd_flags flags) LIBTORRENT_EXPORT;
-+void fd_close(int fd) LIBTORRENT_EXPORT;
-+
-+fd_sap_tuple fd_accept(int fd) LIBTORRENT_EXPORT;
-+
-+bool fd_bind(int fd, const sockaddr* sa) LIBTORRENT_EXPORT;
-+bool fd_connect(int fd, const sockaddr* sa) LIBTORRENT_EXPORT;
-+bool fd_listen(int fd, int backlog) LIBTORRENT_EXPORT;
-+
-+bool fd_set_nonblock(int fd) LIBTORRENT_EXPORT;
-+bool fd_set_reuse_address(int fd, bool state) LIBTORRENT_EXPORT;
-+bool fd_set_v6only(int fd, bool state) LIBTORRENT_EXPORT;
-+
-+[[gnu::weak]] int fd__accept(int socket, sockaddr *address, socklen_t *address_len) LIBTORRENT_EXPORT;
-+[[gnu::weak]] int fd__bind(int socket, const sockaddr *address, socklen_t address_len) LIBTORRENT_EXPORT;
-+[[gnu::weak]] int fd__close(int fildes) LIBTORRENT_EXPORT;
-+[[gnu::weak]] int fd__connect(int socket, const sockaddr *address, socklen_t address_len) LIBTORRENT_EXPORT;
-+[[gnu::weak]] int fd__fcntl_int(int fildes, int cmd, int arg) LIBTORRENT_EXPORT;
-+[[gnu::weak]] int fd__listen(int socket, int backlog) LIBTORRENT_EXPORT;
-+[[gnu::weak]] int fd__setsockopt_int(int socket, int level, int option_name, int option_value) LIBTORRENT_EXPORT;
-+[[gnu::weak]] int fd__socket(int domain, int type, int protocol) LIBTORRENT_EXPORT;
-+
-+constexpr fd_flags
-+operator |(fd_flags lhs, fd_flags rhs) {
-+ return static_cast<fd_flags>(static_cast<int>(lhs) | static_cast<int>(rhs));
-+}
-+
-+inline fd_flags&
-+operator |=(fd_flags& lhs, fd_flags rhs) {
-+ return (lhs = lhs | rhs);
-+}
-+
-+constexpr bool
-+fd_valid_flags(fd_flags flags) {
-+ return
-+ (flags & fd_flag_stream) &&
-+ !((flags & fd_flag_v4only) && (flags & fd_flag_v6only)) &&
-+ !(flags & ~(fd_flag_all));
-+}
-+
-+}
-+
-+#endif
-diff --git a/src/torrent/net/socket_address.cc b/src/torrent/net/socket_address.cc
-new file mode 100644
-index 00000000..c36ba0ae
---- /dev/null
-+++ b/src/torrent/net/socket_address.cc
-@@ -0,0 +1,559 @@
-+#include "config.h"
-+
-+#include "socket_address.h"
-+
-+#include <cstring>
-+#include <arpa/inet.h>
-+#include <sys/un.h>
-+
-+// TODO: Deprecate.
-+#include "rak/socket_address.h"
-+
-+#include "torrent/exceptions.h"
-+
-+namespace torrent {
-+
-+constexpr uint32_t
-+sin6_addr32_index(const sockaddr_in6* sa, unsigned int index) {
-+ return
-+ (sa->sin6_addr.s6_addr[index * 4 + 0] << 24) +
-+ (sa->sin6_addr.s6_addr[index * 4 + 1] << 16) +
-+ (sa->sin6_addr.s6_addr[index * 4 + 2] << 8) +
-+ (sa->sin6_addr.s6_addr[index * 4 + 3] << 0);
-+}
-+
-+inline void
-+sin6_addr32_set(sockaddr_in6* sa, unsigned int index, uint32_t value) {
-+ sa->sin6_addr.s6_addr[index * 4 + 0] = (value >> 24);
-+ sa->sin6_addr.s6_addr[index * 4 + 1] = (value >> 16);
-+ sa->sin6_addr.s6_addr[index * 4 + 2] = (value >> 8);
-+ sa->sin6_addr.s6_addr[index * 4 + 3] = (value >> 0);
-+}
-+
-+inline in6_addr
-+sin6_make_addr32(uint32_t addr0, uint32_t addr1, uint32_t addr2, uint32_t addr3) {
-+ uint32_t addr32[4];
-+ addr32[0] = htonl(addr0);
-+ addr32[1] = htonl(addr1);
-+ addr32[2] = htonl(addr2);
-+ addr32[3] = htonl(addr3);
-+
-+ return *reinterpret_cast<in6_addr*>(addr32);
-+}
-+
-+bool
-+sa_is_unspec(const sockaddr* sa) {
-+ return sa != NULL && sa->sa_family == AF_UNSPEC;
-+}
-+
-+bool
-+sa_is_inet(const sockaddr* sa) {
-+ return sa != NULL && sa->sa_family == AF_INET;
-+}
-+
-+bool
-+sa_is_inet6(const sockaddr* sa) {
-+ return sa != NULL && sa->sa_family == AF_INET6;
-+}
-+
-+bool
-+sa_is_inet_inet6(const sockaddr* sa) {
-+ return sa != NULL && (sa->sa_family == AF_INET || sa->sa_family == AF_INET6);
-+}
-+
-+bool
-+sa_is_any(const sockaddr* sa) {
-+ switch (sa->sa_family) {
-+ case AF_INET:
-+ return sin_is_any(reinterpret_cast<const sockaddr_in*>(sa));
-+ case AF_INET6:
-+ if (sa_is_v4mapped(sa))
-+ return sin6_addr32_index(reinterpret_cast<const sockaddr_in6*>(sa), 3) == htonl(INADDR_ANY);
-+ return sin6_is_any(reinterpret_cast<const sockaddr_in6*>(sa));
-+ default:
-+ return true;
-+ }
-+}
-+
-+bool
-+sin_is_any(const sockaddr_in* sa) {
-+ return sa->sin_addr.s_addr == htonl(INADDR_ANY);
-+}
-+
-+bool
-+sin6_is_any(const sockaddr_in6* sa) {
-+ return std::memcmp(&sa->sin6_addr, &in6addr_any, sizeof(in6_addr)) == 0;
-+}
-+
-+bool
-+sa_is_broadcast(const sockaddr* sa) {
-+ switch (sa->sa_family) {
-+ case AF_INET:
-+ return sin_is_broadcast(reinterpret_cast<const sockaddr_in*>(sa));
-+ case AF_INET6:
-+ if (sa_is_v4mapped(sa))
-+ return sin6_addr32_index(reinterpret_cast<const sockaddr_in6*>(sa), 3) == htonl(INADDR_BROADCAST);
-+ return false;
-+ default:
-+ return false;
-+ }
-+}
-+
-+bool
-+sin_is_broadcast(const sockaddr_in* sa) {
-+ return sa->sin_addr.s_addr == htonl(INADDR_BROADCAST);
-+}
-+
-+bool
-+sa_is_v4mapped(const sockaddr* sa) {
-+ return sa != NULL && sa->sa_family == AF_INET6 && sin6_is_v4mapped(reinterpret_cast<const sockaddr_in6*>(sa));
-+}
-+
-+bool
-+sin6_is_v4mapped(const sockaddr_in6* sa) {
-+ return sa != NULL && IN6_IS_ADDR_V4MAPPED(&sa->sin6_addr);
-+}
-+
-+bool
-+sa_is_port_any(const sockaddr* sa) {
-+ return sa_port(sa) == 0;
-+}
-+
-+size_t
-+sa_length(const sockaddr* sa) {
-+ switch(sa->sa_family) {
-+ case AF_INET:
-+ return sizeof(sockaddr_in);
-+ case AF_INET6:
-+ return sizeof(sockaddr_in6);
-+ default:
-+ return sizeof(sa);
-+ }
-+}
-+
-+sa_unique_ptr
-+sa_make_unspec() {
-+ sa_unique_ptr sa(new sockaddr);
-+
-+ std::memset(sa.get(), 0, sizeof(sa));
-+ sa.get()->sa_family = AF_UNSPEC;
-+
-+ return sa;
-+}
-+
-+sa_unique_ptr
-+sa_make_inet() {
-+ return sa_unique_ptr(reinterpret_cast<sockaddr*>(sin_make().release()));
-+}
-+
-+sa_unique_ptr
-+sa_make_inet6() {
-+ return sa_unique_ptr(reinterpret_cast<sockaddr*>(sin6_make().release()));
-+}
-+
-+sa_unique_ptr
-+sa_make_unix(const std::string& pathname) {
-+ if (!pathname.empty())
-+ throw internal_error("torrent::sa_make_unix: function not implemented");
-+
-+ sun_unique_ptr sunp(new sockaddr_un);
-+
-+ std::memset(sunp.get(), 0, sizeof(sockaddr_un));
-+ sunp->sun_family = AF_UNIX;
-+ // TODO: verify length, copy pathname
-+
-+ return sa_unique_ptr(reinterpret_cast<sockaddr*>(sunp.release()));
-+}
-+
-+sa_unique_ptr
-+sa_convert(const sockaddr* sa) {
-+ if (sa == NULL)
-+ return sa_make_unspec();
-+
-+ switch(sa->sa_family) {
-+ case AF_INET:
-+ return sa_copy_in(reinterpret_cast<const sockaddr_in*>(sa));
-+ case AF_INET6:
-+ if (sin6_is_v4mapped(reinterpret_cast<const sockaddr_in6*>(sa)))
-+ return sa_from_v4mapped_in6(reinterpret_cast<const sockaddr_in6*>(sa));
-+
-+ return sa_copy_in6(reinterpret_cast<const sockaddr_in6*>(sa));
-+ case AF_UNSPEC:
-+ return sa_make_unspec();
-+ default:
-+ throw internal_error("torrent::sa_convert: sockaddr is not a valid family");
-+ }
-+}
-+
-+sa_unique_ptr
-+sa_copy(const sockaddr* sa) {
-+ if (sa == nullptr)
-+ throw internal_error("torrent::sa_copy: sockaddr is a nullptr");
-+
-+ switch(sa->sa_family) {
-+ case AF_INET:
-+ return sa_copy_in(reinterpret_cast<const sockaddr_in*>(sa));
-+ case AF_INET6:
-+ return sa_copy_in6(reinterpret_cast<const sockaddr_in6*>(sa));
-+ case AF_UNSPEC:
-+ return sa_make_unspec();
-+ default:
-+ throw internal_error("torrent::sa_copy: sockaddr is not a valid family");
-+ }
-+}
-+
-+sa_unique_ptr
-+sa_copy_in(const sockaddr_in* sa) {
-+ sa_unique_ptr result(reinterpret_cast<sockaddr*>(new sockaddr_in));
-+ std::memcpy(result.get(), sa, sizeof(sockaddr_in));
-+ return result;
-+}
-+
-+sa_unique_ptr
-+sa_copy_in6(const sockaddr_in6* sa) {
-+ sa_unique_ptr result(reinterpret_cast<sockaddr*>(new sockaddr_in6));
-+ std::memcpy(result.get(), sa, sizeof(sockaddr_in6));
-+ return result;
-+}
-+
-+sa_unique_ptr
-+sa_copy_addr(const sockaddr* sa, uint16_t port) {
-+ if (sa == nullptr)
-+ throw internal_error("torrent::sa_copy_addr: sockaddr is a nullptr");
-+
-+ switch(sa->sa_family) {
-+ case AF_INET:
-+ return sa_copy_addr_in(reinterpret_cast<const sockaddr_in*>(sa), port);
-+ case AF_INET6:
-+ return sa_copy_addr_in6(reinterpret_cast<const sockaddr_in6*>(sa), port);
-+ case AF_UNSPEC:
-+ return sa_make_unspec();
-+ default:
-+ throw internal_error("torrent::sa_copy_addr: sockaddr is not a valid family");
-+ }
-+}
-+
-+sa_unique_ptr
-+sa_copy_addr_in(const sockaddr_in* sa, uint16_t port) {
-+ sa_unique_ptr result(reinterpret_cast<sockaddr*>(new sockaddr_in));
-+ std::memset(result.get(), 0, sizeof(sockaddr_in));
-+ reinterpret_cast<sockaddr_in*>(result.get())->sin_family = AF_INET;
-+ reinterpret_cast<sockaddr_in*>(result.get())->sin_addr = sa->sin_addr;
-+ reinterpret_cast<sockaddr_in*>(result.get())->sin_port = htons(port);
-+ return result;
-+}
-+
-+sa_unique_ptr
-+sa_copy_addr_in6(const sockaddr_in6* sa, uint16_t port) {
-+ sa_unique_ptr result(reinterpret_cast<sockaddr*>(new sockaddr_in6));
-+ std::memset(result.get(), 0, sizeof(sockaddr_in6));
-+ reinterpret_cast<sockaddr_in6*>(result.get())->sin6_family = AF_INET6;
-+ std::memcpy(&reinterpret_cast<sockaddr_in6*>(result.get())->sin6_addr, &sa->sin6_addr, sizeof(in6_addr));
-+ reinterpret_cast<sockaddr_in6*>(result.get())->sin6_port = htons(port);
-+ return result;
-+}
-+
-+sin_unique_ptr
-+sin_copy(const sockaddr_in* sa) {
-+ sin_unique_ptr result(new sockaddr_in);
-+ std::memcpy(result.get(), sa, sizeof(sockaddr_in));
-+ return result;
-+}
-+
-+sin6_unique_ptr
-+sin6_copy(const sockaddr_in6* sa) {
-+ sin6_unique_ptr result(new sockaddr_in6);
-+ std::memcpy(result.get(), sa, sizeof(sockaddr_in6));
-+ return result;
-+}
-+
-+sin_unique_ptr
-+sin_make() {
-+ sin_unique_ptr sa(new sockaddr_in);
-+ std::memset(sa.get(), 0, sizeof(sockaddr_in));
-+ sa.get()->sin_family = AF_INET;
-+
-+ return sa;
-+}
-+
-+sin6_unique_ptr
-+sin6_make() {
-+ sin6_unique_ptr sa(new sockaddr_in6);
-+ std::memset(sa.get(), 0, sizeof(sockaddr_in6));
-+ sa.get()->sin6_family = AF_INET6;
-+
-+ return sa;
-+}
-+
-+sa_unique_ptr
-+sa_from_v4mapped(const sockaddr* sa) {
-+ if (!sa_is_inet6(sa))
-+ throw internal_error("torrent::sa_from_v4mapped: sockaddr is not inet6");
-+
-+ return sa_from_in(sin_from_v4mapped_in6(reinterpret_cast<const sockaddr_in6*>(sa)));
-+}
-+
-+sa_unique_ptr
-+sa_to_v4mapped(const sockaddr* sa) {
-+ if (!sa_is_inet(sa))
-+ throw internal_error("torrent::sa_to_v4mapped: sockaddr is not inet");
-+
-+ return sa_from_in6(sin6_to_v4mapped_in(reinterpret_cast<const sockaddr_in*>(sa)));
-+}
-+
-+sin_unique_ptr
-+sin_from_v4mapped_in6(const sockaddr_in6* sin6) {
-+ if (!sin6_is_v4mapped(sin6))
-+ throw internal_error("torrent::sin6_is_v4mapped: sockaddr_in6 is not v4mapped");
-+
-+ sin_unique_ptr result = sin_make();
-+ result.get()->sin_addr.s_addr = reinterpret_cast<in_addr_t>(htonl(sin6_addr32_index(sin6, 3)));
-+ result.get()->sin_port = sin6->sin6_port;
-+
-+ return result;
-+}
-+
-+sin6_unique_ptr
-+sin6_to_v4mapped_in(const sockaddr_in* sin) {
-+ sin6_unique_ptr result = sin6_make();
-+
-+ result.get()->sin6_addr = sin6_make_addr32(0, 0, 0xffff, ntohl(sin->sin_addr.s_addr));
-+ result.get()->sin6_port = sin->sin_port;
-+
-+ return result;
-+}
-+
-+sin_unique_ptr
-+sin_from_sa(sa_unique_ptr&& sap) {
-+ if (!sap_is_inet(sap))
-+ throw internal_error("torrent::sin_from_sa: sockaddr is nullptr or not inet");
-+
-+ return sin_unique_ptr(reinterpret_cast<sockaddr_in*>(sap.release()));
-+}
-+
-+sin6_unique_ptr
-+sin6_from_sa(sa_unique_ptr&& sap) {
-+ if (!sap_is_inet6(sap))
-+ throw internal_error("torrent::sin6_from_sa: sockaddr is nullptr or not inet6");
-+
-+ return sin6_unique_ptr(reinterpret_cast<sockaddr_in6*>(sap.release()));
-+}
-+
-+c_sin_unique_ptr
-+sin_from_c_sa(c_sa_unique_ptr&& sap) {
-+ if (!sap_is_inet(sap))
-+ throw internal_error("torrent::sin_from_c_sa: sockaddr is nullptr or not inet");
-+
-+ return c_sin_unique_ptr(reinterpret_cast<const sockaddr_in*>(sap.release()));
-+}
-+
-+c_sin6_unique_ptr
-+sin6_from_c_sa(sa_unique_ptr&& sap) {
-+ if (!sap_is_inet6(sap))
-+ throw internal_error("torrent::sin6_from_c_sa: sockaddr is nullptr or not inet6");
-+
-+ return c_sin6_unique_ptr(reinterpret_cast<const sockaddr_in6*>(sap.release()));
-+}
-+
-+void
-+sa_clear_inet6(sockaddr_in6* sa) {
-+ std::memset(sa, 0, sizeof(sockaddr_in6));
-+ sa->sin6_family = AF_INET6;
-+}
-+
-+uint16_t
-+sa_port(const sockaddr* sa) {
-+ if (sa == NULL)
-+ return 0;
-+
-+ switch(sa->sa_family) {
-+ case AF_INET:
-+ return ntohs(reinterpret_cast<const sockaddr_in*>(sa)->sin_port);
-+ case AF_INET6:
-+ return ntohs(reinterpret_cast<const sockaddr_in6*>(sa)->sin6_port);
-+ default:
-+ return 0;
-+ }
-+}
-+
-+void
-+sa_set_port(sockaddr* sa, uint16_t port) {
-+ switch(sa->sa_family) {
-+ case AF_INET:
-+ reinterpret_cast<sockaddr_in*>(sa)->sin_port = htons(port);
-+ return;
-+ case AF_INET6:
-+ reinterpret_cast<sockaddr_in6*>(sa)->sin6_port = htons(port);
-+ return;
-+ default:
-+ throw internal_error("torrent::sa_set_port: invalid family type");
-+ }
-+}
-+
-+bool
-+sa_equal(const sockaddr* lhs, const sockaddr* rhs) {
-+ switch(rhs->sa_family) {
-+ case AF_INET:
-+ case AF_INET6:
-+ case AF_UNSPEC:
-+ break;
-+ default:
-+ throw internal_error("torrent::sa_equal: rhs sockaddr is not a valid family");
-+ }
-+
-+ switch(lhs->sa_family) {
-+ case AF_INET:
-+ return lhs->sa_family == rhs->sa_family &&
-+ sin_equal(reinterpret_cast<const sockaddr_in*>(lhs), reinterpret_cast<const sockaddr_in*>(rhs));
-+ case AF_INET6:
-+ return lhs->sa_family == rhs->sa_family &&
-+ sin6_equal(reinterpret_cast<const sockaddr_in6*>(lhs), reinterpret_cast<const sockaddr_in6*>(rhs));
-+ case AF_UNSPEC:
-+ return lhs->sa_family == rhs->sa_family;
-+ default:
-+ throw internal_error("torrent::sa_equal: lhs sockaddr is not a valid family");
-+ }
-+}
-+
-+bool
-+sin_equal(const sockaddr_in* lhs, const sockaddr_in* rhs) {
-+ return lhs->sin_port == rhs->sin_port && lhs->sin_addr.s_addr == rhs->sin_addr.s_addr;
-+}
-+
-+bool
-+sin6_equal(const sockaddr_in6* lhs, const sockaddr_in6* rhs) {
-+ return lhs->sin6_port == rhs->sin6_port && std::equal(lhs->sin6_addr.s6_addr, lhs->sin6_addr.s6_addr + 16, rhs->sin6_addr.s6_addr);
-+}
-+
-+bool
-+sa_equal_addr(const sockaddr* lhs, const sockaddr* rhs) {
-+ switch(rhs->sa_family) {
-+ case AF_INET:
-+ case AF_INET6:
-+ case AF_UNSPEC:
-+ break;
-+ default:
-+ throw internal_error("torrent::sa_equal_addr: rhs sockaddr is not a valid family");
-+ }
-+
-+ switch(lhs->sa_family) {
-+ case AF_INET:
-+ return lhs->sa_family == rhs->sa_family &&
-+ sin_equal_addr(reinterpret_cast<const sockaddr_in*>(lhs), reinterpret_cast<const sockaddr_in*>(rhs));
-+ case AF_INET6:
-+ return lhs->sa_family == rhs->sa_family &&
-+ sin6_equal_addr(reinterpret_cast<const sockaddr_in6*>(lhs), reinterpret_cast<const sockaddr_in6*>(rhs));
-+ case AF_UNSPEC:
-+ return lhs->sa_family == rhs->sa_family;
-+ default:
-+ throw internal_error("torrent::sa_equal_addr: lhs sockaddr is not a valid family");
-+ }
-+}
-+
-+bool
-+sin_equal_addr(const sockaddr_in* lhs, const sockaddr_in* rhs) {
-+ return lhs->sin_addr.s_addr == rhs->sin_addr.s_addr;
-+}
-+
-+bool
-+sin6_equal_addr(const sockaddr_in6* lhs, const sockaddr_in6* rhs) {
-+ return std::equal(lhs->sin6_addr.s6_addr, lhs->sin6_addr.s6_addr + 16, rhs->sin6_addr.s6_addr);
-+}
-+
-+std::string
-+sa_addr_str(const sockaddr* sa) {
-+ if (sa == NULL)
-+ return "unspec";
-+
-+ switch (sa->sa_family) {
-+ case AF_INET:
-+ return sin_addr_str(reinterpret_cast<const sockaddr_in*>(sa));
-+ case AF_INET6:
-+ return sin6_addr_str(reinterpret_cast<const sockaddr_in6*>(sa));
-+ case AF_UNSPEC:
-+ return "unspec";
-+ default:
-+ return "invalid";
-+ }
-+}
-+
-+std::string
-+sin_addr_str(const sockaddr_in* sa) {
-+ char buffer[INET_ADDRSTRLEN];
-+
-+ if (inet_ntop(AF_INET, &sa->sin_addr, buffer, INET_ADDRSTRLEN) == NULL)
-+ return "inet_error";
-+
-+ return buffer;
-+}
-+
-+
-+std::string
-+sin6_addr_str(const sockaddr_in6* sa) {
-+ char buffer[INET6_ADDRSTRLEN];
-+
-+ if (inet_ntop(AF_INET6, &sa->sin6_addr, buffer, INET6_ADDRSTRLEN) == NULL)
-+ return "inet6_error";
-+
-+ return buffer;
-+}
-+
-+std::string
-+sa_pretty_str(const sockaddr* sa) {
-+ if (sa == nullptr)
-+ return "nullptr";
-+
-+ switch (sa->sa_family) {
-+ case AF_INET:
-+ return sin_pretty_str(reinterpret_cast<const sockaddr_in*>(sa));
-+ case AF_INET6:
-+ return sin6_pretty_str(reinterpret_cast<const sockaddr_in6*>(sa));
-+ case AF_UNSPEC:
-+ return "unspec";
-+ default:
-+ return "invalid";
-+ }
-+}
-+
-+std::string
-+sin_pretty_str(const sockaddr_in* sa) {
-+ auto result = sin_addr_str(sa);
-+
-+ if (sa->sin_port != 0)
-+ result += ':' + std::to_string(ntohs(sa->sin_port));
-+
-+ return result;
-+}
-+
-+std::string
-+sin6_pretty_str(const sockaddr_in6* sa) {
-+ auto result = "[" + sin6_addr_str(sa) + "]";
-+
-+ if (sa->sin6_port != 0)
-+ result += ':' + std::to_string(ntohs(sa->sin6_port));
-+
-+ return result;
-+}
-+
-+// Deprecated:
-+
-+void
-+sa_inet_mapped_inet6(const sockaddr_in* sa, sockaddr_in6* mapped) {
-+ uint32_t addr32[4];
-+ addr32[0] = 0;
-+ addr32[1] = 0;
-+ addr32[2] = htonl(0xffff);
-+ addr32[3] = sa->sin_addr.s_addr;
-+
-+ sa_clear_inet6(mapped);
-+
-+ mapped->sin6_addr = *reinterpret_cast<in6_addr*>(addr32);
-+ mapped->sin6_port = sa->sin_port;
-+}
-+
-+std::string
-+sa_pretty_address_str(const sockaddr* sa) {
-+ return sa_pretty_str(sa);
-+}
-+
-+}
-diff --git a/src/torrent/net/socket_address.h b/src/torrent/net/socket_address.h
-new file mode 100644
-index 00000000..f64aee68
---- /dev/null
-+++ b/src/torrent/net/socket_address.h
-@@ -0,0 +1,229 @@
-+#ifndef LIBTORRENT_NET_SOCKET_ADDRESS_H
-+#define LIBTORRENT_NET_SOCKET_ADDRESS_H
-+
-+#include <memory>
-+#include <string>
-+#include <netinet/in.h>
-+#include <sys/socket.h>
-+#include <torrent/common.h>
-+#include <torrent/net/types.h>
-+
-+namespace torrent {
-+
-+bool sa_is_unspec(const sockaddr* sa) LIBTORRENT_EXPORT;
-+bool sa_is_inet(const sockaddr* sa) LIBTORRENT_EXPORT;
-+bool sa_is_inet6(const sockaddr* sa) LIBTORRENT_EXPORT;
-+bool sa_is_inet_inet6(const sockaddr* sa) LIBTORRENT_EXPORT;
-+
-+bool sa_is_any(const sockaddr* sa) LIBTORRENT_EXPORT;
-+bool sin_is_any(const sockaddr_in* sa) LIBTORRENT_EXPORT;
-+bool sin6_is_any(const sockaddr_in6* sa) LIBTORRENT_EXPORT;
-+
-+bool sa_is_broadcast(const sockaddr* sa) LIBTORRENT_EXPORT;
-+bool sin_is_broadcast(const sockaddr_in* sa) LIBTORRENT_EXPORT;
-+
-+bool sa_is_v4mapped(const sockaddr* sa) LIBTORRENT_EXPORT;
-+bool sin6_is_v4mapped(const sockaddr_in6* sa) LIBTORRENT_EXPORT;
-+
-+bool sa_is_port_any(const sockaddr* sa) LIBTORRENT_EXPORT;
-+
-+size_t sa_length(const sockaddr* sa) LIBTORRENT_EXPORT;
-+
-+sa_unique_ptr sa_make_unspec() LIBTORRENT_EXPORT;
-+sa_unique_ptr sa_make_inet() LIBTORRENT_EXPORT;
-+sa_unique_ptr sa_make_inet6() LIBTORRENT_EXPORT;
-+sa_unique_ptr sa_make_unix(const std::string& pathname) LIBTORRENT_EXPORT;
-+
-+sa_unique_ptr sa_convert(const sockaddr* sa) LIBTORRENT_EXPORT;
-+
-+sa_unique_ptr sa_copy(const sockaddr* sa) LIBTORRENT_EXPORT;
-+sa_unique_ptr sa_copy_in(const sockaddr_in* sa) LIBTORRENT_EXPORT;
-+sa_unique_ptr sa_copy_in6(const sockaddr_in6* sa) LIBTORRENT_EXPORT;
-+sa_unique_ptr sa_copy_addr(const sockaddr* sa, uint16_t port = 0) LIBTORRENT_EXPORT;
-+sa_unique_ptr sa_copy_addr_in(const sockaddr_in* sa, uint16_t port = 0) LIBTORRENT_EXPORT;
-+sa_unique_ptr sa_copy_addr_in6(const sockaddr_in6* sa, uint16_t port = 0) LIBTORRENT_EXPORT;
-+sin_unique_ptr sin_copy(const sockaddr_in* sa) LIBTORRENT_EXPORT;
-+sin6_unique_ptr sin6_copy(const sockaddr_in6* sa) LIBTORRENT_EXPORT;
-+
-+sin_unique_ptr sin_make() LIBTORRENT_EXPORT;
-+sin6_unique_ptr sin6_make() LIBTORRENT_EXPORT;
-+
-+sa_unique_ptr sa_from_v4mapped(const sockaddr* sa) LIBTORRENT_EXPORT;
-+sa_unique_ptr sa_to_v4mapped(const sockaddr* sa) LIBTORRENT_EXPORT;
-+sa_unique_ptr sa_from_v4mapped_in6(const sockaddr_in6* sin6) LIBTORRENT_EXPORT;
-+sa_unique_ptr sa_to_v4mapped_in(const sockaddr_in* sin) LIBTORRENT_EXPORT;
-+sin_unique_ptr sin_from_v4mapped_in6(const sockaddr_in6* sin6) LIBTORRENT_EXPORT;
-+sin6_unique_ptr sin6_to_v4mapped_in(const sockaddr_in* sin) LIBTORRENT_EXPORT;
-+
-+sa_unique_ptr sa_from_in(sin_unique_ptr&& sinp) LIBTORRENT_EXPORT;
-+c_sa_unique_ptr sa_from_in(c_sin_unique_ptr&& sinp) LIBTORRENT_EXPORT;
-+sa_unique_ptr sa_from_in6(sin6_unique_ptr&& sin6p) LIBTORRENT_EXPORT;
-+c_sa_unique_ptr sa_from_in6(c_sin6_unique_ptr&& sin6p) LIBTORRENT_EXPORT;
-+sin_unique_ptr sin_from_sa(sa_unique_ptr&& sap) LIBTORRENT_EXPORT;
-+sin6_unique_ptr sin6_from_sa(sa_unique_ptr&& sap) LIBTORRENT_EXPORT;
-+c_sin_unique_ptr sin_from_c_sa(c_sa_unique_ptr&& sap) LIBTORRENT_EXPORT;
-+c_sin6_unique_ptr sin6_from_c_sa(c_sa_unique_ptr&& sap) LIBTORRENT_EXPORT;
-+
-+void sa_clear_inet6(sockaddr_in6* sa) LIBTORRENT_EXPORT;
-+
-+uint16_t sa_port(const sockaddr* sa) LIBTORRENT_EXPORT;
-+void sa_set_port(sockaddr* sa, uint16_t port) LIBTORRENT_EXPORT;
-+
-+bool sa_equal(const sockaddr* lhs, const sockaddr* rhs) LIBTORRENT_EXPORT;
-+bool sin_equal(const sockaddr_in* lhs, const sockaddr_in* rhs) LIBTORRENT_EXPORT;
-+bool sin6_equal(const sockaddr_in6* lhs, const sockaddr_in6* rhs) LIBTORRENT_EXPORT;
-+
-+bool sa_equal_addr(const sockaddr* lhs, const sockaddr* rhs) LIBTORRENT_EXPORT;
-+bool sin_equal_addr(const sockaddr_in* lhs, const sockaddr_in* rhs) LIBTORRENT_EXPORT;
-+bool sin6_equal_addr(const sockaddr_in6* lhs, const sockaddr_in6* rhs) LIBTORRENT_EXPORT;
-+
-+std::string sa_addr_str(const sockaddr* sa) LIBTORRENT_EXPORT;
-+std::string sin_addr_str(const sockaddr_in* sa) LIBTORRENT_EXPORT;
-+std::string sin6_addr_str(const sockaddr_in6* sa) LIBTORRENT_EXPORT;
-+
-+std::string sa_pretty_str(const sockaddr* sa) LIBTORRENT_EXPORT;
-+std::string sin_pretty_str(const sockaddr_in* sa) LIBTORRENT_EXPORT;
-+std::string sin6_pretty_str(const sockaddr_in6* sa) LIBTORRENT_EXPORT;
-+
-+// Rename/replace:
-+void sa_inet_mapped_inet6(const sockaddr_in* sa, sockaddr_in6* mapped) LIBTORRENT_EXPORT;
-+
-+std::string sa_pretty_address_str(const sockaddr* sa) LIBTORRENT_EXPORT;
-+
-+//
-+// Tuples:
-+//
-+
-+bool fd_sap_equal(const fd_sap_tuple& lhs, const fd_sap_tuple& rhs) LIBTORRENT_EXPORT;
-+
-+//
-+// Safe conversion from unique_ptr arguments:
-+//
-+
-+inline bool sap_is_unspec(const sa_unique_ptr& sap) { return sa_is_unspec(sap.get()); }
-+inline bool sap_is_unspec(const c_sa_unique_ptr& sap) { return sa_is_unspec(sap.get()); }
-+inline bool sap_is_inet(const c_sa_unique_ptr& sap) { return sa_is_inet(sap.get()); }
-+inline bool sap_is_inet(const sa_unique_ptr& sap) { return sa_is_inet(sap.get()); }
-+inline bool sap_is_inet6(const sa_unique_ptr& sap) { return sa_is_inet6(sap.get()); }
-+inline bool sap_is_inet6(const c_sa_unique_ptr& sap) { return sa_is_inet6(sap.get()); }
-+inline bool sap_is_inet_inet6(const sa_unique_ptr& sap) { return sa_is_inet_inet6(sap.get()); }
-+inline bool sap_is_inet_inet6(const c_sa_unique_ptr& sap) { return sa_is_inet_inet6(sap.get()); }
-+
-+inline bool sap_is_any(const sa_unique_ptr& sap) { return sa_is_any(sap.get()); }
-+inline bool sap_is_any(const c_sa_unique_ptr& sap) { return sa_is_any(sap.get()); }
-+inline bool sinp_is_any(const sin_unique_ptr& sinp) { return sin_is_any(sinp.get()); }
-+inline bool sinp_is_any(const c_sin_unique_ptr& sinp) { return sin_is_any(sinp.get()); }
-+inline bool sinp6_is_any(const sin6_unique_ptr& sin6p) { return sin6_is_any(sin6p.get()); }
-+inline bool sinp6_is_any(const c_sin6_unique_ptr& sin6p) { return sin6_is_any(sin6p.get()); }
-+
-+inline bool sap_is_broadcast(const sa_unique_ptr& sap) { return sa_is_broadcast(sap.get()); }
-+inline bool sap_is_broadcast(const c_sa_unique_ptr& sap) { return sa_is_broadcast(sap.get()); }
-+inline bool sinp_is_broadcast(const sin_unique_ptr& sap) { return sin_is_broadcast(sap.get()); }
-+inline bool sinp_is_broadcast(const c_sin_unique_ptr& sap) { return sin_is_broadcast(sap.get()); }
-+
-+inline bool sap_is_v4mapped(const sa_unique_ptr& sap) { return sa_is_v4mapped(sap.get()); }
-+inline bool sap_is_v4mapped(const c_sa_unique_ptr& sap) { return sa_is_v4mapped(sap.get()); }
-+inline bool sinp6_is_v4mapped(const sin6_unique_ptr& sin6p) { return sin6_is_v4mapped(sin6p.get()); }
-+inline bool sinp6_is_v4mapped(const c_sin6_unique_ptr& sin6p) { return sin6_is_v4mapped(sin6p.get()); }
-+
-+inline bool sap_is_port_any(const sa_unique_ptr& sap) { return sa_is_port_any(sap.get()); }
-+inline bool sap_is_port_any(const c_sa_unique_ptr& sap) { return sa_is_port_any(sap.get()); }
-+
-+inline size_t sap_length(const sa_unique_ptr& sap) { return sa_length(sap.get()); }
-+inline size_t sap_length(const c_sa_unique_ptr& sap) { return sa_length(sap.get()); }
-+
-+inline sa_unique_ptr sap_copy(const sa_unique_ptr& sap) { return sa_copy(sap.get()); }
-+inline sa_unique_ptr sap_copy(const c_sa_unique_ptr& sap) { return sa_copy(sap.get()); }
-+inline sa_unique_ptr sap_copy_addr(const sa_unique_ptr& sap, uint16_t port = 0) { return sa_copy_addr(sap.get(), port); }
-+inline sa_unique_ptr sap_copy_addr(const c_sa_unique_ptr& sap, uint16_t port = 0) { return sa_copy_addr(sap.get(), port); }
-+inline sa_unique_ptr sap_copy_in(const sin_unique_ptr& sinp) { return sa_copy_in(sinp.get()); }
-+inline sa_unique_ptr sap_copy_in(const c_sin_unique_ptr& sinp) { return sa_copy_in(sinp.get()); }
-+inline sa_unique_ptr sap_copy_in6(const sin6_unique_ptr& sin6p) { return sa_copy_in6(sin6p.get()); }
-+inline sa_unique_ptr sap_copy_in6(const c_sin6_unique_ptr& sin6p) { return sa_copy_in6(sin6p.get()); }
-+
-+inline sa_unique_ptr sap_from_v4mapped(const sa_unique_ptr& sap) { return sa_from_v4mapped(sap.get()); }
-+inline sa_unique_ptr sap_from_v4mapped(const c_sa_unique_ptr& sap) { return sa_from_v4mapped(sap.get()); }
-+inline sa_unique_ptr sap_to_v4mapped(const sa_unique_ptr& sap) { return sa_to_v4mapped(sap.get()); }
-+inline sa_unique_ptr sap_to_v4mapped(const c_sa_unique_ptr& sap) { return sa_to_v4mapped(sap.get()); }
-+inline sin_unique_ptr sinp_from_v4mapped_in6(const sin6_unique_ptr& sin6p) { return sin_from_v4mapped_in6(sin6p.get()); }
-+inline sin_unique_ptr sinp_from_v4mapped_in6(const c_sin6_unique_ptr& sin6p) { return sin_from_v4mapped_in6(sin6p.get()); }
-+inline sin6_unique_ptr sin6p_to_v4mapped_in(const sin_unique_ptr& sinp) { return sin6_to_v4mapped_in(sinp.get()); }
-+inline sin6_unique_ptr sin6p_to_v4mapped_in(const c_sin_unique_ptr& sinp) { return sin6_to_v4mapped_in(sinp.get()); }
-+
-+inline uint16_t sap_port(const sa_unique_ptr& sap) { return sa_port(sap.get()); }
-+inline uint16_t sap_port(const c_sa_unique_ptr& sap) { return sa_port(sap.get()); }
-+inline void sap_set_port(const sa_unique_ptr& sap, uint16_t port) { sa_set_port(sap.get(), port); }
-+
-+inline bool sap_equal(const sa_unique_ptr& lhs, const sa_unique_ptr& rhs) { return sa_equal(lhs.get(), rhs.get()); }
-+inline bool sap_equal(const sa_unique_ptr& lhs, const c_sa_unique_ptr& rhs) { return sa_equal(lhs.get(), rhs.get()); }
-+inline bool sap_equal(const c_sa_unique_ptr& lhs, const sa_unique_ptr& rhs) { return sa_equal(lhs.get(), rhs.get()); }
-+inline bool sap_equal(const c_sa_unique_ptr& lhs, const c_sa_unique_ptr& rhs) { return sa_equal(lhs.get(), rhs.get()); }
-+inline bool sinp_equal(const sin_unique_ptr& lhs, const sin_unique_ptr& rhs) { return sin_equal(lhs.get(), rhs.get()); }
-+inline bool sinp_equal(const sin_unique_ptr& lhs, const c_sin_unique_ptr& rhs) { return sin_equal(lhs.get(), rhs.get()); }
-+inline bool sinp_equal(const c_sin_unique_ptr& lhs, const sin_unique_ptr& rhs) { return sin_equal(lhs.get(), rhs.get()); }
-+inline bool sinp_equal(const c_sin_unique_ptr& lhs, const c_sin_unique_ptr& rhs) { return sin_equal(lhs.get(), rhs.get()); }
-+inline bool sin6p_equal(const sin6_unique_ptr& lhs, const sin6_unique_ptr& rhs) { return sin6_equal(lhs.get(), rhs.get()); }
-+inline bool sin6p_equal(const sin6_unique_ptr& lhs, const c_sin6_unique_ptr& rhs) { return sin6_equal(lhs.get(), rhs.get()); }
-+inline bool sin6p_equal(const c_sin6_unique_ptr& lhs, const sin6_unique_ptr& rhs) { return sin6_equal(lhs.get(), rhs.get()); }
-+inline bool sin6p_equal(const c_sin6_unique_ptr& lhs, const c_sin6_unique_ptr& rhs) { return sin6_equal(lhs.get(), rhs.get()); }
-+
-+inline bool sap_equal_addr(const sa_unique_ptr& lhs, const sa_unique_ptr& rhs) { return sa_equal_addr(lhs.get(), rhs.get()); }
-+inline bool sap_equal_addr(const sa_unique_ptr& lhs, const c_sa_unique_ptr& rhs) { return sa_equal_addr(lhs.get(), rhs.get()); }
-+inline bool sap_equal_addr(const c_sa_unique_ptr& lhs, const sa_unique_ptr& rhs) { return sa_equal_addr(lhs.get(), rhs.get()); }
-+inline bool sap_equal_addr(const c_sa_unique_ptr& lhs, const c_sa_unique_ptr& rhs) { return sa_equal_addr(lhs.get(), rhs.get()); }
-+inline bool sinp_equal_addr(const sin_unique_ptr& lhs, const sin_unique_ptr& rhs) { return sin_equal_addr(lhs.get(), rhs.get()); }
-+inline bool sinp_equal_addr(const sin_unique_ptr& lhs, const c_sin_unique_ptr& rhs) { return sin_equal_addr(lhs.get(), rhs.get()); }
-+inline bool sinp_equal_addr(const c_sin_unique_ptr& lhs, const sin_unique_ptr& rhs) { return sin_equal_addr(lhs.get(), rhs.get()); }
-+inline bool sinp_equal_addr(const c_sin_unique_ptr& lhs, const c_sin_unique_ptr& rhs) { return sin_equal_addr(lhs.get(), rhs.get()); }
-+inline bool sin6p_equal_addr(const sin6_unique_ptr& lhs, const sin6_unique_ptr& rhs) { return sin6_equal_addr(lhs.get(), rhs.get()); }
-+inline bool sin6p_equal_addr(const sin6_unique_ptr& lhs, const c_sin6_unique_ptr& rhs) { return sin6_equal_addr(lhs.get(), rhs.get()); }
-+inline bool sin6p_equal_addr(const c_sin6_unique_ptr& lhs, const sin6_unique_ptr& rhs) { return sin6_equal_addr(lhs.get(), rhs.get()); }
-+inline bool sin6p_equal_addr(const c_sin6_unique_ptr& lhs, const c_sin6_unique_ptr& rhs) { return sin6_equal_addr(lhs.get(), rhs.get()); }
-+
-+inline std::string sap_addr_str(const sa_unique_ptr& sap) { return sa_addr_str(sap.get()); }
-+inline std::string sap_addr_str(const c_sa_unique_ptr& sap) { return sa_addr_str(sap.get()); }
-+inline std::string sap_pretty_str(const sa_unique_ptr& sap) { return sa_pretty_str(sap.get()); }
-+inline std::string sap_pretty_str(const c_sa_unique_ptr& sap) { return sa_pretty_str(sap.get()); }
-+
-+//
-+// Implementations:
-+//
-+
-+inline sa_unique_ptr
-+sa_from_v4mapped_in6(const sockaddr_in6* sin6) {
-+ return sa_from_in(sin_from_v4mapped_in6(sin6));
-+}
-+
-+inline sa_unique_ptr
-+sa_to_v4mapped_in(const sockaddr_in* sin) {
-+ return sa_from_in6(sin6_to_v4mapped_in(sin));
-+}
-+
-+inline sa_unique_ptr
-+sa_from_in(sin_unique_ptr&& sinp) {
-+ return sa_unique_ptr(reinterpret_cast<sockaddr*>(sinp.release()));
-+}
-+
-+inline c_sa_unique_ptr
-+sa_from_in(c_sin_unique_ptr&& sinp) {
-+ return c_sa_unique_ptr(reinterpret_cast<const sockaddr*>(sinp.release()));
-+}
-+
-+inline sa_unique_ptr
-+sa_from_in6(sin6_unique_ptr&& sin6p) {
-+ return sa_unique_ptr(reinterpret_cast<sockaddr*>(sin6p.release()));
-+}
-+
-+inline c_sa_unique_ptr
-+sa_from_in6(c_sin6_unique_ptr&& sin6p) {
-+ return c_sa_unique_ptr(reinterpret_cast<const sockaddr*>(sin6p.release()));
-+}
-+
-+inline bool
-+fd_sap_equal(const fd_sap_tuple& lhs, const fd_sap_tuple& rhs) {
-+ return std::get<0>(lhs) == std::get<0>(rhs) && sap_equal(std::get<1>(lhs), std::get<1>(rhs));
-+}
-+
-+}
-+
-+#endif
-diff --git a/src/torrent/net/socket_address_key.h b/src/torrent/net/socket_address_key.h
-index 9d6e0c49..0fd0feb3 100644
---- a/src/torrent/net/socket_address_key.h
-+++ b/src/torrent/net/socket_address_key.h
-@@ -5,7 +5,7 @@
- #define LIBTORRENT_UTILS_SOCKET_ADDRESS_KEY_H
-
- #include <cstring>
--#include <inttypes.h>
-+#include <cinttypes>
- #include <netinet/in.h>
-
- // Unique key for the socket address, excluding port numbers, etc.
-diff --git a/src/torrent/net/socket_event.cc b/src/torrent/net/socket_event.cc
-new file mode 100644
-index 00000000..e6805290
---- /dev/null
-+++ b/src/torrent/net/socket_event.cc
-@@ -0,0 +1,29 @@
-+#include "config.h"
-+
-+#include "socket_event.h"
-+
-+#include "torrent/exceptions.h"
-+
-+namespace torrent {
-+
-+socket_event::~socket_event() {
-+ if (is_open())
-+ throw internal_error("Called socket_event::~socket_event while still open on type " + std::string(type_name()));
-+}
-+
-+void
-+socket_event::event_read() {
-+ throw internal_error("Called unsupported socket_event::event_read on type " + std::string(type_name()));
-+}
-+
-+void
-+socket_event::event_write() {
-+ throw internal_error("Called unsupported socket_event::event_write on type " + std::string(type_name()));
-+}
-+
-+void
-+socket_event::event_error() {
-+ throw internal_error("Called unsupported socket_event::event_error on type " + std::string(type_name()));
-+}
-+
-+}
-diff --git a/src/torrent/net/socket_event.h b/src/torrent/net/socket_event.h
-new file mode 100644
-index 00000000..d9904bd6
---- /dev/null
-+++ b/src/torrent/net/socket_event.h
-@@ -0,0 +1,31 @@
-+#ifndef LIBTORRENT_SOCKET_EVENT_H
-+#define LIBTORRENT_SOCKET_EVENT_H
-+
-+#include <cinttypes>
-+
-+#include "torrent/event.h"
-+#include "torrent/net/socket_address.h"
-+
-+namespace torrent {
-+
-+class LIBTORRENT_EXPORT socket_event : public Event {
-+public:
-+ ~socket_event() override;
-+
-+ const sockaddr* socket_address() const;
-+ uint16_t socket_address_port() const;
-+
-+ void event_read() override;
-+ void event_write() override;
-+ void event_error() override;
-+
-+protected:
-+ sa_unique_ptr m_socket_address;
-+};
-+
-+inline const sockaddr* socket_event::socket_address() const { return m_socket_address.get(); }
-+inline uint16_t socket_event::socket_address_port() const { return sap_port(m_socket_address); }
-+
-+}
-+
-+#endif
-diff --git a/src/torrent/net/types.h b/src/torrent/net/types.h
-new file mode 100644
-index 00000000..016e8b85
---- /dev/null
-+++ b/src/torrent/net/types.h
-@@ -0,0 +1,33 @@
-+#ifndef LIBTORRENT_NET_TYPES_H
-+#define LIBTORRENT_NET_TYPES_H
-+
-+#include <memory>
-+#include <tuple>
-+#include <sys/socket.h>
-+
-+struct sockaddr_in;
-+struct sockaddr_in6;
-+struct sockaddr_un;
-+
-+namespace torrent {
-+
-+typedef std::unique_ptr<sockaddr> sa_unique_ptr;
-+typedef std::unique_ptr<sockaddr_in> sin_unique_ptr;
-+typedef std::unique_ptr<sockaddr_in6> sin6_unique_ptr;
-+typedef std::unique_ptr<sockaddr_un> sun_unique_ptr;
-+
-+typedef std::unique_ptr<const sockaddr> c_sa_unique_ptr;
-+typedef std::unique_ptr<const sockaddr_in> c_sin_unique_ptr;
-+typedef std::unique_ptr<const sockaddr_in6> c_sin6_unique_ptr;
-+typedef std::unique_ptr<const sockaddr_un> c_sun_unique_ptr;
-+
-+typedef std::tuple<int, std::unique_ptr<sockaddr>> fd_sap_tuple;
-+
-+struct listen_result_type {
-+ int fd;
-+ sa_unique_ptr address;
-+};
-+
-+}
-+
-+#endif
-diff --git a/src/torrent/object.h b/src/torrent/object.h
-index 3325a434..3f9fe7e4 100644
---- a/src/torrent/object.h
-+++ b/src/torrent/object.h
-@@ -37,8 +37,9 @@
- #ifndef LIBTORRENT_OBJECT_H
- #define LIBTORRENT_OBJECT_H
-
--#include <string>
-+#include <limits>
- #include <map>
-+#include <string>
- #include <vector>
- #include <torrent/common.h>
- #include <torrent/exceptions.h>
-@@ -162,6 +163,7 @@ public:
- string_type& as_string() { check_throw(TYPE_STRING); return _string(); }
- const string_type& as_string() const { check_throw(TYPE_STRING); return _string(); }
- const string_type& as_string_c() const { check_throw(TYPE_STRING); return _string(); }
-+ const char* as_c_str() const { check_throw(TYPE_STRING); return _string().c_str(); }
- list_type& as_list() { check_throw(TYPE_LIST); return _list(); }
- const list_type& as_list() const { check_throw(TYPE_LIST); return _list(); }
- map_type& as_map() { check_throw(TYPE_MAP); return _map(); }
-@@ -179,6 +181,8 @@ public:
- raw_map& as_raw_map() { check_throw(TYPE_RAW_MAP); return _raw_map(); }
- const raw_map& as_raw_map() const { check_throw(TYPE_RAW_MAP); return _raw_map(); }
-
-+ template <typename T> T as_value_type(const char* err_msg) const { check_value_throw<T>(err_msg); return _value(); }
-+
- bool has_key(const key_type& k) const { check_throw(TYPE_MAP); return _map().find(k) != _map().end(); }
- bool has_key_value(const key_type& k) const { check_throw(TYPE_MAP); return check(_map().find(k), TYPE_VALUE); }
- bool has_key_string(const key_type& k) const { check_throw(TYPE_MAP); return check(_map().find(k), TYPE_STRING); }
-@@ -246,6 +250,8 @@ public:
- inline bool check(map_type::const_iterator itr, type_type t) const { return itr != _map().end() && itr->second.type() == t; }
- inline void check_throw(type_type t) const { if (t != type()) throw bencode_error("Wrong object type."); }
-
-+ template <typename T> void check_value_throw(const char* err_msg) const;
-+
- uint32_t m_flags;
-
- #ifndef HAVE_STDCXX_0X
-@@ -484,6 +490,19 @@ object_equal(const Object& left, const Object& right) {
- }
- }
-
-+template <typename T>
-+inline void
-+Object::check_value_throw(const char* err_msg) const {
-+ if (!std::numeric_limits<T>::is_integer)
-+ throw internal_error("Tried to check value with non-integer type.");
-+
-+ if (!is_value())
-+ throw bencode_error(err_msg);
-+
-+ if (!(_value() >= std::numeric_limits<T>::min() && _value() <= std::numeric_limits<T>::max()))
-+ throw bencode_error(err_msg);
-+}
-+
- }
-
- #endif
-diff --git a/src/torrent/peer/client_list.cc b/src/torrent/peer/client_list.cc
-index c857f62d..9c18aa50 100644
---- a/src/torrent/peer/client_list.cc
-+++ b/src/torrent/peer/client_list.cc
-@@ -37,8 +37,8 @@
- #include "config.h"
-
- #include <algorithm>
-+#include <functional>
- #include <rak/string_manip.h>
--#include lt_tr1_functional
-
- #include "client_list.h"
- #include "exceptions.h"
-diff --git a/src/torrent/peer/connection_list.h b/src/torrent/peer/connection_list.h
-index ec26835f..eb058784 100644
---- a/src/torrent/peer/connection_list.h
-+++ b/src/torrent/peer/connection_list.h
-@@ -37,9 +37,10 @@
- #ifndef LIBTORRENT_PEER_CONNECTION_LIST_H
- #define LIBTORRENT_PEER_CONNECTION_LIST_H
-
-+#include <functional>
- #include <list>
- #include <vector>
--#include lt_tr1_functional
-+
- #include <torrent/common.h>
- #include <torrent/hash_string.h>
-
-diff --git a/src/torrent/peer/peer_list.cc b/src/torrent/peer/peer_list.cc
-index aa60939a..080a7f13 100644
---- a/src/torrent/peer/peer_list.cc
-+++ b/src/torrent/peer/peer_list.cc
-@@ -36,8 +36,6 @@
-
- #include "config.h"
-
--#define __STDC_FORMAT_MACROS
--
- #include <algorithm>
- #include <functional>
- #include <rak/functional.h>
-@@ -56,6 +54,8 @@
-
- #define LT_LOG_EVENTS(log_fmt, ...) \
- lt_log_print_info(LOG_PEER_LIST_EVENTS, m_info, "peer_list", log_fmt, __VA_ARGS__);
-+#define LT_LOG_ADDRESS(log_fmt, ...) \
-+ lt_log_print_info(LOG_PEER_LIST_ADDRESS, m_info, "peer_list", log_fmt, __VA_ARGS__);
- #define LT_LOG_SA_FMT "'%s:%" PRIu16 "'"
-
- namespace torrent {
-@@ -196,6 +196,7 @@ PeerList::insert_available(const void* al) {
- for (; itr != last; itr++) {
- if (!socket_address_key::is_comparable_sockaddr(itr->c_sockaddr()) || itr->port() == 0) {
- invalid++;
-+ LT_LOG_ADDRESS("skipped invalid address " LT_LOG_SA_FMT, itr->address_str().c_str(), itr->port());
- continue;
- }
-
-@@ -242,6 +243,8 @@ PeerList::insert_available(const void* al) {
-
- inserted++;
- m_available_list->push_back(&*itr);
-+
-+ LT_LOG_ADDRESS("added available address " LT_LOG_SA_FMT, itr->address_str().c_str(), itr->port());
- }
-
- LT_LOG_EVENTS("inserted peers"
-diff --git a/src/torrent/poll.h b/src/torrent/poll.h
-index b12c8ec2..15a73897 100644
---- a/src/torrent/poll.h
-+++ b/src/torrent/poll.h
-@@ -37,8 +37,7 @@
- #ifndef LIBTORRENT_TORRENT_POLL_H
- #define LIBTORRENT_TORRENT_POLL_H
-
--#include lt_tr1_functional
--
-+#include <functional>
- #include <torrent/common.h>
-
- namespace torrent {
-diff --git a/src/torrent/torrent.cc b/src/torrent/torrent.cc
-index 339c2c4f..fb70d247 100644
---- a/src/torrent/torrent.cc
-+++ b/src/torrent/torrent.cc
-@@ -1,39 +1,3 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #include "config.h"
-
- #include <rak/address_info.h>
-@@ -139,8 +103,8 @@ main_thread() {
-
- ChunkManager* chunk_manager() { return manager->chunk_manager(); }
- ClientList* client_list() { return manager->client_list(); }
--FileManager* file_manager() { return manager->file_manager(); }
- ConnectionManager* connection_manager() { return manager->connection_manager(); }
-+FileManager* file_manager() { return manager->file_manager(); }
- DhtManager* dht_manager() { return manager->dht_manager(); }
- ResourceManager* resource_manager() { return manager->resource_manager(); }
-
-@@ -189,8 +153,10 @@ download_add(Object* object) {
- download->main()->set_metadata_size(metadata_size);
- }
-
-+ std::string local_id = PEER_NAME + rak::generate_random<std::string>(20 - std::string(PEER_NAME).size());
-+
- download->set_hash_queue(manager->hash_queue());
-- download->initialize(infoHash, PEER_NAME + rak::generate_random<std::string>(20 - std::string(PEER_NAME).size()));
-+ download->initialize(infoHash, local_id);
-
- // Add trackers, etc, after setting the info hash so that log
- // entries look sane.
-diff --git a/src/torrent/torrent.h b/src/torrent/torrent.h
-index 7bcf88fe..0cdfdaa7 100644
---- a/src/torrent/torrent.h
-+++ b/src/torrent/torrent.h
-@@ -44,6 +44,11 @@
-
- namespace torrent {
-
-+class FileManager;
-+class ResourceManager;
-+
-+class thread_base;
-+
- // Make sure you seed srandom and srand48 if available.
- void initialize() LIBTORRENT_EXPORT;
-
-@@ -53,16 +58,12 @@ void cleanup() LIBTORRENT_EXPORT;
-
- bool is_inactive() LIBTORRENT_EXPORT;
-
--class FileManager;
--class ResourceManager;
--class thread_base;
--
- thread_base* main_thread() LIBTORRENT_EXPORT;
-
- ChunkManager* chunk_manager() LIBTORRENT_EXPORT;
- ClientList* client_list() LIBTORRENT_EXPORT;
--FileManager* file_manager() LIBTORRENT_EXPORT;
- ConnectionManager* connection_manager() LIBTORRENT_EXPORT;
-+FileManager* file_manager() LIBTORRENT_EXPORT;
- DhtManager* dht_manager() LIBTORRENT_EXPORT;
- ResourceManager* resource_manager() LIBTORRENT_EXPORT;
-
-diff --git a/src/torrent/tracker.h b/src/torrent/tracker.h
-index a528ef6a..bd7546a9 100644
---- a/src/torrent/tracker.h
-+++ b/src/torrent/tracker.h
-@@ -2,7 +2,7 @@
- #define LIBTORRENT_TRACKER_H
-
- #include <string>
--#include <inttypes.h>
-+#include <cinttypes>
- #include <torrent/common.h>
-
- namespace torrent {
-diff --git a/src/torrent/tracker_controller.h b/src/torrent/tracker_controller.h
-index 70d1b43f..9452be0f 100644
---- a/src/torrent/tracker_controller.h
-+++ b/src/torrent/tracker_controller.h
-@@ -37,8 +37,9 @@
- #ifndef LIBTORRENT_TRACKER_CONTROLLER_H
- #define LIBTORRENT_TRACKER_CONTROLLER_H
-
-+#include <functional>
- #include <string>
--#include lt_tr1_functional
-+
- #include <torrent/common.h>
- #include <torrent/tracker.h>
-
-diff --git a/src/torrent/tracker_list.h b/src/torrent/tracker_list.h
-index c6817b3a..bb06f8af 100644
---- a/src/torrent/tracker_list.h
-+++ b/src/torrent/tracker_list.h
-@@ -38,10 +38,10 @@
- #define LIBTORRENT_TRACKER_LIST_H
-
- #include <algorithm>
-+#include <functional>
- #include <string>
- #include <vector>
- #include <torrent/common.h>
--#include lt_tr1_functional
-
- namespace torrent {
-
-diff --git a/src/torrent/utils/Makefile.am b/src/torrent/utils/Makefile.am
-index 51c9a026..a48786c6 100644
---- a/src/torrent/utils/Makefile.am
-+++ b/src/torrent/utils/Makefile.am
-@@ -8,10 +8,10 @@ libsub_torrentutils_la_SOURCES = \
- log.h \
- log_buffer.cc \
- log_buffer.h \
-- net.cc \
-- net.h \
- option_strings.cc \
- option_strings.h \
-+ random.cc \
-+ random.h \
- ranges.h \
- resume.cc \
- resume.h \
-@@ -32,7 +32,6 @@ libtorrentinclude_HEADERS = \
- extents.h \
- log.h \
- log_buffer.h \
-- net.h \
- option_strings.h \
- ranges.h \
- resume.h \
-diff --git a/src/torrent/utils/directory_events.h b/src/torrent/utils/directory_events.h
-index 30fa0508..fd9246c5 100644
---- a/src/torrent/utils/directory_events.h
-+++ b/src/torrent/utils/directory_events.h
-@@ -37,9 +37,10 @@
- #ifndef LIBTORRENT_DIRECTORY_EVENTS_H
- #define LIBTORRENT_DIRECTORY_EVENTS_H
-
-+#include <functional>
- #include <string>
- #include <vector>
--#include lt_tr1_functional
-+
- #include <torrent/event.h>
-
- namespace torrent {
-diff --git a/src/torrent/utils/log.cc b/src/torrent/utils/log.cc
-index 6c605474..b855a2c6 100644
---- a/src/torrent/utils/log.cc
-+++ b/src/torrent/utils/log.cc
-@@ -1,45 +1,6 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #include "config.h"
-
--#define __STDC_FORMAT_MACROS
--
- #include "log.h"
--#include "log_buffer.h"
-
- #include "globals.h"
- #include "torrent/exceptions.h"
-@@ -54,8 +15,6 @@
- #include <fstream>
- #include <functional>
- #include <memory>
--#include lt_tr1_functional
--#include lt_tr1_memory
-
- namespace torrent {
-
-@@ -232,7 +191,6 @@ log_initialize() {
-
- LOG_CASCADE(LOG_CRITICAL);
-
-- LOG_CASCADE(LOG_CONNECTION_CRITICAL);
- LOG_CASCADE(LOG_PEER_CRITICAL);
- LOG_CASCADE(LOG_SOCKET_CRITICAL);
- LOG_CASCADE(LOG_STORAGE_CRITICAL);
-@@ -240,7 +198,6 @@ log_initialize() {
- LOG_CASCADE(LOG_TRACKER_CRITICAL);
- LOG_CASCADE(LOG_TORRENT_CRITICAL);
-
-- LOG_CHILDREN_CASCADE(LOG_CRITICAL, LOG_CONNECTION_CRITICAL);
- LOG_CHILDREN_CASCADE(LOG_CRITICAL, LOG_PEER_CRITICAL);
- LOG_CHILDREN_CASCADE(LOG_CRITICAL, LOG_SOCKET_CRITICAL);
- LOG_CHILDREN_CASCADE(LOG_CRITICAL, LOG_STORAGE_CRITICAL);
-@@ -248,6 +205,12 @@ log_initialize() {
- LOG_CHILDREN_CASCADE(LOG_CRITICAL, LOG_TRACKER_CRITICAL);
- LOG_CHILDREN_CASCADE(LOG_CRITICAL, LOG_TORRENT_CRITICAL);
-
-+ LOG_LINK(LOG_CONNECTION, LOG_CONNECTION_BIND);
-+ LOG_LINK(LOG_CONNECTION, LOG_CONNECTION_FD);
-+ LOG_LINK(LOG_CONNECTION, LOG_CONNECTION_FILTER);
-+ LOG_LINK(LOG_CONNECTION, LOG_CONNECTION_HANDSHAKE);
-+ LOG_LINK(LOG_CONNECTION, LOG_CONNECTION_LISTEN);
-+
- LOG_LINK(LOG_DHT_ALL, LOG_DHT_MANAGER);
- LOG_LINK(LOG_DHT_ALL, LOG_DHT_NODE);
- LOG_LINK(LOG_DHT_ALL, LOG_DHT_ROUTER);
-@@ -447,21 +410,4 @@ log_open_gz_file_output(const char* name, const char* filename, bool append) {
- std::placeholders::_3));
- }
-
--log_buffer*
--log_open_log_buffer(const char* name) {
-- log_buffer* buffer = new log_buffer;
--
-- try {
-- log_open_output(name, std::bind(&log_buffer::lock_and_push_log, buffer,
-- std::placeholders::_1,
-- std::placeholders::_2,
-- std::placeholders::_3));
-- return buffer;
--
-- } catch (torrent::input_error& e) {
-- delete buffer;
-- throw;
-- }
--}
--
- }
-diff --git a/src/torrent/utils/log.h b/src/torrent/utils/log.h
-index 0dfdc86b..fe6127d6 100644
---- a/src/torrent/utils/log.h
-+++ b/src/torrent/utils/log.h
-@@ -1,47 +1,12 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #ifndef LIBTORRENT_UTILS_LOG_H
- #define LIBTORRENT_UTILS_LOG_H
-
-+#include <array>
- #include <bitset>
-+#include <functional>
- #include <string>
- #include <vector>
--#include lt_tr1_array
--#include lt_tr1_functional
-+
- #include <torrent/common.h>
-
- namespace torrent {
-@@ -55,13 +20,6 @@ enum {
- LOG_INFO,
- LOG_DEBUG,
-
-- LOG_CONNECTION_CRITICAL,
-- LOG_CONNECTION_ERROR,
-- LOG_CONNECTION_WARN,
-- LOG_CONNECTION_NOTICE,
-- LOG_CONNECTION_INFO,
-- LOG_CONNECTION_DEBUG,
--
- LOG_DHT_CRITICAL,
- LOG_DHT_ERROR,
- LOG_DHT_WARN,
-@@ -113,6 +71,14 @@ enum {
-
- LOG_NON_CASCADING,
-
-+ LOG_CONNECTION,
-+ LOG_CONNECTION_BIND,
-+ LOG_CONNECTION_FD,
-+ LOG_CONNECTION_FILTER,
-+ LOG_CONNECTION_HANDSHAKE,
-+ LOG_CONNECTION_LISTEN,
-+
-+ // TODO: Rename dht_all to just dht.
- LOG_DHT_ALL,
- LOG_DHT_MANAGER,
- LOG_DHT_NODE,
-@@ -125,7 +91,10 @@ enum {
- LOG_INSTRUMENTATION_POLLING,
- LOG_INSTRUMENTATION_TRANSFERS,
-
-+ LOG_MOCK_CALLS,
-+
- LOG_PEER_LIST_EVENTS,
-+ LOG_PEER_LIST_ADDRESS,
-
- LOG_PROTOCOL_PIECE_EVENTS,
- LOG_PROTOCOL_METADATA_EVENTS,
-@@ -137,6 +106,8 @@ enum {
- LOG_RPC_EVENTS,
- LOG_RPC_DUMP,
-
-+ LOG_SYSTEM,
-+
- LOG_UI_EVENTS,
-
- LOG_GROUP_MAX_SIZE
-@@ -145,34 +116,32 @@ enum {
- #define lt_log_is_valid(log_group) (torrent::log_groups[log_group].valid())
-
- #define lt_log_print(log_group, ...) \
-- if (torrent::log_groups[log_group].valid()) \
-- torrent::log_groups[log_group].internal_print(NULL, NULL, NULL, 0, __VA_ARGS__);
-+ { if (torrent::log_groups[log_group].valid()) \
-+ torrent::log_groups[log_group].internal_print(NULL, NULL, NULL, 0, __VA_ARGS__); }
-
- #define lt_log_print_info(log_group, log_info, log_subsystem, ...) \
-- if (torrent::log_groups[log_group].valid()) \
-- torrent::log_groups[log_group].internal_print(&log_info->hash(), log_subsystem, NULL, 0, __VA_ARGS__);
-+ { if (torrent::log_groups[log_group].valid()) \
-+ torrent::log_groups[log_group].internal_print(&log_info->hash(), log_subsystem, NULL, 0, __VA_ARGS__); }
-
- #define lt_log_print_data(log_group, log_data, log_subsystem, ...) \
-- if (torrent::log_groups[log_group].valid()) \
-- torrent::log_groups[log_group].internal_print(&log_data->hash(), log_subsystem, NULL, 0, __VA_ARGS__);
-+ { if (torrent::log_groups[log_group].valid()) \
-+ torrent::log_groups[log_group].internal_print(&log_data->hash(), log_subsystem, NULL, 0, __VA_ARGS__); }
-
- #define lt_log_print_dump(log_group, log_dump_data, log_dump_size, ...) \
-- if (torrent::log_groups[log_group].valid()) \
-- torrent::log_groups[log_group].internal_print(NULL, NULL, log_dump_data, log_dump_size, __VA_ARGS__); \
-+ { if (torrent::log_groups[log_group].valid()) \
-+ torrent::log_groups[log_group].internal_print(NULL, NULL, log_dump_data, log_dump_size, __VA_ARGS__); }
-
- #define lt_log_print_hash(log_group, log_hash, log_subsystem, ...) \
-- if (torrent::log_groups[log_group].valid()) \
-- torrent::log_groups[log_group].internal_print(&log_hash, log_subsystem, NULL, 0, __VA_ARGS__);
-+ { if (torrent::log_groups[log_group].valid()) \
-+ torrent::log_groups[log_group].internal_print(&log_hash, log_subsystem, NULL, 0, __VA_ARGS__); }
-
- #define lt_log_print_info_dump(log_group, log_dump_data, log_dump_size, log_info, log_subsystem, ...) \
-- if (torrent::log_groups[log_group].valid()) \
-- torrent::log_groups[log_group].internal_print(&log_info->hash(), log_subsystem, log_dump_data, log_dump_size, __VA_ARGS__); \
-+ { if (torrent::log_groups[log_group].valid()) \
-+ torrent::log_groups[log_group].internal_print(&log_info->hash(), log_subsystem, log_dump_data, log_dump_size, __VA_ARGS__); }
-
- #define lt_log_print_subsystem(log_group, log_subsystem, ...) \
-- if (torrent::log_groups[log_group].valid()) \
-- torrent::log_groups[log_group].internal_print(NULL, log_subsystem, NULL, 0, __VA_ARGS__);
--
--class log_buffer;
-+ { if (torrent::log_groups[log_group].valid()) \
-+ torrent::log_groups[log_group].internal_print(NULL, log_subsystem, NULL, 0, __VA_ARGS__); }
-
- typedef std::function<void (const char*, unsigned int, int)> log_slot;
-
-@@ -222,7 +191,7 @@ private:
-
- typedef std::array<log_group, LOG_GROUP_MAX_SIZE> log_group_list;
-
--extern log_group_list log_groups LIBTORRENT_EXPORT;
-+extern log_group_list log_groups LIBTORRENT_EXPORT;
-
- void log_initialize() LIBTORRENT_EXPORT;
- void log_cleanup() LIBTORRENT_EXPORT;
-@@ -237,9 +206,8 @@ void log_remove_group_output(int group, const char* name) LIBTORRENT_EXPORT;
- void log_add_child(int group, int child) LIBTORRENT_EXPORT;
- void log_remove_child(int group, int child) LIBTORRENT_EXPORT;
-
--void log_open_file_output(const char* name, const char* filename, bool append = false) LIBTORRENT_EXPORT;
--void log_open_gz_file_output(const char* name, const char* filename, bool append = false) LIBTORRENT_EXPORT;
--log_buffer* log_open_log_buffer(const char* name) LIBTORRENT_EXPORT;
-+void log_open_file_output(const char* name, const char* filename, bool append = false) LIBTORRENT_EXPORT;
-+void log_open_gz_file_output(const char* name, const char* filename, bool append = false) LIBTORRENT_EXPORT;
-
- //
- // Implementation:
-diff --git a/src/torrent/utils/log_buffer.cc b/src/torrent/utils/log_buffer.cc
-index f82d57e0..5bf159a4 100644
---- a/src/torrent/utils/log_buffer.cc
-+++ b/src/torrent/utils/log_buffer.cc
-@@ -1,46 +1,8 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #include "config.h"
-
- #include "log_buffer.h"
-
--#include <functional>
--#include lt_tr1_functional
--
-+#include "log.h"
- #include "globals.h"
-
- namespace torrent {
-@@ -72,4 +34,19 @@ log_buffer::lock_and_push_log(const char* data, size_t length, int group) {
- unlock();
- }
-
-+static void
-+log_buffer_deleter(log_buffer* lb) {
-+ delete lb;
-+}
-+
-+log_buffer_ptr
-+log_open_log_buffer(const char* name) {
-+ // TODO: Deregister when deleting.
-+ auto buffer = log_buffer_ptr(new log_buffer, std::bind(&log_buffer_deleter, std::placeholders::_1));
-+
-+ log_open_output(name, std::bind(&log_buffer::lock_and_push_log, buffer.get(),
-+ std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
-+ return buffer;
-+}
-+
- }
-diff --git a/src/torrent/utils/log_buffer.h b/src/torrent/utils/log_buffer.h
-index befd780b..259e5910 100644
---- a/src/torrent/utils/log_buffer.h
-+++ b/src/torrent/utils/log_buffer.h
-@@ -1,47 +1,11 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
--#ifndef LIBTORRENT_UTILS_LOG_BUFFER_H
--#define LIBTORRENT_UTILS_LOG_BUFFER_H
-+#ifndef LIBTORRENT_TORRENT_UTILS_LOG_BUFFER_H
-+#define LIBTORRENT_TORRENT_UTILS_LOG_BUFFER_H
-
- #include <string>
- #include <deque>
-+#include <functional>
-+#include <memory>
- #include <pthread.h>
--#include lt_tr1_functional
--#include <torrent/common.h>
-
- namespace torrent {
-
-@@ -57,9 +21,9 @@ struct log_entry {
- std::string message;
- };
-
--class LIBTORRENT_EXPORT log_buffer : private std::deque<log_entry> {
-+class [[gnu::visibility("default")]] log_buffer : private std::deque<log_entry> {
- public:
-- typedef std::deque<log_entry> base_type;
-+ typedef std::deque<log_entry> base_type;
- typedef std::function<void ()> slot_void;
-
- using base_type::iterator;
-@@ -97,6 +61,10 @@ private:
- slot_void m_slot_update;
- };
-
-+typedef std::unique_ptr<log_buffer, std::function<void (log_buffer*)>> log_buffer_ptr;
-+
-+[[gnu::visibility("default")]] log_buffer_ptr log_open_log_buffer(const char* name);
-+
- }
-
- #endif
-diff --git a/src/torrent/utils/net.cc b/src/torrent/utils/net.cc
-deleted file mode 100644
-index 83c9b506..00000000
---- a/src/torrent/utils/net.cc
-+++ /dev/null
-@@ -1,72 +0,0 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
--#include "config.h"
--
--#include "net.h"
--#include "exceptions.h"
--
--#include <cstring>
--
--namespace torrent {
--
--addrinfo*
--address_info_lookup(const char* hostname, int family, int socktype) {
-- addrinfo hints;
-- std::memset(&hints, 0, sizeof(addrinfo));
-- hints.ai_family = family;
-- hints.ai_socktype = socktype;
--
-- addrinfo* res = NULL;
-- int err = ::getaddrinfo(hostname, NULL, &hints, &res);
--
-- if (err)
-- throw address_info_error(err);
--
-- return res;
--}
--
--bool
--address_info_call(addrinfo* ai, int flags, slot_ai_success slot_success) {
-- while (ai != NULL) {
-- slot_success(ai->ai_addr, ai->ai_addrlen);
-- return true;
-- }
--
-- return false;
--}
--
--}
-diff --git a/src/torrent/utils/net.h b/src/torrent/utils/net.h
-deleted file mode 100644
-index f5af7cc0..00000000
---- a/src/torrent/utils/net.h
-+++ /dev/null
-@@ -1,56 +0,0 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
--#ifndef LIBTORRENT_UTILS_NET_H
--#define LIBTORRENT_UTILS_NET_H
--
--#include <netdb.h>
--#include lt_tr1_functional
--
--namespace torrent {
--
--typedef std::function<void (sockaddr*, socklen_t)> slot_ai_success;
--//typedef std::function<void (const char*, int)> slot_ai_failure;
--
--// Throws address_info_error on lookup failure.
--addrinfo* address_info_lookup(const char* hostname, int family, int socktype);
--inline void address_info_free(addrinfo* ai) { ::freeaddrinfo(ai); }
--
--bool address_info_call(addrinfo* ai, int flags, slot_ai_success slot_success);
--
--}
--
--#endif
-diff --git a/src/torrent/utils/option_strings.cc b/src/torrent/utils/option_strings.cc
-index 5992cf37..101e2688 100644
---- a/src/torrent/utils/option_strings.cc
-+++ b/src/torrent/utils/option_strings.cc
-@@ -62,7 +62,7 @@ struct option_pair {
- unsigned int value;
- };
-
--option_pair option_list_connection[] = {
-+option_pair option_list_connection_type[] = {
- { "leech", Download::CONNECTION_LEECH },
- { "seed", Download::CONNECTION_SEED },
- { "initial_seed", Download::CONNECTION_INITIAL_SEED },
-@@ -124,6 +124,19 @@ option_pair option_list_tracker_mode[] = {
- { NULL, 0 }
- };
-
-+const char* option_list_handshake_connection[] = {
-+ "none",
-+ "incoming",
-+ "outgoing_normal",
-+ "outgoing_encrypted",
-+ "outgoing_proxy",
-+ "success",
-+ "dropped",
-+ "failed",
-+ "retry_plaintext",
-+ "retry_encrypted"
-+};
-+
- const char* option_list_log_group[] = {
- "critical",
- "error",
-@@ -132,13 +145,6 @@ const char* option_list_log_group[] = {
- "info",
- "debug",
-
-- "connection_critical",
-- "connection_error",
-- "connection_warn",
-- "connection_notice",
-- "connection_info",
-- "connection_debug",
--
- "dht_critical",
- "dht_error",
- "dht_warn",
-@@ -190,6 +196,13 @@ const char* option_list_log_group[] = {
-
- "__non_cascading__",
-
-+ "connection",
-+ "connection_bind",
-+ "connection_fd",
-+ "connection_filter",
-+ "connection_hanshake",
-+ "connection_listen",
-+
- "dht_all",
- "dht_manager",
- "dht_node",
-@@ -202,7 +215,10 @@ const char* option_list_log_group[] = {
- "instrumentation_polling",
- "instrumentation_transfers",
-
-+ "mock_calls",
-+
- "peer_list_events",
-+ "peer_list_address",
-
- "protocol_piece_events",
- "protocol_metadata_events",
-@@ -214,6 +230,8 @@ const char* option_list_log_group[] = {
- "rpc_events",
- "rpc_dump",
-
-+ "system",
-+
- "ui_events",
-
- NULL
-@@ -230,7 +248,7 @@ const char* option_list_tracker_event[] = {
- };
-
- option_pair* option_pair_lists[OPTION_START_COMPACT] = {
-- option_list_connection,
-+ option_list_connection_type,
- option_list_heuristics,
- option_list_heuristics_download,
- option_list_heuristics_upload,
-@@ -244,6 +262,7 @@ option_pair* option_pair_lists[OPTION_START_COMPACT] = {
- { sizeof(single_name) / sizeof(const char*) - 1, single_name }
-
- option_single option_single_lists[OPTION_SINGLE_SIZE] = {
-+ OPTION_SINGLE_ENTRY(option_list_handshake_connection),
- OPTION_SINGLE_ENTRY(option_list_log_group),
- OPTION_SINGLE_ENTRY(option_list_tracker_event),
- };
-@@ -267,11 +286,11 @@ option_find_string(option_enum opt_enum, const char* name) {
- } while (*++itr != NULL);
- }
-
-- throw input_error("Invalid option name.");
-+ throw input_error("Invalid option name.");
- }
-
- const char*
--option_as_string(option_enum opt_enum, unsigned int value) {
-+option_to_string(option_enum opt_enum, unsigned int value, const char* not_found) {
- if (opt_enum < OPTION_START_COMPACT) {
- option_pair* itr = option_pair_lists[opt_enum];
-
-@@ -285,7 +304,27 @@ option_as_string(option_enum opt_enum, unsigned int value) {
- return option_single_lists[opt_enum - OPTION_START_COMPACT].name[value];
- }
-
-- throw input_error("Invalid option value.");
-+ return not_found;
-+}
-+
-+const char*
-+option_to_string_or_throw(option_enum opt_enum, unsigned int value, const char* not_found) {
-+ const char* result = option_to_string(opt_enum, value, NULL);
-+
-+ if (result == NULL)
-+ throw input_error(not_found);
-+ else
-+ return result;
-+}
-+
-+const char*
-+option_as_string(option_enum opt_enum, unsigned int value) {
-+ const char* result = option_to_string(opt_enum, value, NULL);
-+
-+ if (result == NULL)
-+ throw input_error("Invalid option value.");
-+ else
-+ return result;
- }
-
- torrent::Object
-diff --git a/src/torrent/utils/option_strings.h b/src/torrent/utils/option_strings.h
-index 1b57efa8..f9e5ef77 100644
---- a/src/torrent/utils/option_strings.h
-+++ b/src/torrent/utils/option_strings.h
-@@ -54,17 +54,22 @@ enum option_enum {
- OPTION_IP_TOS,
- OPTION_TRACKER_MODE,
-
-+ OPTION_HANDSHAKE_CONNECTION,
- OPTION_LOG_GROUP,
- OPTION_TRACKER_EVENT,
-
- OPTION_MAX_SIZE,
-- OPTION_START_COMPACT = OPTION_LOG_GROUP,
-+ OPTION_START_COMPACT = OPTION_HANDSHAKE_CONNECTION,
- OPTION_SINGLE_SIZE = OPTION_MAX_SIZE - OPTION_START_COMPACT
- };
-
- int option_find_string(option_enum opt_enum, const char* name) LIBTORRENT_EXPORT;
- inline int option_find_string_str(option_enum opt_enum, const std::string& name) { return option_find_string(opt_enum, name.c_str()); }
-
-+const char* option_to_string(option_enum opt_enum, unsigned int value, const char* not_found = "invalid") LIBTORRENT_EXPORT;
-+const char* option_to_string_or_throw(option_enum opt_enum, unsigned int value, const char* not_found = "Invalid option value") LIBTORRENT_EXPORT;
-+
-+// TODO: Deprecated.
- const char* option_as_string(option_enum opt_enum, unsigned int value) LIBTORRENT_EXPORT;
-
- torrent::Object option_list_strings(option_enum opt_enum) LIBTORRENT_EXPORT;
-diff --git a/src/torrent/utils/random.cc b/src/torrent/utils/random.cc
-new file mode 100644
-index 00000000..6a045429
---- /dev/null
-+++ b/src/torrent/utils/random.cc
-@@ -0,0 +1,29 @@
-+#include "config.h"
-+
-+#include "random.h"
-+
-+#include "torrent/exceptions.h"
-+
-+namespace torrent {
-+
-+// TODO: Replace with std and thread_local generator.
-+
-+template <typename T>
-+T
-+random_uniform_template(T min, T max) {
-+ if (min > max)
-+ throw internal_error("random_uniform: min > max");
-+
-+ if (min == max)
-+ return min;
-+
-+ std::random_device rd;
-+ std::mt19937 mt(rd());
-+
-+ return min + std::uniform_int_distribution<T>(min, max)(mt) % (max - min + 1);
-+}
-+
-+uint16_t random_uniform_uint16(uint16_t min, uint16_t max) { return random_uniform_template<uint16_t>(min, max); }
-+uint32_t random_uniform_uint32(uint32_t min, uint32_t max) { return random_uniform_template<uint32_t>(min, max); }
-+
-+}
-diff --git a/src/torrent/utils/random.h b/src/torrent/utils/random.h
-new file mode 100644
-index 00000000..d5992ab6
---- /dev/null
-+++ b/src/torrent/utils/random.h
-@@ -0,0 +1,15 @@
-+#ifndef LIBTORRENT_TORRENT_UTILS_RANDOM_H
-+#define LIBTORRENT_TORRENT_UTILS_RANDOM_H
-+
-+#include <cinttypes>
-+#include <limits>
-+#include <random>
-+
-+namespace torrent {
-+
-+[[gnu::weak]] [[gnu::visibility("default")]] uint16_t random_uniform_uint16(uint16_t min = std::numeric_limits<uint16_t>::min(), uint16_t max = std::numeric_limits<uint16_t>::max());
-+[[gnu::weak]] [[gnu::visibility("default")]] uint32_t random_uniform_uint32(uint32_t min = std::numeric_limits<uint32_t>::min(), uint32_t max = std::numeric_limits<uint32_t>::max());
-+
-+}
-+
-+#endif
-diff --git a/src/torrent/utils/ranges.h b/src/torrent/utils/ranges.h
-index e784b084..7b1f8cb0 100644
---- a/src/torrent/utils/ranges.h
-+++ b/src/torrent/utils/ranges.h
-@@ -40,7 +40,6 @@
- #include <algorithm>
- #include <vector>
-
--// TODO: Use tr1 functional instead.
- #include <rak/functional.h>
-
- namespace torrent {
-diff --git a/src/torrent/utils/resume.cc b/src/torrent/utils/resume.cc
-index 3f528c14..f8467d54 100644
---- a/src/torrent/utils/resume.cc
-+++ b/src/torrent/utils/resume.cc
-@@ -34,8 +34,6 @@
- // Skomakerveien 33
- // 3185 Skoppum, NORWAY
-
--#define __STDC_FORMAT_MACROS
--
- #include "config.h"
-
- #include <rak/file_stat.h>
-diff --git a/src/torrent/utils/signal_bitfield.h b/src/torrent/utils/signal_bitfield.h
-index b9f57a60..ffa336d2 100644
---- a/src/torrent/utils/signal_bitfield.h
-+++ b/src/torrent/utils/signal_bitfield.h
-@@ -37,7 +37,8 @@
- #ifndef LIBTORRENT_UTILS_SIGNAL_BITFIELD_H
- #define LIBTORRENT_UTILS_SIGNAL_BITFIELD_H
-
--#include lt_tr1_functional
-+#include <functional>
-+
- #include <torrent/common.h>
-
- namespace torrent {
-diff --git a/src/torrent/utils/thread_base.h b/src/torrent/utils/thread_base.h
-index bfd443ae..b92a98ba 100644
---- a/src/torrent/utils/thread_base.h
-+++ b/src/torrent/utils/thread_base.h
-@@ -37,11 +37,12 @@
- #ifndef LIBTORRENT_UTILS_THREAD_BASE_H
- #define LIBTORRENT_UTILS_THREAD_BASE_H
-
-+#include <functional>
- #include <pthread.h>
- #include <sys/types.h>
-+
- #include <torrent/common.h>
- #include <torrent/utils/signal_bitfield.h>
--#include lt_tr1_functional
-
- namespace torrent {
-
-diff --git a/src/utils/instrumentation.cc b/src/utils/instrumentation.cc
-index 729b20e2..178d6a19 100644
---- a/src/utils/instrumentation.cc
-+++ b/src/utils/instrumentation.cc
-@@ -36,8 +36,6 @@
-
- #include "config.h"
-
--#define __STDC_FORMAT_MACROS
--
- #include "instrumentation.h"
-
- namespace torrent {
-diff --git a/src/utils/instrumentation.h b/src/utils/instrumentation.h
-index 956429bf..11e77f6d 100644
---- a/src/utils/instrumentation.h
-+++ b/src/utils/instrumentation.h
-@@ -37,9 +37,8 @@
- #ifndef LIBTORRENT_UTILS_INSTRUMENTATION_H
- #define LIBTORRENT_UTILS_INSTRUMENTATION_H
-
--#include lt_tr1_array
--
- #include <algorithm>
-+#include <array>
-
- #include "torrent/common.h"
- #include "torrent/utils/log.h"
-diff --git a/src/utils/queue_buckets.h b/src/utils/queue_buckets.h
-index de8584ff..b9174f27 100644
---- a/src/utils/queue_buckets.h
-+++ b/src/utils/queue_buckets.h
-@@ -38,9 +38,9 @@
- #define LIBTORRENT_QUEUE_BUCKETS_H
-
- #include <algorithm>
-+#include <array>
- #include <deque>
--#include lt_tr1_functional
--#include lt_tr1_array
-+#include <functional>
-
- namespace torrent {
-
-diff --git a/src/utils/sha_fast.h b/src/utils/sha_fast.h
-index f7ce3b87..eb357864 100644
---- a/src/utils/sha_fast.h
-+++ b/src/utils/sha_fast.h
-@@ -41,7 +41,7 @@
- #ifndef _SHA_FAST_H_
- #define _SHA_FAST_H_
-
--#include <inttypes.h>
-+#include <cinttypes>
-
- namespace torrent {
-
-diff --git a/test/Makefile.am b/test/Makefile.am
-index d7a9d5b3..b60a86a6 100644
---- a/test/Makefile.am
-+++ b/test/Makefile.am
-@@ -18,6 +18,17 @@ LibTorrentTest_LDADD = \
- ../src/torrent/utils/libsub_torrentutils.la
-
- LibTorrentTest_SOURCES = \
-+ helpers/expect_fd.h \
-+ helpers/expect_utils.h \
-+ helpers/mock_compare.h \
-+ helpers/mock_function.cc \
-+ helpers/mock_function.h \
-+ helpers/network.h \
-+ helpers/progress_listener.cc \
-+ helpers/progress_listener.h \
-+ helpers/test_fixture.cc \
-+ helpers/test_fixture.h \
-+ \
- ../src/thread_disk.cc \
- ../src/thread_disk.h \
- \
-@@ -31,22 +42,28 @@ LibTorrentTest_SOURCES = \
- data/hash_check_queue_test.h \
- data/hash_queue_test.cc \
- data/hash_queue_test.h \
-+ \
-+ net/test_socket_listen.cc \
-+ net/test_socket_listen.h \
-+ \
- protocol/test_request_list.cc \
- protocol/test_request_list.h \
- \
-- torrent/net/test_socket_address_key.cc \
-- torrent/net/test_socket_address_key.h \
-+ torrent/net/test_address_info.cc \
-+ torrent/net/test_address_info.h \
-+ torrent/net/test_fd.cc \
-+ torrent/net/test_fd.h \
-+ torrent/net/test_socket_address.cc \
-+ torrent/net/test_socket_address.h \
- \
- torrent/utils/log_test.cc \
- torrent/utils/log_test.h \
-- torrent/utils/log_buffer_test.cc \
-- torrent/utils/log_buffer_test.h \
-- torrent/utils/net_test.cc \
-- torrent/utils/net_test.h \
- torrent/utils/option_strings_test.cc \
- torrent/utils/option_strings_test.h \
- torrent/utils/test_extents.cc \
- torrent/utils/test_extents.h \
-+ torrent/utils/test_log_buffer.cc \
-+ torrent/utils/test_log_buffer.h \
- torrent/utils/test_queue_buckets.cc \
- torrent/utils/test_queue_buckets.h \
- torrent/utils/test_uri_parser.cc \
-diff --git a/test/data/hash_check_queue_test.cc b/test/data/hash_check_queue_test.cc
-index c6bdeaec..4b15245e 100644
---- a/test/data/hash_check_queue_test.cc
-+++ b/test/data/hash_check_queue_test.cc
-@@ -1,7 +1,7 @@
- #include "config.h"
-
-+#include <functional>
- #include <signal.h>
--#include lt_tr1_functional
-
- #include "data/hash_queue_node.h"
- #include "utils/sha1.h"
-diff --git a/test/data/hash_queue_test.cc b/test/data/hash_queue_test.cc
-index 287c28e9..d7ce3ba8 100644
---- a/test/data/hash_queue_test.cc
-+++ b/test/data/hash_queue_test.cc
-@@ -1,7 +1,7 @@
- #include "config.h"
-
-+#include <functional>
- #include <signal.h>
--#include lt_tr1_functional
-
- #include "data/hash_queue_node.h"
- #include "torrent/chunk_manager.h"
-diff --git a/test/helpers/expect_fd.h b/test/helpers/expect_fd.h
-new file mode 100644
-index 00000000..178cbabc
---- /dev/null
-+++ b/test/helpers/expect_fd.h
-@@ -0,0 +1,107 @@
-+#ifndef LIBTORRENT_HELPER_EXPECT_FD_H
-+#define LIBTORRENT_HELPER_EXPECT_FD_H
-+
-+#include "helpers/mock_function.h"
-+
-+#include <fcntl.h>
-+#include <torrent/event.h>
-+#include <torrent/net/fd.h>
-+#include <torrent/net/socket_address.h>
-+
-+typedef std::vector<torrent::sa_unique_ptr> sap_cache_type;
-+
-+inline const sockaddr*
-+sap_cache_copy_addr_c_ptr(sap_cache_type& sap_cache, const torrent::c_sa_unique_ptr& sap, uint16_t port = 0) {
-+ sap_cache.push_back(torrent::sap_copy_addr(sap, port));
-+ return sap_cache.back().get();
-+}
-+
-+inline void
-+expect_event_open_re(int idx) {
-+ mock_expect(&torrent::poll_event_open, mock_compare_map<torrent::Event>::begin_pointer + idx);
-+ mock_expect(&torrent::poll_event_insert_read, mock_compare_map<torrent::Event>::begin_pointer + idx);
-+ mock_expect(&torrent::poll_event_insert_error, mock_compare_map<torrent::Event>::begin_pointer + idx);
-+}
-+
-+inline void
-+expect_event_closed_fd(int idx, int fd) {
-+ mock_expect(&torrent::fd__close, 0, fd);
-+ mock_expect(&torrent::poll_event_closed, mock_compare_map<torrent::Event>::begin_pointer + idx);
-+}
-+
-+inline void
-+expect_fd_inet_tcp(int fd) {
-+ mock_expect(&torrent::fd__socket, fd, (int)PF_INET, (int)SOCK_STREAM, (int)IPPROTO_TCP);
-+}
-+
-+inline void
-+expect_fd_inet6_tcp(int fd) {
-+ mock_expect(&torrent::fd__socket, fd, (int)PF_INET6, (int)SOCK_STREAM, (int)IPPROTO_TCP);
-+}
-+
-+inline void
-+expect_fd_inet_tcp_nonblock(int fd) {
-+ mock_expect(&torrent::fd__socket, fd, (int)PF_INET, (int)SOCK_STREAM, (int)IPPROTO_TCP);
-+ mock_expect(&torrent::fd__fcntl_int, 0, fd, F_SETFL, O_NONBLOCK);
-+}
-+
-+inline void
-+expect_fd_inet6_tcp_nonblock(int fd) {
-+ mock_expect(&torrent::fd__socket, fd, (int)PF_INET6, (int)SOCK_STREAM, (int)IPPROTO_TCP);
-+ mock_expect(&torrent::fd__fcntl_int, 0, fd, F_SETFL, O_NONBLOCK);
-+}
-+
-+inline void
-+expect_fd_inet_tcp_nonblock_reuseaddr(int fd) {
-+ mock_expect(&torrent::fd__socket, fd, (int)PF_INET, (int)SOCK_STREAM, (int)IPPROTO_TCP);
-+ mock_expect(&torrent::fd__fcntl_int, 0, fd, F_SETFL, O_NONBLOCK);
-+ mock_expect(&torrent::fd__setsockopt_int, 0, fd, (int)SOL_SOCKET, (int)SO_REUSEADDR, (int)true);
-+}
-+
-+inline void
-+expect_fd_inet6_tcp_nonblock_reuseaddr(int fd) {
-+ mock_expect(&torrent::fd__socket, fd, (int)PF_INET6, (int)SOCK_STREAM, (int)IPPROTO_TCP);
-+ mock_expect(&torrent::fd__fcntl_int, 0, fd, F_SETFL, O_NONBLOCK);
-+ mock_expect(&torrent::fd__setsockopt_int, 0, fd, (int)SOL_SOCKET, (int)SO_REUSEADDR, (int)true);
-+}
-+
-+inline void
-+expect_fd_inet6_tcp_v6only_nonblock(int fd) {
-+ mock_expect(&torrent::fd__socket, fd, (int)PF_INET6, (int)SOCK_STREAM, (int)IPPROTO_TCP);
-+ mock_expect(&torrent::fd__setsockopt_int, 0, fd, (int)IPPROTO_IPV6, (int)IPV6_V6ONLY, (int)true);
-+ mock_expect(&torrent::fd__fcntl_int, 0, fd, F_SETFL, O_NONBLOCK);
-+}
-+
-+inline void
-+expect_fd_inet6_tcp_v6only_nonblock_reuseaddr(int fd) {
-+ mock_expect(&torrent::fd__socket, fd, (int)PF_INET6, (int)SOCK_STREAM, (int)IPPROTO_TCP);
-+ mock_expect(&torrent::fd__setsockopt_int, 0, fd, (int)IPPROTO_IPV6, (int)IPV6_V6ONLY, (int)true);
-+ mock_expect(&torrent::fd__fcntl_int, 0, fd, F_SETFL, O_NONBLOCK);
-+ mock_expect(&torrent::fd__setsockopt_int, 0, fd, (int)SOL_SOCKET, (int)SO_REUSEADDR, (int)true);
-+}
-+
-+inline void
-+expect_fd_bind_connect(int fd, const torrent::c_sa_unique_ptr& bind_sap, const torrent::c_sa_unique_ptr& connect_sap) {
-+ mock_expect(&torrent::fd__bind, 0, fd, bind_sap.get(), (socklen_t)torrent::sap_length(bind_sap));
-+ mock_expect(&torrent::fd__connect, 0, fd, connect_sap.get(), (socklen_t)torrent::sap_length(connect_sap));
-+}
-+
-+inline void
-+expect_fd_bind_fail_range(int fd, sap_cache_type& sap_cache, const torrent::c_sa_unique_ptr& sap, uint16_t first_port, uint16_t last_port) {
-+ do {
-+ mock_expect(&torrent::fd__bind, -1, fd, sap_cache_copy_addr_c_ptr(sap_cache, sap, first_port), (socklen_t)torrent::sap_length(sap));
-+ } while (first_port++ != last_port);
-+}
-+
-+inline void
-+expect_fd_bind_listen(int fd, const torrent::c_sa_unique_ptr& sap) {
-+ mock_expect(&torrent::fd__bind, 0, fd, sap.get(), (socklen_t)torrent::sap_length(sap));
-+ mock_expect(&torrent::fd__listen, 0, fd, SOMAXCONN);
-+}
-+
-+inline void
-+expect_fd_connect(int fd, const torrent::c_sa_unique_ptr& sap) {
-+ mock_expect(&torrent::fd__connect, 0, fd, sap.get(), (socklen_t)torrent::sap_length(sap));
-+}
-+
-+#endif
-diff --git a/test/helpers/expect_utils.h b/test/helpers/expect_utils.h
-new file mode 100644
-index 00000000..c84a11e0
---- /dev/null
-+++ b/test/helpers/expect_utils.h
-@@ -0,0 +1,13 @@
-+#ifndef LIBTORRENT_HELPER_EXPECT_UTILS_H
-+#define LIBTORRENT_HELPER_EXPECT_UTILS_H
-+
-+#include "helpers/mock_function.h"
-+
-+#include <torrent/utils/random.h>
-+
-+inline void
-+expect_random_uniform_uint16(uint16_t result, uint16_t first, uint16_t last) {
-+ mock_expect(&torrent::random_uniform_uint16, result, first, last);
-+}
-+
-+#endif
-diff --git a/test/helpers/mock_compare.h b/test/helpers/mock_compare.h
-new file mode 100644
-index 00000000..3ea90305
---- /dev/null
-+++ b/test/helpers/mock_compare.h
-@@ -0,0 +1,96 @@
-+#ifndef LIBTORRENT_HELPERS_MOCK_COMPARE_H
-+#define LIBTORRENT_HELPERS_MOCK_COMPARE_H
-+
-+#include <algorithm>
-+#include <type_traits>
-+#include <torrent/event.h>
-+#include <torrent/net/socket_address.h>
-+
-+// Compare arguments to mock functions with what is expected. The lhs
-+// are the expected arguments, rhs are the ones called with.
-+
-+template <typename Arg>
-+inline bool mock_compare_arg(Arg lhs, Arg rhs) { return lhs == rhs; }
-+
-+template <int I, typename A, typename... Args>
-+typename std::enable_if<I == 1, int>::type
-+mock_compare_tuple(const std::tuple<A, Args...>& lhs, const std::tuple<Args...>& rhs) {
-+ return mock_compare_arg(std::get<I>(lhs), std::get<I - 1>(rhs)) ? 0 : 1;
-+}
-+
-+template <int I, typename A, typename... Args>
-+typename std::enable_if<1 < I, int>::type
-+mock_compare_tuple(const std::tuple<A, Args...>& lhs, const std::tuple<Args...>& rhs) {
-+ auto res = mock_compare_tuple<I - 1>(lhs, rhs);
-+
-+ if (res != 0)
-+ return res;
-+
-+ return mock_compare_arg(std::get<I>(lhs), std::get<I - 1>(rhs)) ? 0 : I;
-+}
-+
-+//template <typename T, typename std::enable_if<!std::is_const<T>::value, int>::type = 0>
-+template <typename T>
-+struct mock_compare_map {
-+ typedef std::map<const T*, const T*> values_type;
-+
-+ constexpr static T* begin_pointer = reinterpret_cast<T*>(0x1000);
-+ constexpr static T* end_pointer = reinterpret_cast<T*>(0x2000);
-+
-+ static bool is_key(const T* k) {
-+ return k >= begin_pointer && k < end_pointer;
-+ }
-+
-+ static bool has_key(const T* k) {
-+ return values.find(k) != values.end();
-+ }
-+
-+ static bool has_value(const T* v) {
-+ return std::find_if(values.begin(), values.end(), [v](typename values_type::value_type& kv) { return v == kv.second; }) != values.end();
-+ }
-+
-+ static const T* get(const T* k) {
-+ auto itr = values.find(k);
-+ CPPUNIT_ASSERT_MESSAGE("mock_compare_map get failed, not inserted", itr != values.end());
-+ return itr->second;
-+ }
-+
-+ static values_type values;
-+};
-+
-+template<typename T>
-+typename mock_compare_map<T>::values_type mock_compare_map<T>::values;
-+
-+template<typename T>
-+void mock_compare_add(T* v) {
-+ mock_compare_map<T>::add_value(v);
-+}
-+
-+//
-+// Specialize:
-+//
-+
-+template <>
-+inline bool mock_compare_arg<sockaddr*>(sockaddr* lhs, sockaddr* rhs) {
-+ return lhs != nullptr && rhs != nullptr && torrent::sa_equal(lhs, rhs);
-+}
-+template <>
-+inline bool mock_compare_arg<const sockaddr*>(const sockaddr* lhs, const sockaddr* rhs) {
-+ return lhs != nullptr && rhs != nullptr && torrent::sa_equal(lhs, rhs);
-+}
-+
-+template <>
-+inline bool mock_compare_arg<torrent::Event*>(torrent::Event* lhs, torrent::Event* rhs) {
-+ if (mock_compare_map<torrent::Event>::is_key(lhs)) {
-+ if (!mock_compare_map<torrent::Event>::has_value(rhs)) {
-+ mock_compare_map<torrent::Event>::values[lhs] = rhs;
-+ return true;
-+ }
-+
-+ return mock_compare_map<torrent::Event>::has_key(lhs) && mock_compare_map<torrent::Event>::get(lhs) == rhs;
-+ }
-+
-+ return lhs == rhs;
-+}
-+
-+#endif
-diff --git a/test/helpers/mock_function.cc b/test/helpers/mock_function.cc
-new file mode 100644
-index 00000000..83e81551
---- /dev/null
-+++ b/test/helpers/mock_function.cc
-@@ -0,0 +1,170 @@
-+#include "config.h"
-+
-+#include "mock_function.h"
-+
-+#include <fcntl.h>
-+#include <iostream>
-+#include <torrent/event.h>
-+#include <torrent/net/socket_address.h>
-+#include <torrent/net/fd.h>
-+#include <torrent/utils/log.h>
-+#include <torrent/utils/random.h>
-+
-+#define MOCK_CLEANUP_MAP(MOCK_FUNC) \
-+ CPPUNIT_ASSERT_MESSAGE("expected mock function calls not completed for '" #MOCK_FUNC "'", mock_cleanup_map(&MOCK_FUNC) || ignore_assert);
-+#define MOCK_LOG(log_fmt, ...) \
-+ lt_log_print(torrent::LOG_MOCK_CALLS, "%s: " log_fmt, __func__, __VA_ARGS__);
-+
-+void
-+mock_clear(bool ignore_assert) {
-+ MOCK_CLEANUP_MAP(torrent::fd__accept);
-+ MOCK_CLEANUP_MAP(torrent::fd__bind);
-+ MOCK_CLEANUP_MAP(torrent::fd__close);
-+ MOCK_CLEANUP_MAP(torrent::fd__connect);
-+ MOCK_CLEANUP_MAP(torrent::fd__fcntl_int);
-+ MOCK_CLEANUP_MAP(torrent::fd__listen);
-+ MOCK_CLEANUP_MAP(torrent::fd__setsockopt_int);
-+ MOCK_CLEANUP_MAP(torrent::fd__socket);
-+
-+ MOCK_CLEANUP_MAP(torrent::poll_event_open);
-+ MOCK_CLEANUP_MAP(torrent::poll_event_close);
-+ MOCK_CLEANUP_MAP(torrent::poll_event_closed);
-+ MOCK_CLEANUP_MAP(torrent::poll_event_insert_read);
-+ MOCK_CLEANUP_MAP(torrent::poll_event_insert_write);
-+ MOCK_CLEANUP_MAP(torrent::poll_event_insert_error);
-+ MOCK_CLEANUP_MAP(torrent::poll_event_remove_read);
-+ MOCK_CLEANUP_MAP(torrent::poll_event_remove_write);
-+ MOCK_CLEANUP_MAP(torrent::poll_event_remove_error);
-+
-+ MOCK_CLEANUP_MAP(torrent::random_uniform_uint16);
-+ MOCK_CLEANUP_MAP(torrent::random_uniform_uint32);
-+
-+ mock_compare_map<torrent::Event>::values.clear();
-+};
-+
-+void mock_init() {
-+ log_add_group_output(torrent::LOG_MOCK_CALLS, "test_output");
-+ mock_clear(true);
-+}
-+
-+void mock_cleanup() {
-+ mock_clear(false);
-+}
-+
-+namespace torrent {
-+
-+//
-+// Mock functions for 'torrent/net/fd.h':
-+//
-+
-+int fd__accept(int socket, sockaddr *address, socklen_t *address_len) {
-+ MOCK_LOG("entry socket:%i address:%s address_len:%u",
-+ socket, torrent::sa_pretty_str(address).c_str(), (unsigned int)(*address_len));
-+ auto ret = mock_call<int>(__func__, &torrent::fd__accept, socket, address, address_len);
-+ MOCK_LOG("exit socket:%i address:%s address_len:%u",
-+ socket, torrent::sa_pretty_str(address).c_str(), (unsigned int)(*address_len));
-+ return ret;
-+}
-+
-+int fd__bind(int socket, const sockaddr *address, socklen_t address_len) {
-+ MOCK_LOG("socket:%i address:%s address_len:%u",
-+ socket, torrent::sa_pretty_str(address).c_str(), (unsigned int)address_len);
-+ return mock_call<int>(__func__, &torrent::fd__bind, socket, address, address_len);
-+}
-+
-+int fd__close(int fildes) {
-+ MOCK_LOG("filedes:%i", fildes);
-+ return mock_call<int>(__func__, &torrent::fd__close, fildes);
-+}
-+
-+int fd__connect(int socket, const sockaddr *address, socklen_t address_len) {
-+ MOCK_LOG("socket:%i address:%s address_len:%u",
-+ socket, torrent::sa_pretty_str(address).c_str(), (unsigned int)address_len);
-+ return mock_call<int>(__func__, &torrent::fd__connect, socket, address, address_len);
-+}
-+
-+int fd__fcntl_int(int fildes, int cmd, int arg) {
-+ MOCK_LOG("filedes:%i cmd:%i arg:%i", fildes, cmd, arg);
-+ return mock_call<int>(__func__, &torrent::fd__fcntl_int, fildes, cmd, arg);
-+}
-+
-+int fd__listen(int socket, int backlog) {
-+ MOCK_LOG("socket:%i backlog:%i", socket, backlog);
-+ return mock_call<int>(__func__, &torrent::fd__listen, socket, backlog);
-+}
-+
-+int fd__setsockopt_int(int socket, int level, int option_name, int option_value) {
-+ MOCK_LOG("socket:%i level:%i option_name:%i option_value:%i",
-+ socket, level, option_name, option_value);
-+ return mock_call<int>(__func__, &torrent::fd__setsockopt_int, socket, level, option_name, option_value);
-+}
-+
-+int fd__socket(int domain, int type, int protocol) {
-+ MOCK_LOG("domain:%i type:%i protocol:%i", domain, type, protocol);
-+ return mock_call<int>(__func__, &torrent::fd__socket, domain, type, protocol);
-+}
-+
-+//
-+// Mock functions for 'torrent/event.h':
-+//
-+
-+void poll_event_open(Event* event) {
-+ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
-+ return mock_call<void>(__func__, &torrent::poll_event_open, event);
-+}
-+
-+void poll_event_close(Event* event) {
-+ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
-+ return mock_call<void>(__func__, &torrent::poll_event_close, event);
-+}
-+
-+void poll_event_closed(Event* event) {
-+ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
-+ return mock_call<void>(__func__, &torrent::poll_event_closed, event);
-+}
-+
-+void poll_event_insert_read(Event* event) {
-+ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
-+ return mock_call<void>(__func__, &torrent::poll_event_insert_read, event);
-+}
-+
-+void poll_event_insert_write(Event* event) {
-+ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
-+ return mock_call<void>(__func__, &torrent::poll_event_insert_write, event);
-+}
-+
-+void poll_event_insert_error(Event* event) {
-+ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
-+ return mock_call<void>(__func__, &torrent::poll_event_insert_error, event);
-+}
-+
-+void poll_event_remove_read(Event* event) {
-+ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
-+ return mock_call<void>(__func__, &torrent::poll_event_remove_read, event);
-+}
-+
-+void poll_event_remove_write(Event* event) {
-+ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
-+ return mock_call<void>(__func__, &torrent::poll_event_remove_write, event);
-+}
-+
-+void poll_event_remove_error(Event* event) {
-+ MOCK_LOG("fd:%i type_name:%s", event->file_descriptor(), event->type_name());
-+ return mock_call<void>(__func__, &torrent::poll_event_remove_error, event);
-+}
-+
-+//
-+// Mock functions for 'torrent/utils/random.h':
-+//
-+
-+uint16_t random_uniform_uint16(uint16_t min, uint16_t max) {
-+ MOCK_LOG("min:%" PRIu16 " max:%" PRIu16, min, max);
-+ return mock_call<uint16_t>(__func__, &torrent::random_uniform_uint16, min, max);
-+}
-+
-+uint32_t random_uniform_uint32(uint32_t min, uint32_t max) {
-+ MOCK_LOG("min:%" PRIu32 " max:%" PRIu32, min, max);
-+ return mock_call<uint32_t>(__func__, &torrent::random_uniform_uint32, min, max);
-+}
-+
-+}
-diff --git a/test/helpers/mock_function.h b/test/helpers/mock_function.h
-new file mode 100644
-index 00000000..6c194137
---- /dev/null
-+++ b/test/helpers/mock_function.h
-@@ -0,0 +1,133 @@
-+#ifndef LIBTORRENT_HELPERS_MOCK_FUNCTION_H
-+#define LIBTORRENT_HELPERS_MOCK_FUNCTION_H
-+
-+#include <functional>
-+#include <map>
-+#include <string>
-+#include <tuple>
-+#include <type_traits>
-+#include <utility>
-+#include <cppunit/extensions/HelperMacros.h>
-+
-+#include "helpers/mock_compare.h"
-+
-+template<typename R, typename... Args>
-+struct mock_function_map {
-+ typedef std::tuple<R, Args...> call_type;
-+ typedef std::vector<call_type> call_list_type;
-+ typedef std::map<void*, call_list_type> func_map_type;
-+
-+ typedef std::function<R (Args...)> function_type;
-+ typedef std::map<void*, function_type> redirect_map_type;
-+
-+ static func_map_type functions;
-+ static redirect_map_type redirects;
-+
-+ static bool cleanup(void* fn) {
-+ redirects.erase(fn);
-+ return functions.erase(fn) == 0;
-+ }
-+
-+ static R ret_erase(void* fn) {
-+ auto itr = functions.find(fn);
-+ auto ret = std::get<0>(itr->second.front());
-+ itr->second.erase(itr->second.begin());
-+
-+ if (itr->second.empty())
-+ functions.erase(itr);
-+
-+ return ret;
-+ }
-+};
-+
-+template<typename R, typename... Args>
-+typename mock_function_map<R, Args...>::func_map_type mock_function_map<R, Args...>::functions;
-+template<typename R, typename... Args>
-+typename mock_function_map<R, Args...>::redirect_map_type mock_function_map<R, Args...>::redirects;
-+
-+struct mock_void {};
-+
-+template<typename R, typename... Args>
-+struct mock_function_type {
-+ typedef mock_function_map<R, Args...> type;
-+
-+ static int compare_expected(typename type::call_type lhs, Args... rhs) {
-+ return mock_compare_tuple<sizeof...(Args)>(lhs, std::make_tuple(rhs...));
-+ }
-+
-+ static R ret_erase(void* fn) { return type::ret_erase(fn); }
-+ static bool has_redirect(void* fn) { return type::redirects.find(fn) != type::redirects.end(); }
-+ static R call_redirect(void* fn, Args... args) { return type::redirects.find(fn)->second(args...); }
-+};
-+
-+template<typename... Args>
-+struct mock_function_type<void, Args...> {
-+ typedef mock_function_map<mock_void, Args...> type;
-+
-+ static int compare_expected(typename type::call_type lhs, Args... rhs) {
-+ return mock_compare_tuple<sizeof...(Args)>(lhs, std::make_tuple(rhs...));
-+ }
-+
-+ static void ret_erase(void* fn) { type::ret_erase(fn); }
-+ static bool has_redirect(void* fn) { return type::redirects.find(fn) != type::redirects.end(); }
-+ static void call_redirect(void* fn, Args... args) { type::redirects.find(fn)->second(args...); }
-+};
-+
-+void mock_init();
-+void mock_cleanup();
-+
-+template<typename R, typename... Args>
-+bool
-+mock_cleanup_map(R fn[[gnu::unused]](Args...)) {
-+ return mock_function_type<R, Args...>::type::cleanup(reinterpret_cast<void*>(fn));
-+}
-+
-+template<typename R, typename... Args>
-+void
-+mock_expect(R fn(Args...), R ret, Args... args) {
-+ typedef mock_function_map<R, Args...> mock_map;
-+ mock_map::functions[reinterpret_cast<void*>(fn)].push_back(std::tuple<R, Args...>(ret, args...));
-+}
-+
-+template<typename... Args>
-+void
-+mock_expect(void fn(Args...), Args... args) {
-+ typedef mock_function_map<mock_void, Args...> mock_map;
-+ mock_map::functions[reinterpret_cast<void*>(fn)].push_back(std::tuple<mock_void, Args...>(mock_void(), args...));
-+}
-+
-+template<typename R, typename... Args>
-+void
-+mock_redirect(R fn(Args...), std::function<R (Args...)> func) {
-+ typedef mock_function_map<R, Args...> mock_map;
-+ mock_map::redirects[reinterpret_cast<void*>(fn)] = func;
-+}
-+
-+template<typename R, typename... Args>
-+auto
-+mock_call_direct(std::string name, R fn(Args...), Args... args) -> decltype(fn(args...)) {
-+ typedef mock_function_type<R, Args...> mock_type;
-+
-+ auto itr = mock_type::type::functions.find(reinterpret_cast<void*>(fn));
-+ CPPUNIT_ASSERT_MESSAGE(("mock_call expected function calls exhausted by '" + name + "'").c_str(),
-+ itr != mock_type::type::functions.end());
-+
-+ auto mismatch_arg = mock_type::compare_expected(itr->second.front(), args...);
-+ CPPUNIT_ASSERT_MESSAGE(("mock_call expected function call argument " + std::to_string(mismatch_arg) + " mismatch for '" + name + "'").c_str(),
-+ mismatch_arg == 0);
-+
-+ return mock_type::ret_erase(reinterpret_cast<void*>(fn));
-+}
-+
-+template<typename R, typename... Args>
-+auto
-+mock_call(std::string name, R fn(Args...), Args... args) -> decltype(fn(args...)) {
-+ typedef mock_function_type<R, Args...> mock_type;
-+
-+ if (mock_type::has_redirect(reinterpret_cast<void*>(fn)))
-+ return mock_type::call_redirect(reinterpret_cast<void*>(fn), args...);
-+
-+ return mock_call_direct(name, fn, args...);
-+}
-+
-+#endif
-diff --git a/test/helpers/network.h b/test/helpers/network.h
-new file mode 100644
-index 00000000..6cf2f870
---- /dev/null
-+++ b/test/helpers/network.h
-@@ -0,0 +1,182 @@
-+#ifndef LIBTORRENT_HELPER_NETWORK_H
-+#define LIBTORRENT_HELPER_NETWORK_H
-+
-+#include <functional>
-+#include <string>
-+#include <cppunit/extensions/HelperMacros.h>
-+
-+#include "torrent/net/address_info.h"
-+
-+//
-+// Socket addresses
-+//
-+
-+#define TEST_DEFAULT_SA \
-+ auto sin_any = wrap_ai_get_first_sa("0.0.0.0"); \
-+ auto sin_any_5000 = wrap_ai_get_first_sa("0.0.0.0", "5000"); \
-+ auto sin_any_5005 = wrap_ai_get_first_sa("0.0.0.0", "5005"); \
-+ auto sin_bc = wrap_ai_get_first_sa("255.255.255.255"); \
-+ auto sin_bc_5000 = wrap_ai_get_first_sa("255.255.255.255", "5000"); \
-+ auto sin_bnd = wrap_ai_get_first_sa("123.123.123.123"); \
-+ auto sin_1 = wrap_ai_get_first_sa("1.2.3.4"); \
-+ auto sin_1_5000 = wrap_ai_get_first_sa("1.2.3.4", "5000"); \
-+ auto sin_1_5005 = wrap_ai_get_first_sa("1.2.3.4", "5005"); \
-+ auto sin_1_5100 = wrap_ai_get_first_sa("1.2.3.4", "5100"); \
-+ auto sin_2 = wrap_ai_get_first_sa("4.3.2.1"); \
-+ auto sin_2_5000 = wrap_ai_get_first_sa("4.3.2.1", "5000"); \
-+ auto sin_2_5100 = wrap_ai_get_first_sa("4.3.2.1", "5100"); \
-+ \
-+ auto sin6_any = wrap_ai_get_first_sa("::"); \
-+ auto sin6_any_5000 = wrap_ai_get_first_sa("::", "5000"); \
-+ auto sin6_any_5005 = wrap_ai_get_first_sa("::", "5005"); \
-+ auto sin6_bnd = wrap_ai_get_first_sa("ff01::123"); \
-+ auto sin6_1 = wrap_ai_get_first_sa("ff01::1"); \
-+ auto sin6_1_5000 = wrap_ai_get_first_sa("ff01::1", "5000"); \
-+ auto sin6_1_5005 = wrap_ai_get_first_sa("ff01::1", "5005"); \
-+ auto sin6_1_5100 = wrap_ai_get_first_sa("ff01::1", "5100"); \
-+ auto sin6_2 = wrap_ai_get_first_sa("ff02::2"); \
-+ auto sin6_2_5000 = wrap_ai_get_first_sa("ff02::2", "5000"); \
-+ auto sin6_2_5100 = wrap_ai_get_first_sa("ff02::2", "5100"); \
-+ auto sin6_v4_1 = wrap_ai_get_first_sa("::ffff:1.2.3.4"); \
-+ auto sin6_v4_1_5000 = wrap_ai_get_first_sa("::ffff:1.2.3.4", "5000"); \
-+ auto sin6_v4_any = wrap_ai_get_first_sa("::ffff:0.0.0.0"); \
-+ auto sin6_v4_any_5000 = wrap_ai_get_first_sa("::ffff:0.0.0.0", "5000"); \
-+ auto sin6_v4_bc = wrap_ai_get_first_sa("::ffff:255.255.255.255"); \
-+ auto sin6_v4_bc_5000 = wrap_ai_get_first_sa("::ffff:255.255.255.255", "5000"); \
-+ auto sin6_v4_bnd = wrap_ai_get_first_sa("::ffff:123.123.123.123"); \
-+ \
-+ auto c_sin_any = wrap_ai_get_first_c_sa("0.0.0.0"); \
-+ auto c_sin_any_5000 = wrap_ai_get_first_c_sa("0.0.0.0", "5000"); \
-+ auto c_sin_any_5005 = wrap_ai_get_first_c_sa("0.0.0.0", "5005"); \
-+ auto c_sin_any_5010 = wrap_ai_get_first_c_sa("0.0.0.0", "5010"); \
-+ auto c_sin_any_6881 = wrap_ai_get_first_c_sa("0.0.0.0", "6881"); \
-+ auto c_sin_any_6900 = wrap_ai_get_first_c_sa("0.0.0.0", "6900"); \
-+ auto c_sin_any_6999 = wrap_ai_get_first_c_sa("0.0.0.0", "6999"); \
-+ auto c_sin_bc = wrap_ai_get_first_c_sa("255.255.255.255"); \
-+ auto c_sin_bc_5000 = wrap_ai_get_first_c_sa("255.255.255.255", "5000"); \
-+ auto c_sin_bnd = wrap_ai_get_first_c_sa("123.123.123.123"); \
-+ auto c_sin_bnd_5000 = wrap_ai_get_first_c_sa("123.123.123.123", "5000"); \
-+ auto c_sin_bnd_6881 = wrap_ai_get_first_c_sa("123.123.123.123", "6881"); \
-+ auto c_sin_bnd_6900 = wrap_ai_get_first_c_sa("123.123.123.123", "6900"); \
-+ auto c_sin_bnd_6999 = wrap_ai_get_first_c_sa("123.123.123.123", "6999"); \
-+ auto c_sin_1 = wrap_ai_get_first_c_sa("1.2.3.4"); \
-+ auto c_sin_1_5000 = wrap_ai_get_first_c_sa("1.2.3.4", "5000"); \
-+ auto c_sin_1_5005 = wrap_ai_get_first_c_sa("1.2.3.4", "5005"); \
-+ auto c_sin_1_5010 = wrap_ai_get_first_c_sa("1.2.3.4", "5010"); \
-+ auto c_sin_1_6881 = wrap_ai_get_first_c_sa("1.2.3.4", "6881"); \
-+ auto c_sin_1_6900 = wrap_ai_get_first_c_sa("1.2.3.4", "6900"); \
-+ auto c_sin_1_6999 = wrap_ai_get_first_c_sa("1.2.3.4", "6999"); \
-+ auto c_sin_2 = wrap_ai_get_first_c_sa("4.3.2.1"); \
-+ auto c_sin_2_5000 = wrap_ai_get_first_c_sa("4.3.2.1", "5000"); \
-+ auto c_sin_2_5100 = wrap_ai_get_first_c_sa("4.3.2.1", "5100"); \
-+ \
-+ auto c_sin6_any = wrap_ai_get_first_c_sa("::"); \
-+ auto c_sin6_any_5000 = wrap_ai_get_first_c_sa("::", "5000"); \
-+ auto c_sin6_any_5005 = wrap_ai_get_first_c_sa("::", "5005"); \
-+ auto c_sin6_any_5010 = wrap_ai_get_first_c_sa("::", "5010"); \
-+ auto c_sin6_any_6881 = wrap_ai_get_first_c_sa("::", "6881"); \
-+ auto c_sin6_any_6900 = wrap_ai_get_first_c_sa("::", "6900"); \
-+ auto c_sin6_any_6999 = wrap_ai_get_first_c_sa("::", "6999"); \
-+ auto c_sin6_bnd = wrap_ai_get_first_c_sa("ff01::123"); \
-+ auto c_sin6_bnd_5000 = wrap_ai_get_first_c_sa("ff01::123", "5000"); \
-+ auto c_sin6_bnd_6881 = wrap_ai_get_first_c_sa("ff01::123", "6881"); \
-+ auto c_sin6_bnd_6900 = wrap_ai_get_first_c_sa("ff01::123", "6900"); \
-+ auto c_sin6_bnd_6999 = wrap_ai_get_first_c_sa("ff01::123", "6999"); \
-+ auto c_sin6_v4_1_5000 = wrap_ai_get_first_c_sa("::ffff:1.2.3.4", "5000"); \
-+ auto c_sin6_1 = wrap_ai_get_first_c_sa("ff01::1"); \
-+ auto c_sin6_1_5000 = wrap_ai_get_first_c_sa("ff01::1", "5000"); \
-+ auto c_sin6_1_5005 = wrap_ai_get_first_c_sa("ff01::1", "5005"); \
-+ auto c_sin6_1_5010 = wrap_ai_get_first_c_sa("ff01::1", "5010"); \
-+ auto c_sin6_1_5100 = wrap_ai_get_first_c_sa("ff01::1", "5100"); \
-+ auto c_sin6_1_6881 = wrap_ai_get_first_c_sa("ff01::1", "6881"); \
-+ auto c_sin6_1_6900 = wrap_ai_get_first_c_sa("ff01::1", "6900"); \
-+ auto c_sin6_1_6999 = wrap_ai_get_first_c_sa("ff01::1", "6999"); \
-+ auto c_sin6_2 = wrap_ai_get_first_c_sa("ff02::2"); \
-+ auto c_sin6_2_5000 = wrap_ai_get_first_c_sa("ff02::2", "5000"); \
-+ auto c_sin6_2_5100 = wrap_ai_get_first_c_sa("ff02::2", "5100");
-+
-+inline bool
-+compare_sin6_addr(in6_addr lhs, in6_addr rhs) {
-+ return std::equal(lhs.s6_addr, lhs.s6_addr + 16, rhs.s6_addr);
-+}
-+
-+inline bool
-+compare_listen_result(const torrent::listen_result_type& lhs, int rhs_fd, const torrent::c_sa_unique_ptr& rhs_sap) {
-+ return lhs.fd == rhs_fd &&
-+ ((lhs.address && rhs_sap) || ((lhs.address && rhs_sap) && torrent::sap_equal(lhs.address, rhs_sap)));
-+}
-+
-+inline torrent::sa_unique_ptr
-+wrap_ai_get_first_sa(const char* nodename, const char* servname = nullptr, const addrinfo* hints = nullptr) {
-+ auto sa = torrent::ai_get_first_sa(nodename, servname, hints);
-+
-+ CPPUNIT_ASSERT_MESSAGE(("wrap_ai_get_first_sa: nodename:'" + std::string(nodename) + "'").c_str(),
-+ sa != nullptr);
-+ return sa;
-+}
-+
-+inline torrent::c_sa_unique_ptr
-+wrap_ai_get_first_c_sa(const char* nodename, const char* servname = nullptr, const addrinfo* hints = nullptr) {
-+ auto sa = torrent::ai_get_first_sa(nodename, servname, hints);
-+
-+ CPPUNIT_ASSERT_MESSAGE(("wrap_ai_get_first_sa: nodename:'" + std::string(nodename) + "'").c_str(),
-+ sa != nullptr);
-+ return torrent::c_sa_unique_ptr(sa.release());
-+}
-+
-+//
-+// Address info tests:
-+//
-+
-+typedef std::function<int (torrent::ai_unique_ptr&)> test_ai_ref;
-+
-+enum ai_flags_enum : int {
-+ aif_none = 0x0,
-+ aif_inet = 0x1,
-+ aif_inet6 = 0x2,
-+ aif_any = 0x4,
-+};
-+
-+constexpr ai_flags_enum operator | (ai_flags_enum a, ai_flags_enum b) {
-+ return static_cast<ai_flags_enum>(static_cast<int>(a) | static_cast<int>(b));
-+}
-+
-+template <ai_flags_enum ai_flags>
-+inline bool
-+test_valid_ai_ref(test_ai_ref ftor, uint16_t port = 0) {
-+ torrent::ai_unique_ptr ai;
-+
-+ if (int err = ftor(ai)) {
-+ std::cout << std::endl << "valid_ai_ref got error '" << gai_strerror(err) << "'" << std::endl;
-+ return false;
-+ }
-+
-+ if ((ai_flags & aif_inet) && !torrent::sa_is_inet(ai->ai_addr))
-+ return false;
-+
-+ if ((ai_flags & aif_inet6) && !torrent::sa_is_inet6(ai->ai_addr))
-+ return false;
-+
-+ if (!!(ai_flags & aif_any) == !torrent::sa_is_any(ai->ai_addr))
-+ return false;
-+
-+ if (torrent::sa_port(ai->ai_addr) != port)
-+ return false;
-+
-+ return true;
-+}
-+
-+inline bool
-+test_valid_ai_ref_err(test_ai_ref ftor, int expect_err) {
-+ torrent::ai_unique_ptr ai;
-+ int err = ftor(ai);
-+
-+ if (err != expect_err) {
-+ std::cout << std::endl << "ai_ref_err got wrong error, expected '" << gai_strerror(expect_err) << "', got '" << gai_strerror(err) << "'" << std::endl;
-+ return false;
-+ }
-+
-+ return true;
-+}
-+
-+#endif
-diff --git a/test/helpers/progress_listener.cc b/test/helpers/progress_listener.cc
-new file mode 100644
-index 00000000..02803ffc
---- /dev/null
-+++ b/test/helpers/progress_listener.cc
-@@ -0,0 +1,63 @@
-+#include "config.h"
-+
-+#include "progress_listener.h"
-+
-+#include <algorithm>
-+#include <iostream>
-+#include <iterator>
-+#include <numeric>
-+#include <stdexcept>
-+#include "torrent/utils/log.h"
-+#include "torrent/utils/log_buffer.h"
-+
-+static std::string
-+get_test_path(const test_list_type& tl) {
-+ if (tl.size() < 2)
-+ return "";
-+
-+ return std::accumulate(std::next(tl.begin()), std::prev(tl.end()), std::string(), [](std::string result, CppUnit::Test* test) {
-+ return std::move(result) + test->getName() + "::";
-+ });
-+}
-+
-+void
-+progress_listener::startTest(CppUnit::Test *test) {
-+ std::cout << get_test_path(m_test_path) << test->getName() << std::flush;
-+
-+ torrent::log_cleanup();
-+
-+ m_last_test_failed = false;
-+ m_current_log_buffer = torrent::log_open_log_buffer("test_output");
-+}
-+
-+void
-+progress_listener::addFailure(const CppUnit::TestFailure &failure) {
-+ // AddFailure is called for parent test suits, so only deal with leafs.
-+ if (m_current_log_buffer == nullptr)
-+ return;
-+
-+ std::cout << " : " << (failure.isError() ? "error" : "assertion");
-+
-+ m_last_test_failed = true;
-+ m_failures.push_back(std::move(failure_type{failure.failedTestName(), std::move(m_current_log_buffer)}));
-+}
-+
-+void
-+progress_listener::endTest(CppUnit::Test *test) {
-+ std::cout << (m_last_test_failed ? "" : " : OK") << std::endl;
-+
-+ m_current_log_buffer.reset();
-+ torrent::log_cleanup();
-+}
-+
-+void
-+progress_listener::startSuite(CppUnit::Test *suite) {
-+ m_test_path.push_back(suite);
-+
-+ std::cout << std::endl << get_test_path(m_test_path) << suite->getName() << ":" << std::endl;
-+}
-+
-+void
-+progress_listener::endSuite(CppUnit::Test *suite) {
-+ m_test_path.pop_back();
-+}
-diff --git a/test/helpers/progress_listener.h b/test/helpers/progress_listener.h
-new file mode 100644
-index 00000000..18fb8faa
---- /dev/null
-+++ b/test/helpers/progress_listener.h
-@@ -0,0 +1,47 @@
-+#include <memory>
-+#include <vector>
-+#include <cppunit/Test.h>
-+#include <cppunit/TestFailure.h>
-+#include <cppunit/TestListener.h>
-+
-+#include "torrent/utils/log_buffer.h"
-+
-+struct failure_type {
-+ std::string name;
-+ torrent::log_buffer_ptr log;
-+};
-+
-+typedef std::unique_ptr<CppUnit::TestFailure> test_failure_ptr;
-+typedef std::vector<CppUnit::Test*> test_list_type;
-+typedef std::vector<failure_type> failure_list_type;
-+
-+class progress_listener : public CppUnit::TestListener {
-+public:
-+ progress_listener() : m_last_test_failed(false) {}
-+
-+ void startTest(CppUnit::Test *test) override;
-+ void addFailure(const CppUnit::TestFailure &failure) override;
-+ void endTest(CppUnit::Test *test) override;
-+
-+ void startSuite(CppUnit::Test *suite) override;
-+ void endSuite(CppUnit::Test *suite) override;
-+
-+ //Called by a TestRunner before running the test.
-+ // void startTestRun(CppUnit::Test *test, CppUnit::TestResult *event_manager) override;
-+
-+ // Called by a TestRunner after running the test.
-+ // void endTestRun(CppUnit::Test *test, CppUnit::TestResult *event_manager) override;
-+
-+ const failure_list_type& failures() { return m_failures; }
-+ failure_list_type&& move_failures() { return std::move(m_failures); }
-+
-+private:
-+ progress_listener(const progress_listener& rhs) = delete;
-+ void operator =(const progress_listener& rhs) = delete;
-+
-+ test_list_type m_test_path;
-+ failure_list_type m_failures;
-+ bool m_last_test_failed;
-+
-+ torrent::log_buffer_ptr m_current_log_buffer;
-+};
-diff --git a/test/helpers/test_fixture.cc b/test/helpers/test_fixture.cc
-new file mode 100644
-index 00000000..4d8d7214
---- /dev/null
-+++ b/test/helpers/test_fixture.cc
-@@ -0,0 +1,18 @@
-+#include "config.h"
-+
-+#include "test_fixture.h"
-+
-+#include "torrent/utils/log.h"
-+
-+void
-+test_fixture::setUp() {
-+ mock_init();
-+
-+ log_add_group_output(torrent::LOG_CONNECTION_BIND, "test_output");
-+ log_add_group_output(torrent::LOG_CONNECTION_FD, "test_output");
-+}
-+
-+void
-+test_fixture::tearDown() {
-+ mock_cleanup();
-+}
-diff --git a/test/helpers/test_fixture.h b/test/helpers/test_fixture.h
-new file mode 100644
-index 00000000..312d5009
---- /dev/null
-+++ b/test/helpers/test_fixture.h
-@@ -0,0 +1,14 @@
-+#ifndef LIBTORRENT_HELPER_TEST_FIXTURE_H
-+#define LIBTORRENT_HELPER_TEST_FIXTURE_H
-+
-+#include <cppunit/extensions/HelperMacros.h>
-+
-+#include "helpers/mock_function.h"
-+
-+class test_fixture : public CppUnit::TestFixture {
-+public:
-+ void setUp();
-+ void tearDown();
-+};
-+
-+#endif
-diff --git a/test/helpers/utils.h b/test/helpers/utils.h
-new file mode 100644
-index 00000000..d18450c1
---- /dev/null
-+++ b/test/helpers/utils.h
-@@ -0,0 +1,60 @@
-+#ifndef LIBTORRENT_HELPER_UTILS_H
-+#define LIBTORRENT_HELPER_UTILS_H
-+
-+#include <algorithm>
-+#include <iostream>
-+#include <cppunit/extensions/TestFactoryRegistry.h>
-+#include <torrent/utils/log.h>
-+
-+static void
-+dump_failure_log(const failure_type& failure) {
-+ if (failure.log->empty())
-+ return;
-+
-+ std::cout << std::endl << failure.name << std::endl;
-+
-+ // Doesn't print dump messages as log_buffer drops them.
-+ std::for_each(failure.log->begin(), failure.log->end(), [](const torrent::log_entry& entry) {
-+ std::cout << entry.timestamp << ' ' << entry.message << '\n';
-+ });
-+
-+ std::cout << std::flush;
-+}
-+
-+static void
-+dump_failures(const failure_list_type& failures) {
-+ if (failures.empty())
-+ return;
-+
-+ std::cout << std::endl
-+ << "=================" << std::endl
-+ << "Failed Test Logs:" << std::endl
-+ << "=================" << std::endl;
-+
-+ std::for_each(failures.begin(), failures.end(), [](const failure_type& failure) {
-+ dump_failure_log(failure);
-+ });
-+ std::cout << std::endl;
-+}
-+
-+static
-+void add_tests(CppUnit::TextUi::TestRunner& runner, const char* c_test_names) {
-+ if (c_test_names == NULL || std::string(c_test_names).empty()) {
-+ runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
-+ return;
-+ }
-+
-+ const std::string& test_names(c_test_names);
-+
-+ size_t pos = 0;
-+ size_t next = 0;
-+
-+ while ((next = test_names.find(',', pos)) < test_names.size()) {
-+ runner.addTest(CppUnit::TestFactoryRegistry::getRegistry(test_names.substr(pos, next - pos)).makeTest());
-+ pos = next + 1;
-+ }
-+
-+ runner.addTest(CppUnit::TestFactoryRegistry::getRegistry(test_names.substr(pos)).makeTest());
-+}
-+
-+#endif
-diff --git a/test/main.cc b/test/main.cc
-index e69d3d70..da93fead 100644
---- a/test/main.cc
-+++ b/test/main.cc
-@@ -1,44 +1,92 @@
-+#include "config.h"
-+
-+#include <cstdlib>
- #include <stdexcept>
-+#include <signal.h>
-+#include <string.h>
- #include <cppunit/BriefTestProgressListener.h>
- #include <cppunit/CompilerOutputter.h>
- #include <cppunit/TestResult.h>
- #include <cppunit/TestResultCollector.h>
-+#include <cppunit/extensions/HelperMacros.h>
- #include <cppunit/extensions/TestFactoryRegistry.h>
- #include <cppunit/ui/text/TestRunner.h>
-
--int main(int argc, char* argv[])
--{
-+#ifdef USE_EXECINFO
-+#include <execinfo.h>
-+#endif
-+
-+#include "helpers/progress_listener.h"
-+#include "helpers/utils.h"
-+
-+CPPUNIT_REGISTRY_ADD_TO_DEFAULT("net");
-+CPPUNIT_REGISTRY_ADD_TO_DEFAULT("torrent/net");
-+CPPUNIT_REGISTRY_ADD_TO_DEFAULT("torrent/utils");
-+
-+void
-+do_test_panic(int signum) {
-+ signal(signum, SIG_DFL);
-+
-+ std::cout << std::endl << std::endl << "Caught " << strsignal(signum) << ", dumping stack:" << std::endl << std::endl;
-+
-+#ifdef USE_EXECINFO
-+ void* stackPtrs[20];
-+
-+ // Print the stack and exit.
-+ int stackSize = backtrace(stackPtrs, 20);
-+ char** stackStrings = backtrace_symbols(stackPtrs, stackSize);
-+
-+ for (int i = 0; i < stackSize; ++i)
-+ std::cout << stackStrings[i] << std::endl;
-+
-+#else
-+ std::cout << "Stack dump not enabled." << std::endl;
-+#endif
-+
-+ std::cout << std::endl;
-+ torrent::log_cleanup();
-+ std::abort();
-+}
-+
-+void
-+register_signal_handlers() {
-+ struct sigaction sa;
-+ sigemptyset(&sa.sa_mask);
-+ sa.sa_flags = SA_RESTART;
-+ sa.sa_handler = &do_test_panic;
-+
-+ if (sigaction(SIGSEGV, &sa, NULL) == -1) {
-+ std::cout << "Could not register signal handlers." << std::endl;
-+ exit(-1);
-+ }
-+}
-+
-+int main(int argc, char* argv[]) {
-+ register_signal_handlers();
-+
- CppUnit::TestResult controller;
- CppUnit::TestResultCollector result;
-- CppUnit::BriefTestProgressListener progressListener;
-+ progress_listener progress;
-
- controller.addListener( &result );
-- controller.addListener( &progressListener );
--
-- // Get the top level suite from the registry
-- CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest();
-+ controller.addListener( &progress );
-
-- // Adds the test to the list of test to run
- CppUnit::TextUi::TestRunner runner;
-- runner.addTest( suite );
-+ add_tests(runner, std::getenv("TEST_NAME"));
-
-- // Change the default outputter to a compiler error format outputter
-- runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(),
-- std::cerr ) );
- try {
- std::cout << "Running ";
- runner.run( controller );
-
-- std::cerr << std::endl;
--
-+ // TODO: Make outputter.
-+ dump_failures(progress.failures());
-+
- // Print test in a compiler compatible format.
- CppUnit::CompilerOutputter outputter( &result, std::cerr );
- outputter.write();
-
- } catch ( std::invalid_argument &e ) { // Test path not resolved
-- std::cerr << std::endl
-- << "ERROR: " << e.what()
-- << std::endl;
-+ std::cerr << std::endl << "ERROR: " << e.what() << std::endl;
- return 1;
- }
-
-diff --git a/test/net/test_socket_listen.cc b/test/net/test_socket_listen.cc
-new file mode 100644
-index 00000000..e86a078b
---- /dev/null
-+++ b/test/net/test_socket_listen.cc
-@@ -0,0 +1,398 @@
-+#include "config.h"
-+
-+#include "test_socket_listen.h"
-+
-+#include "helpers/expect_fd.h"
-+#include "helpers/expect_utils.h"
-+#include "helpers/mock_function.h"
-+#include "helpers/network.h"
-+
-+#include <net/socket_listen.h>
-+#include <torrent/exceptions.h>
-+#include <torrent/utils/log.h>
-+
-+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_socket_listen, "net");
-+
-+struct test_sl_deleter {
-+ void operator()(torrent::socket_listen* sl) const { if (!sl->is_open()) delete sl; }
-+};
-+
-+typedef std::unique_ptr<torrent::socket_listen, test_sl_deleter> test_sl_unique_ptr;
-+
-+#define TEST_SL_BEGIN(name) \
-+ test_sl_unique_ptr sl(new torrent::socket_listen); \
-+ std::vector<torrent::sa_unique_ptr> sap_cache; \
-+ lt_log_print(torrent::LOG_MOCK_CALLS, "sl_begin: %s", name); \
-+ TEST_DEFAULT_SA;
-+
-+#define TEST_SL_ASSERT_OPEN(_sap_bind, _sap_result, _flags) \
-+ TEST_SL_ASSERT_OPEN_PORT(_sap_bind, _sap_result, 5000, 5009, 5005, _flags); \
-+ CPPUNIT_ASSERT(sl->socket_address_port() == 5005);
-+
-+#define TEST_SL_ASSERT_OPEN_PORT(_sap_bind, _sap_result, _first_port, _last_port, _itr_port, _flags) \
-+ expect_event_open_re(0); \
-+ CPPUNIT_ASSERT(sl->open(_sap_bind, _first_port, _last_port, _itr_port, _flags)); \
-+ CPPUNIT_ASSERT(sl->is_open()); \
-+ CPPUNIT_ASSERT(torrent::sa_equal(sl->socket_address(), _sap_result.get()));
-+
-+#define TEST_SL_ASSERT_OPEN_SEQUENTIAL(_sap_bind, _sap_result, _first_port, _last_port, _flags) \
-+ expect_event_open_re(0); \
-+ CPPUNIT_ASSERT(sl->open_sequential(_sap_bind, _first_port, _last_port, _flags)); \
-+ CPPUNIT_ASSERT(sl->is_open()); \
-+ CPPUNIT_ASSERT(torrent::sa_equal(sl->socket_address(), _sap_result.get()));
-+
-+#define TEST_SL_ASSERT_OPEN_RANDOMIZE(_sap_bind, _sap_result, _first_port, _last_port, _flags) \
-+ expect_event_open_re(0); \
-+ CPPUNIT_ASSERT(sl->open_randomize(_sap_bind, _first_port, _last_port, _flags)); \
-+ CPPUNIT_ASSERT(sl->is_open()); \
-+ CPPUNIT_ASSERT(torrent::sa_equal(sl->socket_address(), _sap_result.get()));
-+
-+#define TEST_SL_ASSERT_CLOSED() \
-+ CPPUNIT_ASSERT(!sl->is_open()); \
-+ CPPUNIT_ASSERT(sl->file_descriptor() == -1); \
-+ CPPUNIT_ASSERT(sl->socket_address() == nullptr); \
-+ CPPUNIT_ASSERT(sl->socket_address_port() == 0);
-+
-+#define TEST_SL_CLOSE(_fd) \
-+ mock_expect(&torrent::fd__close, 0, _fd); \
-+ mock_expect(&torrent::poll_event_closed, (torrent::Event*)sl.get()); \
-+ CPPUNIT_ASSERT_NO_THROW(sl->close()); \
-+ TEST_SL_ASSERT_CLOSED();
-+
-+#define TEST_SL_MOCK_CLOSED_PORT_RANGE(_src_sap, _first_port, _last_port) \
-+ { uint16_t _port = _first_port; do { \
-+ sap_cache.push_back(torrent::sap_copy(_src_sap)); \
-+ torrent::sap_set_port(sap_cache.back(), _port); \
-+ mock_expect(&torrent::fd__bind, -1, 1000, \
-+ (const sockaddr*)sap_cache.back().get(), \
-+ (socklen_t)torrent::sap_length(sap_cache.back())); \
-+ } while (_port++ != _last_port); \
-+ }
-+
-+void
-+test_socket_listen::test_basic() {
-+ TEST_SL_BEGIN("basic");
-+ TEST_SL_ASSERT_CLOSED();
-+ CPPUNIT_ASSERT(sl->backlog() == SOMAXCONN);
-+ CPPUNIT_ASSERT(sl->type_name() == std::string("socket_listen"));
-+}
-+
-+void
-+test_socket_listen::test_open_error() {
-+ { TEST_SL_BEGIN("open twice");
-+ expect_fd_inet6_tcp_nonblock(1000);
-+ expect_fd_bind_listen(1000, c_sin6_any_5005);
-+ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin6_any), c_sin6_any_5005, torrent::fd_flag_stream | torrent::fd_flag_nonblock);
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 5000, 5009, 5005, torrent::fd_flag_stream),
-+ torrent::internal_error);
-+ TEST_SL_CLOSE(1000);
-+ };
-+ { TEST_SL_BEGIN("sin_any, stream, no v4only");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin_any), 5000, 5009, 5005, torrent::fd_flag_stream),
-+ torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+}
-+
-+void
-+test_socket_listen::test_open_sap() {
-+ { TEST_SL_BEGIN("sin6_any, stream");
-+ expect_fd_inet6_tcp(1000);
-+ expect_fd_bind_listen(1000, c_sin6_any_5005);
-+ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin6_any), c_sin6_any_5005, torrent::fd_flag_stream);
-+ TEST_SL_CLOSE(1000);
-+ };
-+ { TEST_SL_BEGIN("sin_any, stream|v4only");
-+ expect_fd_inet_tcp(1000);
-+ expect_fd_bind_listen(1000, c_sin_any_5005);
-+ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin_any), c_sin_any_5005, torrent::fd_flag_stream | torrent::fd_flag_v4only);
-+ TEST_SL_CLOSE(1000);
-+ };
-+ { TEST_SL_BEGIN("sin_1, stream|v4only");
-+ expect_fd_inet_tcp(1000);
-+ expect_fd_bind_listen(1000, c_sin_1_5005);
-+ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin_1), c_sin_1_5005, torrent::fd_flag_stream | torrent::fd_flag_v4only);
-+ TEST_SL_CLOSE(1000);
-+ };
-+ { TEST_SL_BEGIN("sin6_any, stream|v6only");
-+ expect_fd_inet6_tcp(1000);
-+ mock_expect(&torrent::fd__setsockopt_int, 0, 1000, (int)IPPROTO_IPV6, (int)IPV6_V6ONLY, (int)true);
-+ expect_fd_bind_listen(1000, c_sin6_any_5005);
-+ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin6_any), c_sin6_any_5005, torrent::fd_flag_stream | torrent::fd_flag_v6only);
-+ TEST_SL_CLOSE(1000);
-+ };
-+ { TEST_SL_BEGIN("sin6_1, stream|v6only");
-+ expect_fd_inet6_tcp(1000);
-+ mock_expect(&torrent::fd__setsockopt_int, 0, 1000, (int)IPPROTO_IPV6, (int)IPV6_V6ONLY, (int)true);
-+ expect_fd_bind_listen(1000, c_sin6_1_5005);
-+ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin6_1), c_sin6_1_5005, torrent::fd_flag_stream | torrent::fd_flag_v6only);
-+ TEST_SL_CLOSE(1000);
-+ };
-+}
-+
-+void
-+test_socket_listen::test_open_sap_error() {
-+ { TEST_SL_BEGIN("unspec");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sa_make_unspec(), 5000, 5009, 5005, torrent::fd_flag_stream), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+ { TEST_SL_BEGIN("unix");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sa_make_unix("test"), 5000, 5009, 5005, torrent::fd_flag_stream), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+ { TEST_SL_BEGIN("sin_any_5005");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin_any_5005), 5000, 5009, 5005, torrent::fd_flag_stream | torrent::fd_flag_v4only), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+ { TEST_SL_BEGIN("sin6_any_5005");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any_5005), 5000, 5009, 5005, torrent::fd_flag_stream), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+ { TEST_SL_BEGIN("sin_any");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_to_v4mapped(sin_any), 5000, 5009, 5005, torrent::fd_flag_stream | torrent::fd_flag_v4only), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+ { TEST_SL_BEGIN("sin_1, v4mapped");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_to_v4mapped(sin_1), 5000, 5009, 5005, torrent::fd_flag_stream | torrent::fd_flag_v4only), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+ { TEST_SL_BEGIN("sin_broadcast");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin_bc), 5000, 5009, 5005, torrent::fd_flag_stream | torrent::fd_flag_v4only), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+}
-+
-+void
-+test_socket_listen::test_open_flags() {
-+ { TEST_SL_BEGIN("sin_any, stream|v4only|nonblock");
-+ expect_fd_inet_tcp_nonblock(1000);
-+ expect_fd_bind_listen(1000, c_sin_any_5005);
-+ TEST_SL_ASSERT_OPEN(torrent::sap_copy_addr(sin_any), c_sin_any_5005, torrent::fd_flag_stream | torrent::fd_flag_v4only | torrent::fd_flag_nonblock);
-+ TEST_SL_CLOSE(1000);
-+ };
-+ { TEST_SL_BEGIN("sin6_any, stream|nonblock");
-+ expect_fd_inet6_tcp_nonblock(1000);
-+ expect_fd_bind_listen(1000, c_sin6_any_5005);
-+ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin6_any), c_sin6_any_5005, torrent::fd_flag_stream | torrent::fd_flag_nonblock);
-+ TEST_SL_CLOSE(1000);
-+ };
-+ { TEST_SL_BEGIN("sin_any, stream|v4only|reuse_address");
-+ expect_fd_inet_tcp(1000);
-+ mock_expect(&torrent::fd__setsockopt_int, 0, 1000, (int)SOL_SOCKET, (int)SO_REUSEADDR, (int)true);
-+ expect_fd_bind_listen(1000, c_sin_any_5005);
-+ TEST_SL_ASSERT_OPEN(torrent::sap_copy_addr(sin_any), c_sin_any_5005, torrent::fd_flag_stream | torrent::fd_flag_v4only | torrent::fd_flag_reuse_address);
-+ TEST_SL_CLOSE(1000);
-+ };
-+ { TEST_SL_BEGIN("sin6_any, stream|reuse_address");
-+ expect_fd_inet6_tcp(1000);
-+ mock_expect(&torrent::fd__setsockopt_int, 0, 1000, (int)SOL_SOCKET, (int)SO_REUSEADDR, (int)true);
-+ expect_fd_bind_listen(1000, c_sin6_any_5005);
-+ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin6_any), c_sin6_any_5005, torrent::fd_flag_stream | torrent::fd_flag_reuse_address);
-+ TEST_SL_CLOSE(1000);
-+ };
-+ { TEST_SL_BEGIN("sin_any, stream|v4only|nonblock|reuse_address");
-+ expect_fd_inet_tcp_nonblock(1000);
-+ mock_expect(&torrent::fd__setsockopt_int, 0, 1000, (int)SOL_SOCKET, (int)SO_REUSEADDR, (int)true);
-+ expect_fd_bind_listen(1000, c_sin_any_5005);
-+ TEST_SL_ASSERT_OPEN(torrent::sap_copy_addr(sin_any), c_sin_any_5005, torrent::fd_flag_stream | torrent::fd_flag_v4only | torrent::fd_flag_nonblock | torrent::fd_flag_reuse_address);
-+ TEST_SL_CLOSE(1000);
-+ };
-+ { TEST_SL_BEGIN("sin6_any, stream|nonblock|reuse_address");
-+ expect_fd_inet6_tcp_nonblock_reuseaddr(1000);
-+ expect_fd_bind_listen(1000, c_sin6_any_5005);
-+ TEST_SL_ASSERT_OPEN(torrent::sap_copy(sin6_any), c_sin6_any_5005, torrent::fd_flag_stream | torrent::fd_flag_nonblock | torrent::fd_flag_reuse_address);
-+ TEST_SL_CLOSE(1000);
-+ };
-+}
-+
-+void
-+test_socket_listen::test_open_flags_error() {
-+ { TEST_SL_BEGIN("sin6_any, fd_flags(0)");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 5000, 5009, 5005, torrent::fd_flags(0)), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+ { TEST_SL_BEGIN("sin6_any, fd_flags(0xffff)");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 5000, 5009, 5005, torrent::fd_flags(0xffff)), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+}
-+
-+void
-+test_socket_listen::test_open_port_single() {
-+ { TEST_SL_BEGIN("sin6_any, stream");
-+ expect_fd_inet6_tcp(1000);
-+ expect_fd_bind_listen(1000, c_sin6_any_5000);
-+ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5000, 5000, 5000, 5000, torrent::fd_flag_stream);
-+ TEST_SL_CLOSE(1000);
-+ };
-+ { TEST_SL_BEGIN("sin_any, stream");
-+ expect_fd_inet_tcp(1000);
-+ expect_fd_bind_listen(1000, c_sin_any_5000);
-+ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin_any), c_sin_any_5000, 5000, 5000, 5000, torrent::fd_flag_stream | torrent::fd_flag_v4only);
-+ TEST_SL_CLOSE(1000);
-+ };
-+}
-+
-+void
-+test_socket_listen::test_open_port_single_error() {
-+ { TEST_SL_BEGIN("sin6_any, 0, 0, 0");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 0, 0, 0, torrent::fd_flag_stream), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+ { TEST_SL_BEGIN("sin6_any, 1000, 0, 0");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 1000, 0, 0, torrent::fd_flag_stream), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+ { TEST_SL_BEGIN("sin6_any, 0, 1000, 0");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 0, 1000, 0, torrent::fd_flag_stream), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+ { TEST_SL_BEGIN("sin6_any, 0, 0, 500");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 0, 0, 500, torrent::fd_flag_stream), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+ { TEST_SL_BEGIN("sin6_any, 0, 1000, 500");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 0, 1000, 500, torrent::fd_flag_stream), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+}
-+
-+void
-+test_socket_listen::test_open_port_range() {
-+ { TEST_SL_BEGIN("sin6_any, stream, first");
-+ expect_fd_inet6_tcp(1000);
-+ expect_fd_bind_listen(1000, c_sin6_any_5000);
-+ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5000, 5000, 5010, 5000, torrent::fd_flag_stream);
-+ TEST_SL_CLOSE(1000);
-+ };
-+ { TEST_SL_BEGIN("sin6_any, stream, from first to middle port");
-+ expect_fd_inet6_tcp(1000);
-+ TEST_SL_MOCK_CLOSED_PORT_RANGE(sin6_any, 5000, 5004);
-+ expect_fd_bind_listen(1000, c_sin6_any_5005);
-+ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5005, 5000, 5010, 5000, torrent::fd_flag_stream);
-+ TEST_SL_CLOSE(1000);
-+ };
-+ { TEST_SL_BEGIN("sin6_any, stream, from first to last port");
-+ expect_fd_inet6_tcp(1000);
-+ TEST_SL_MOCK_CLOSED_PORT_RANGE(sin6_any, 5000, 5009);
-+ expect_fd_bind_listen(1000, c_sin6_any_5010);
-+ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5010, 5000, 5010, 5000, torrent::fd_flag_stream);
-+ TEST_SL_CLOSE(1000);
-+ };
-+ { TEST_SL_BEGIN("sin6_any, stream, middle");
-+ expect_fd_inet6_tcp(1000);
-+ expect_fd_bind_listen(1000, c_sin6_any_5005);
-+ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5005, 5000, 5010, 5005, torrent::fd_flag_stream);
-+ TEST_SL_CLOSE(1000);
-+ };
-+ { TEST_SL_BEGIN("sin6_any, stream, from middle to last port");
-+ expect_fd_inet6_tcp(1000);
-+ TEST_SL_MOCK_CLOSED_PORT_RANGE(sin6_any, 5005, 5009);
-+ expect_fd_bind_listen(1000, c_sin6_any_5010);
-+ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5010, 5000, 5010, 5005, torrent::fd_flag_stream);
-+ TEST_SL_CLOSE(1000);
-+ };
-+ { TEST_SL_BEGIN("sin6_any, stream, last");
-+ expect_fd_inet6_tcp(1000);
-+ expect_fd_bind_listen(1000, c_sin6_any_5010);
-+ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5010, 5000, 5010, 5010, torrent::fd_flag_stream);
-+ TEST_SL_CLOSE(1000);
-+ };
-+ { TEST_SL_BEGIN("sin6_any, stream, from last to first port");
-+ expect_fd_inet6_tcp(1000);
-+ TEST_SL_MOCK_CLOSED_PORT_RANGE(sin6_any, 5010, 5010);
-+ expect_fd_bind_listen(1000, c_sin6_any_5000);
-+ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5000, 5000, 5010, 5010, torrent::fd_flag_stream);
-+ TEST_SL_CLOSE(1000);
-+ };
-+ { TEST_SL_BEGIN("sin6_any, stream, from last to middle port");
-+ expect_fd_inet6_tcp(1000);
-+ TEST_SL_MOCK_CLOSED_PORT_RANGE(sin6_any, 5010, 5010);
-+ TEST_SL_MOCK_CLOSED_PORT_RANGE(sin6_any, 5000, 5004);
-+ expect_fd_bind_listen(1000, c_sin6_any_5005);
-+ TEST_SL_ASSERT_OPEN_PORT(torrent::sap_copy(sin6_any), c_sin6_any_5005, 5000, 5010, 5010, torrent::fd_flag_stream);
-+ TEST_SL_CLOSE(1000);
-+ };
-+}
-+
-+void
-+test_socket_listen::test_open_port_range_error() {
-+ { TEST_SL_BEGIN("sin6_any, first > last");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 5000, 4999, 5000, torrent::fd_flag_stream), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+ { TEST_SL_BEGIN("sin6_any, first > itr");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 5001, 5009, 5000, torrent::fd_flag_stream), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+ { TEST_SL_BEGIN("sin6_any, itr > last");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 5000, 5009, 5010, torrent::fd_flag_stream), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+ { TEST_SL_BEGIN("sin6_any, min first > last");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 2, 1, 2, torrent::fd_flag_stream), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+ { TEST_SL_BEGIN("sin6_any, min first > itr");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 2, 1000, 1, torrent::fd_flag_stream), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+ { TEST_SL_BEGIN("sin6_any, min itr > last");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 1, 2, 3, torrent::fd_flag_stream), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+ { TEST_SL_BEGIN("sin6_any, max first > last");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 0xffff, 0xfffe, 0xffff, torrent::fd_flag_stream), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+ { TEST_SL_BEGIN("sin6_any, max first > itr");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 0xffff, 0xffff, 0xfffe, torrent::fd_flag_stream), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+ { TEST_SL_BEGIN("sin6_any, max itr > last");
-+ CPPUNIT_ASSERT_THROW(sl->open(torrent::sap_copy(sin6_any), 0xfffe, 0xfffe, 0xffff, torrent::fd_flag_stream), torrent::internal_error);
-+ TEST_SL_ASSERT_CLOSED();
-+ };
-+}
-+
-+void
-+test_socket_listen::test_open_sequential() {
-+ { TEST_SL_BEGIN("sin6_any, stream");
-+ expect_fd_inet6_tcp(1000);
-+ expect_fd_bind_listen(1000, c_sin6_any_5000);
-+ TEST_SL_ASSERT_OPEN_SEQUENTIAL(torrent::sap_copy(sin6_any), c_sin6_any_5000, 5000, 5010, torrent::fd_flag_stream);
-+ TEST_SL_CLOSE(1000);
-+ };
-+}
-+
-+void
-+test_socket_listen::test_open_randomize() {
-+ { TEST_SL_BEGIN("sin6_any, stream");
-+ expect_random_uniform_uint16(5005, 5000, 5010);
-+ expect_fd_inet6_tcp(1000);
-+ expect_fd_bind_listen(1000, c_sin6_any_5005);
-+ TEST_SL_ASSERT_OPEN_RANDOMIZE(torrent::sap_copy(sin6_any), c_sin6_any_5005, 5000, 5010, torrent::fd_flag_stream);
-+ TEST_SL_CLOSE(1000);
-+ };
-+}
-+
-+// deal with reuse error
-+
-+void
-+test_socket_listen::test_accept() {
-+ { TEST_SL_BEGIN("sin6_any, stream");
-+ expect_fd_inet6_tcp(1000);
-+ expect_fd_bind_listen(1000, c_sin6_any_5000);
-+ TEST_SL_ASSERT_OPEN_SEQUENTIAL(torrent::sap_copy(sin6_any), c_sin6_any_5000, 5000, 5010, torrent::fd_flag_stream);
-+
-+ std::vector<torrent::fd_sap_tuple> accepted_connections;
-+
-+ sl->set_slot_accepted([&accepted_connections](int accept_fd, torrent::sa_unique_ptr sap) {
-+ accepted_connections.push_back(torrent::fd_sap_tuple{accept_fd, std::move(sap)});
-+ });
-+
-+ // CPPUNIT_ASSERT(accepted_connections.size() > 0 && torrent::fd_sap_equal(accepted_connections[0], torrent::fd_sap_tuple{2000, torrent::sap_copy(sin6_1_5100)}));
-+
-+ TEST_SL_CLOSE(1000);
-+ };
-+}
-diff --git a/test/net/test_socket_listen.h b/test/net/test_socket_listen.h
-new file mode 100644
-index 00000000..5d06f7f3
---- /dev/null
-+++ b/test/net/test_socket_listen.h
-@@ -0,0 +1,44 @@
-+#include "helpers/test_fixture.h"
-+
-+class test_socket_listen : public test_fixture {
-+ CPPUNIT_TEST_SUITE(test_socket_listen);
-+
-+ CPPUNIT_TEST(test_basic);
-+
-+ CPPUNIT_TEST(test_open_error);
-+ CPPUNIT_TEST(test_open_sap);
-+ CPPUNIT_TEST(test_open_sap_error);
-+ CPPUNIT_TEST(test_open_flags);
-+ CPPUNIT_TEST(test_open_flags_error);
-+
-+ CPPUNIT_TEST(test_open_port_single);
-+ CPPUNIT_TEST(test_open_port_single_error);
-+ CPPUNIT_TEST(test_open_port_range);
-+ CPPUNIT_TEST(test_open_port_range_error);
-+
-+ CPPUNIT_TEST(test_open_sequential);
-+ CPPUNIT_TEST(test_open_randomize);
-+
-+ CPPUNIT_TEST(test_accept);
-+
-+ CPPUNIT_TEST_SUITE_END();
-+
-+public:
-+ void test_basic();
-+
-+ void test_open_error();
-+ void test_open_sap();
-+ void test_open_sap_error();
-+ void test_open_flags();
-+ void test_open_flags_error();
-+
-+ void test_open_port_single();
-+ void test_open_port_single_error();
-+ void test_open_port_range();
-+ void test_open_port_range_error();
-+
-+ void test_open_sequential();
-+ void test_open_randomize();
-+
-+ void test_accept();
-+};
-diff --git a/test/torrent/net/test_address_info.cc b/test/torrent/net/test_address_info.cc
-new file mode 100644
-index 00000000..e3ee24d1
---- /dev/null
-+++ b/test/torrent/net/test_address_info.cc
-@@ -0,0 +1,62 @@
-+#include "config.h"
-+
-+#include "test_address_info.h"
-+
-+#include "helpers/network.h"
-+#include "torrent/net/address_info.h"
-+#include "torrent/net/socket_address.h"
-+
-+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_address_info, "torrent/net");
-+
-+void
-+test_address_info::test_basic() {
-+ CPPUNIT_ASSERT(test_valid_ai_ref<aif_inet|aif_any> (std::bind(torrent::ai_get_addrinfo, "0.0.0.0", nullptr, nullptr, std::placeholders::_1)));
-+ CPPUNIT_ASSERT(test_valid_ai_ref<aif_inet6|aif_any>(std::bind(torrent::ai_get_addrinfo, "::", nullptr, nullptr, std::placeholders::_1)));
-+
-+ CPPUNIT_ASSERT(test_valid_ai_ref<aif_inet> (std::bind(torrent::ai_get_addrinfo, "1.1.1.1", nullptr, nullptr, std::placeholders::_1)));
-+ CPPUNIT_ASSERT(test_valid_ai_ref<aif_inet6>(std::bind(torrent::ai_get_addrinfo, "ff01::1", nullptr, nullptr, std::placeholders::_1)));
-+ CPPUNIT_ASSERT(test_valid_ai_ref<aif_inet6>(std::bind(torrent::ai_get_addrinfo, "2001:0db8:85a3:0000:0000:8a2e:0370:7334", nullptr, nullptr, std::placeholders::_1)));
-+
-+ CPPUNIT_ASSERT(test_valid_ai_ref<aif_inet> (std::bind(torrent::ai_get_addrinfo, "1.1.1.1", "22123", nullptr, std::placeholders::_1), 22123));
-+ CPPUNIT_ASSERT(test_valid_ai_ref<aif_inet6>(std::bind(torrent::ai_get_addrinfo, "2001:db8:a::", "22123", nullptr, std::placeholders::_1), 22123));
-+
-+ CPPUNIT_ASSERT(test_valid_ai_ref<aif_none> (std::bind(torrent::ai_get_addrinfo, "localhost", nullptr, nullptr, std::placeholders::_1)));
-+
-+ CPPUNIT_ASSERT(test_valid_ai_ref_err(std::bind(torrent::ai_get_addrinfo, "1.1.1.300", nullptr, nullptr, std::placeholders::_1), EAI_NONAME));
-+ CPPUNIT_ASSERT(test_valid_ai_ref_err(std::bind(torrent::ai_get_addrinfo, "2001:db8:a::22123", nullptr, nullptr, std::placeholders::_1), EAI_NONAME));
-+}
-+
-+void
-+test_address_info::test_numericserv() {
-+ CPPUNIT_ASSERT(test_valid_ai_ref<aif_inet> (std::bind(torrent::ai_get_addrinfo, "1.1.1.1", nullptr, torrent::ai_make_hint(AI_NUMERICHOST, 0, 0).get(), std::placeholders::_1)));
-+
-+ CPPUNIT_ASSERT(test_valid_ai_ref_err(std::bind(torrent::ai_get_addrinfo, "localhost", nullptr, torrent::ai_make_hint(AI_NUMERICHOST, 0, 0).get(), std::placeholders::_1), EAI_NONAME));
-+}
-+
-+void
-+test_address_info::test_helpers() {
-+ torrent::sin_unique_ptr sin_zero = torrent::sin_from_sa(wrap_ai_get_first_sa("0.0.0.0"));
-+ CPPUNIT_ASSERT(sin_zero != nullptr);
-+ CPPUNIT_ASSERT(sin_zero->sin_family == AF_INET);
-+ CPPUNIT_ASSERT(sin_zero->sin_port == 0);
-+ CPPUNIT_ASSERT(sin_zero->sin_addr.s_addr == in_addr().s_addr);
-+
-+ torrent::sin_unique_ptr sin_1 = torrent::sin_from_sa(wrap_ai_get_first_sa("1.2.3.4"));
-+ CPPUNIT_ASSERT(sin_1 != nullptr);
-+ CPPUNIT_ASSERT(sin_1->sin_family == AF_INET);
-+ CPPUNIT_ASSERT(sin_1->sin_port == 0);
-+ CPPUNIT_ASSERT(sin_1->sin_addr.s_addr == htonl(0x01020304));
-+
-+ torrent::sin6_unique_ptr sin6_zero = torrent::sin6_from_sa(wrap_ai_get_first_sa("::"));
-+ CPPUNIT_ASSERT(sin6_zero != nullptr);
-+ CPPUNIT_ASSERT(sin6_zero->sin6_family == AF_INET6);
-+ CPPUNIT_ASSERT(sin6_zero->sin6_port == 0);
-+ CPPUNIT_ASSERT(compare_sin6_addr(sin6_zero->sin6_addr, in6_addr{0}));
-+
-+ torrent::sin6_unique_ptr sin6_1 = torrent::sin6_from_sa(wrap_ai_get_first_sa("ff01::1"));
-+ CPPUNIT_ASSERT(sin6_1 != nullptr);
-+ CPPUNIT_ASSERT(sin6_1->sin6_family == AF_INET6);
-+ CPPUNIT_ASSERT(sin6_1->sin6_port == 0);
-+ CPPUNIT_ASSERT(compare_sin6_addr(sin6_1->sin6_addr, in6_addr{0xff, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}));
-+ CPPUNIT_ASSERT(!compare_sin6_addr(sin6_1->sin6_addr, in6_addr{0xff, 0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2}));
-+}
-diff --git a/test/torrent/net/test_address_info.h b/test/torrent/net/test_address_info.h
-new file mode 100644
-index 00000000..c2ce9188
---- /dev/null
-+++ b/test/torrent/net/test_address_info.h
-@@ -0,0 +1,19 @@
-+#include <cppunit/extensions/HelperMacros.h>
-+
-+class test_address_info : public CppUnit::TestFixture {
-+ CPPUNIT_TEST_SUITE(test_address_info);
-+
-+ CPPUNIT_TEST(test_basic);
-+ CPPUNIT_TEST(test_numericserv);
-+ CPPUNIT_TEST(test_helpers);
-+
-+ CPPUNIT_TEST_SUITE_END();
-+
-+public:
-+ void setUp() {}
-+ void tearDown() {}
-+
-+ void test_basic();
-+ void test_numericserv();
-+ void test_helpers();
-+};
-diff --git a/test/torrent/net/test_fd.cc b/test/torrent/net/test_fd.cc
-new file mode 100644
-index 00000000..3cab0c5e
---- /dev/null
-+++ b/test/torrent/net/test_fd.cc
-@@ -0,0 +1,24 @@
-+#include "config.h"
-+
-+#include "test_fd.h"
-+
-+#include <torrent/net/fd.h>
-+
-+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_fd, "torrent/net");
-+
-+void
-+test_fd::test_valid_flags() {
-+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream));
-+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_nonblock));
-+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_reuse_address));
-+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only));
-+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v6only));
-+
-+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_v4only | torrent::fd_flag_v6only));
-+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only | torrent::fd_flag_v6only));
-+
-+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags()));
-+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(~torrent::fd_flag_all)));
-+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(torrent::fd_flag_stream | ~torrent::fd_flag_all)));
-+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(0x3245132)));
-+}
-diff --git a/test/torrent/net/test_fd.h b/test/torrent/net/test_fd.h
-new file mode 100644
-index 00000000..6ba718fc
---- /dev/null
-+++ b/test/torrent/net/test_fd.h
-@@ -0,0 +1,12 @@
-+#include "helpers/test_fixture.h"
-+
-+class test_fd : public test_fixture {
-+ CPPUNIT_TEST_SUITE(test_fd);
-+
-+ CPPUNIT_TEST(test_valid_flags);
-+
-+ CPPUNIT_TEST_SUITE_END();
-+
-+public:
-+ void test_valid_flags();
-+};
-diff --git a/test/torrent/net/test_socket_address.cc b/test/torrent/net/test_socket_address.cc
-new file mode 100644
-index 00000000..8a1b0c8a
---- /dev/null
-+++ b/test/torrent/net/test_socket_address.cc
-@@ -0,0 +1,383 @@
-+#include "config.h"
-+
-+#include "test_socket_address.h"
-+
-+#include "helpers/network.h"
-+#include "torrent/exceptions.h"
-+#include "torrent/net/socket_address.h"
-+
-+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_socket_address, "torrent/net");
-+
-+void
-+test_socket_address::test_sa_is_any() {
-+ TEST_DEFAULT_SA;
-+
-+ CPPUNIT_ASSERT(torrent::sap_is_any(sin_any));
-+ CPPUNIT_ASSERT(torrent::sap_is_any(sin_any_5000));
-+ CPPUNIT_ASSERT(torrent::sap_is_any(sin6_v4_any));
-+ CPPUNIT_ASSERT(torrent::sap_is_any(sin6_v4_any_5000));
-+
-+ CPPUNIT_ASSERT(!torrent::sap_is_any(sin_bc));
-+ CPPUNIT_ASSERT(!torrent::sap_is_any(sin_1));
-+ CPPUNIT_ASSERT(!torrent::sap_is_any(sin6_1));
-+ CPPUNIT_ASSERT(!torrent::sap_is_any(sin_bc_5000));
-+ CPPUNIT_ASSERT(!torrent::sap_is_any(sin_1_5000));
-+ CPPUNIT_ASSERT(!torrent::sap_is_any(sin6_1_5000));
-+
-+ CPPUNIT_ASSERT(!torrent::sap_is_any(c_sin_bc));
-+ CPPUNIT_ASSERT(!torrent::sap_is_any(c_sin_1));
-+ CPPUNIT_ASSERT(!torrent::sap_is_any(c_sin6_1));
-+ CPPUNIT_ASSERT(!torrent::sap_is_any(c_sin_bc_5000));
-+ CPPUNIT_ASSERT(!torrent::sap_is_any(c_sin_1_5000));
-+ CPPUNIT_ASSERT(!torrent::sap_is_any(c_sin6_1_5000));
-+}
-+
-+void
-+test_socket_address::test_sa_is_broadcast() {
-+ TEST_DEFAULT_SA;
-+
-+ CPPUNIT_ASSERT(torrent::sap_is_broadcast(sin_bc));
-+ CPPUNIT_ASSERT(torrent::sap_is_broadcast(sin_bc_5000));
-+ CPPUNIT_ASSERT(torrent::sap_is_broadcast(sin6_v4_bc));
-+ CPPUNIT_ASSERT(torrent::sap_is_broadcast(sin6_v4_bc_5000));
-+
-+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin_any));
-+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin_1));
-+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin6_any));
-+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin6_1));
-+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin_any_5000));
-+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin_1_5000));
-+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin6_any_5000));
-+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(sin6_1_5000));
-+
-+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin_any));
-+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin_1));
-+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin6_any));
-+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin6_1));
-+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin_any_5000));
-+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin_1_5000));
-+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin6_any_5000));
-+ CPPUNIT_ASSERT(!torrent::sap_is_broadcast(c_sin6_1_5000));
-+}
-+
-+void
-+test_socket_address::test_make() {
-+ torrent::sa_unique_ptr sa_unspec = torrent::sa_make_unspec();
-+ CPPUNIT_ASSERT(sa_unspec != nullptr);
-+ CPPUNIT_ASSERT(sa_unspec->sa_family == AF_UNSPEC);
-+
-+ torrent::sa_unique_ptr sa_inet = torrent::sa_make_inet();
-+ CPPUNIT_ASSERT(sa_inet != nullptr);
-+ CPPUNIT_ASSERT(sa_inet->sa_family == AF_INET);
-+
-+ sockaddr_in* sin_inet = reinterpret_cast<sockaddr_in*>(sa_inet.get());
-+ CPPUNIT_ASSERT(sin_inet->sin_family == AF_INET);
-+ CPPUNIT_ASSERT(sin_inet->sin_port == 0);
-+ CPPUNIT_ASSERT(sin_inet->sin_addr.s_addr == in_addr().s_addr);
-+
-+ torrent::sa_unique_ptr sa_inet6 = torrent::sa_make_inet6();
-+ CPPUNIT_ASSERT(sa_inet6 != nullptr);
-+ CPPUNIT_ASSERT(sa_inet6->sa_family == AF_INET6);
-+
-+ sockaddr_in6* sin6_inet6 = reinterpret_cast<sockaddr_in6*>(sa_inet6.get());
-+ CPPUNIT_ASSERT(sin6_inet6->sin6_family == AF_INET6);
-+ CPPUNIT_ASSERT(sin6_inet6->sin6_port == 0);
-+ CPPUNIT_ASSERT(sin6_inet6->sin6_flowinfo == 0);
-+ CPPUNIT_ASSERT(compare_sin6_addr(sin6_inet6->sin6_addr, in6_addr{0}));
-+ CPPUNIT_ASSERT(sin6_inet6->sin6_scope_id == 0);
-+
-+ torrent::sa_unique_ptr sa_unix = torrent::sa_make_unix("");
-+ CPPUNIT_ASSERT(sa_unix != nullptr);
-+ CPPUNIT_ASSERT(sa_unix->sa_family == AF_UNIX);
-+}
-+
-+void
-+test_socket_address::test_sin_from_sa() {
-+ torrent::sa_unique_ptr sa_zero = wrap_ai_get_first_sa("0.0.0.0");
-+ torrent::sin_unique_ptr sin_zero;
-+
-+ CPPUNIT_ASSERT(sa_zero != nullptr);
-+ CPPUNIT_ASSERT_NO_THROW({ sin_zero = torrent::sin_from_sa(std::move(sa_zero)); });
-+ CPPUNIT_ASSERT(sa_zero == nullptr);
-+ CPPUNIT_ASSERT(sin_zero != nullptr);
-+
-+ CPPUNIT_ASSERT(sin_zero->sin_addr.s_addr == htonl(0x0));
-+
-+ torrent::sa_unique_ptr sa_inet = wrap_ai_get_first_sa("1.2.3.4");
-+ torrent::sin_unique_ptr sin_inet;
-+
-+ CPPUNIT_ASSERT(sa_inet != nullptr);
-+ CPPUNIT_ASSERT_NO_THROW({ sin_inet = torrent::sin_from_sa(std::move(sa_inet)); });
-+ CPPUNIT_ASSERT(sa_inet == nullptr);
-+ CPPUNIT_ASSERT(sin_inet != nullptr);
-+
-+ CPPUNIT_ASSERT(sin_inet->sin_addr.s_addr == htonl(0x01020304));
-+
-+ CPPUNIT_ASSERT_THROW(torrent::sin_from_sa(torrent::sa_unique_ptr()), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sin_from_sa(torrent::sa_make_unspec()), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sin_from_sa(torrent::sa_make_inet6()), torrent::internal_error);
-+}
-+
-+void
-+test_socket_address::test_sin6_from_sa() {
-+ torrent::sa_unique_ptr sa_zero = wrap_ai_get_first_sa("::");
-+ torrent::sin6_unique_ptr sin6_zero;
-+
-+ CPPUNIT_ASSERT(sa_zero != nullptr);
-+ CPPUNIT_ASSERT_NO_THROW({ sin6_zero = torrent::sin6_from_sa(std::move(sa_zero)); });
-+ CPPUNIT_ASSERT(sa_zero == nullptr);
-+ CPPUNIT_ASSERT(sin6_zero != nullptr);
-+
-+ CPPUNIT_ASSERT(sin6_zero->sin6_addr.s6_addr[0] == 0x0);
-+ CPPUNIT_ASSERT(sin6_zero->sin6_addr.s6_addr[1] == 0x0);
-+ CPPUNIT_ASSERT(sin6_zero->sin6_addr.s6_addr[15] == 0x0);
-+
-+ torrent::sa_unique_ptr sa_inet6 = wrap_ai_get_first_sa("ff01::1");
-+ torrent::sin6_unique_ptr sin6_inet6;
-+
-+ CPPUNIT_ASSERT(sa_inet6 != nullptr);
-+ CPPUNIT_ASSERT_NO_THROW({ sin6_inet6 = torrent::sin6_from_sa(std::move(sa_inet6)); });
-+ CPPUNIT_ASSERT(sa_inet6 == nullptr);
-+ CPPUNIT_ASSERT(sin6_inet6 != nullptr);
-+
-+ CPPUNIT_ASSERT(sin6_inet6->sin6_addr.s6_addr[0] == 0xff);
-+ CPPUNIT_ASSERT(sin6_inet6->sin6_addr.s6_addr[1] == 0x01);
-+ CPPUNIT_ASSERT(sin6_inet6->sin6_addr.s6_addr[15] == 0x01);
-+
-+ CPPUNIT_ASSERT_THROW(torrent::sin6_from_sa(torrent::sa_unique_ptr()), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sin6_from_sa(torrent::sa_make_unspec()), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sin6_from_sa(torrent::sa_make_inet()), torrent::internal_error);
-+}
-+
-+void
-+test_socket_address::test_sa_equal() {
-+ TEST_DEFAULT_SA;
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sa_make_unspec(), torrent::sa_make_unspec()));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sa_make_inet(), torrent::sa_make_inet()));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sa_make_inet6(), torrent::sa_make_inet6()));
-+
-+ CPPUNIT_ASSERT(!torrent::sap_equal(torrent::sa_make_unspec(), torrent::sa_make_inet()));
-+ CPPUNIT_ASSERT(!torrent::sap_equal(torrent::sa_make_unspec(), torrent::sa_make_inet6()));
-+ CPPUNIT_ASSERT(!torrent::sap_equal(torrent::sa_make_inet(), torrent::sa_make_inet6()));
-+ CPPUNIT_ASSERT(!torrent::sap_equal(torrent::sa_make_inet6(), torrent::sa_make_inet()));
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal(sin_1, sin_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal(sin_1, c_sin_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal(c_sin_1, sin_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal(c_sin_1, c_sin_1));
-+
-+ CPPUNIT_ASSERT(!torrent::sap_equal(sin_1, sin_2));
-+ CPPUNIT_ASSERT(!torrent::sap_equal(sin_1, c_sin_2));
-+ CPPUNIT_ASSERT(!torrent::sap_equal(c_sin_1, sin_2));
-+ CPPUNIT_ASSERT(!torrent::sap_equal(c_sin_1, c_sin_2));
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal(sin6_1, sin6_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal(sin6_1, c_sin6_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal(c_sin6_1, sin6_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal(c_sin6_1, c_sin6_1));
-+
-+ CPPUNIT_ASSERT(!torrent::sap_equal(sin6_1, sin6_2));
-+ CPPUNIT_ASSERT(!torrent::sap_equal(sin6_1, c_sin6_2));
-+ CPPUNIT_ASSERT(!torrent::sap_equal(c_sin6_1, sin6_2));
-+ CPPUNIT_ASSERT(!torrent::sap_equal(c_sin6_1, c_sin6_2));
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal(sin_1_5000, sin_1_5000));
-+ CPPUNIT_ASSERT(torrent::sap_equal(sin6_1_5000, sin6_1_5000));
-+ CPPUNIT_ASSERT(!torrent::sap_equal(sin_1_5000, sin_1_5100));
-+ CPPUNIT_ASSERT(!torrent::sap_equal(sin6_1_5000, sin6_1_5100));
-+ CPPUNIT_ASSERT(!torrent::sap_equal(sin_1_5000, sin_2_5000));
-+ CPPUNIT_ASSERT(!torrent::sap_equal(sin6_1_5000, sin6_2_5000));
-+ CPPUNIT_ASSERT(!torrent::sap_equal(sin_1_5000, sin_2_5100));
-+ CPPUNIT_ASSERT(!torrent::sap_equal(sin6_1_5000, sin6_2_5100));
-+
-+ CPPUNIT_ASSERT_THROW(torrent::sap_equal(torrent::sa_make_unix(""), torrent::sa_make_unix("")), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sap_equal(torrent::sa_make_unix(""), sin6_1), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sap_equal(sin6_1, torrent::sa_make_unix("")), torrent::internal_error);
-+}
-+
-+void
-+test_socket_address::test_sa_equal_addr() {
-+ TEST_DEFAULT_SA;
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sa_make_unspec(), torrent::sa_make_unspec()));
-+ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sa_make_inet(), torrent::sa_make_inet()));
-+ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sa_make_inet6(), torrent::sa_make_inet6()));
-+
-+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(torrent::sa_make_unspec(), torrent::sa_make_inet()));
-+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(torrent::sa_make_unspec(), torrent::sa_make_inet6()));
-+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(torrent::sa_make_inet(), torrent::sa_make_inet6()));
-+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(torrent::sa_make_inet6(), torrent::sa_make_inet()));
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin_1, sin_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin_1, c_sin_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal_addr(c_sin_1, sin_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal_addr(c_sin_1, c_sin_1));
-+
-+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin_1, sin_2));
-+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin_1, c_sin_2));
-+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(c_sin_1, sin_2));
-+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(c_sin_1, c_sin_2));
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin6_1, sin6_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin6_1, c_sin6_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal_addr(c_sin6_1, sin6_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal_addr(c_sin6_1, c_sin6_1));
-+
-+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin6_1, sin6_2));
-+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin6_1, c_sin6_2));
-+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(c_sin6_1, sin6_2));
-+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(c_sin6_1, c_sin6_2));
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin_1_5000, sin_1_5000));
-+ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin6_1_5000, sin6_1_5000));
-+ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin_1_5000, sin_1_5100));
-+ CPPUNIT_ASSERT(torrent::sap_equal_addr(sin6_1_5000, sin6_1_5100));
-+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin_1_5000, sin_2_5000));
-+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin6_1_5000, sin6_2_5000));
-+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin_1_5000, sin_2_5100));
-+ CPPUNIT_ASSERT(!torrent::sap_equal_addr(sin6_1_5000, sin6_2_5100));
-+
-+ CPPUNIT_ASSERT_THROW(torrent::sap_equal_addr(torrent::sa_make_unix(""), torrent::sa_make_unix("")), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sap_equal_addr(torrent::sa_make_unix(""), sin6_1), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sap_equal_addr(sin6_1, torrent::sa_make_unix("")), torrent::internal_error);
-+}
-+
-+void
-+test_socket_address::test_sa_copy() {
-+ TEST_DEFAULT_SA;
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(torrent::sa_make_unspec()), torrent::sa_make_unspec()));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(torrent::sa_make_inet()), sin_any));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(torrent::sa_make_inet6()), sin6_any));
-+
-+ CPPUNIT_ASSERT(torrent::sap_copy(sin_1).get() != sin_1.get());
-+ CPPUNIT_ASSERT(torrent::sap_copy(c_sin_1).get() != c_sin_1.get());
-+ CPPUNIT_ASSERT(torrent::sap_copy(sin6_1).get() != sin6_1.get());
-+ CPPUNIT_ASSERT(torrent::sap_copy(c_sin6_1).get() != c_sin6_1.get());
-+ CPPUNIT_ASSERT(torrent::sap_copy(sin_1_5000).get() != sin_1_5000.get());
-+ CPPUNIT_ASSERT(torrent::sap_copy(sin6_1_5000).get() != sin6_1_5000.get());
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(sin_1), sin_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(sin_1), c_sin_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(c_sin_1), sin_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(c_sin_1), c_sin_1));
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(sin6_1), sin6_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(sin6_1), c_sin6_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(c_sin6_1), sin6_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(c_sin6_1), c_sin6_1));
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(sin_1_5000), sin_1_5000));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(sin6_1_5000), sin6_1_5000));
-+
-+ auto sin6_flags = torrent::sap_copy(sin6_1_5000);
-+ reinterpret_cast<sockaddr_in6*>(sin6_flags.get())->sin6_flowinfo = 0x12345678;
-+ reinterpret_cast<sockaddr_in6*>(sin6_flags.get())->sin6_scope_id = 0x12345678;
-+
-+ // TODO: Need 'strict' equal test.
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy(sin6_flags), sin6_flags));
-+
-+ CPPUNIT_ASSERT_THROW(torrent::sap_copy(torrent::sa_unique_ptr()), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sap_copy(torrent::c_sa_unique_ptr()), torrent::internal_error);
-+}
-+
-+void
-+test_socket_address::test_sa_copy_addr() {
-+ TEST_DEFAULT_SA;
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(torrent::sa_make_unspec()), torrent::sa_make_unspec()));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(torrent::sa_make_inet()), sin_any));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(torrent::sa_make_inet6()), sin6_any));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(torrent::sa_make_unspec(), 5000), torrent::sa_make_unspec()));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(torrent::sa_make_inet(), 5000), sin_any_5000));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(torrent::sa_make_inet6(), 5000), sin6_any_5000));
-+
-+ CPPUNIT_ASSERT(torrent::sap_copy_addr(sin_1).get() != sin_1.get());
-+ CPPUNIT_ASSERT(torrent::sap_copy_addr(c_sin_1).get() != c_sin_1.get());
-+ CPPUNIT_ASSERT(torrent::sap_copy_addr(sin6_1).get() != sin6_1.get());
-+ CPPUNIT_ASSERT(torrent::sap_copy_addr(c_sin6_1).get() != c_sin6_1.get());
-+ CPPUNIT_ASSERT(torrent::sap_copy_addr(sin_1_5000).get() != sin_1_5000.get());
-+ CPPUNIT_ASSERT(torrent::sap_copy_addr(sin6_1_5000).get() != sin6_1_5000.get());
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin_1), sin_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin_1), c_sin_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin_1), sin_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin_1), c_sin_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin_1, 5000), sin_1_5000));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin_1, 5000), c_sin_1_5000));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin_1, 5000), sin_1_5000));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin_1, 5000), c_sin_1_5000));
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin6_1), sin6_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin6_1), c_sin6_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin6_1), sin6_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin6_1), c_sin6_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin6_1, 5000), sin6_1_5000));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin6_1, 5000), c_sin6_1_5000));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin6_1, 5000), sin6_1_5000));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(c_sin6_1, 5000), c_sin6_1_5000));
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin_1_5000), sin_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin6_1_5000), sin6_1));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin_1_5000, 5100), sin_1_5100));
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin6_1_5000, 5100), sin6_1_5100));
-+
-+ auto sin6_flags = wrap_ai_get_first_sa("ff01::1", "5555");
-+ reinterpret_cast<sockaddr_in6*>(sin6_flags.get())->sin6_flowinfo = 0x12345678;
-+ reinterpret_cast<sockaddr_in6*>(sin6_flags.get())->sin6_scope_id = 0x12345678;
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal(torrent::sap_copy_addr(sin6_flags), sin6_1));
-+
-+ CPPUNIT_ASSERT_THROW(torrent::sap_copy_addr(torrent::sa_unique_ptr()), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sap_copy_addr(torrent::c_sa_unique_ptr()), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sap_copy_addr(torrent::sa_unique_ptr(), 5000), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sap_copy_addr(torrent::c_sa_unique_ptr(), 5000), torrent::internal_error);
-+}
-+
-+void
-+test_socket_address::test_sa_from_v4mapped() {
-+ TEST_DEFAULT_SA;
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sap_from_v4mapped(sin6_v4_any), sin_any));
-+ CPPUNIT_ASSERT(torrent::sap_is_port_any(torrent::sap_from_v4mapped(sin6_v4_any)));
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sap_from_v4mapped(sin6_v4_1), sin_1));
-+ CPPUNIT_ASSERT(torrent::sap_is_port_any(torrent::sap_from_v4mapped(sin6_v4_1)));
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sap_from_v4mapped(sin6_v4_bc), sin_bc));
-+ CPPUNIT_ASSERT(torrent::sap_is_port_any(torrent::sap_from_v4mapped(sin6_v4_bc)));
-+
-+ CPPUNIT_ASSERT_THROW(torrent::sap_from_v4mapped(torrent::sa_make_unspec()), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sap_from_v4mapped(torrent::sa_make_inet()), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sap_from_v4mapped(torrent::sa_make_unix("")), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sap_from_v4mapped(sin_any), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sap_from_v4mapped(sin_bc), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sap_from_v4mapped(sin_1), torrent::internal_error);
-+}
-+
-+void
-+test_socket_address::test_sa_to_v4mapped() {
-+ TEST_DEFAULT_SA;
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sap_to_v4mapped(sin_any), sin6_v4_any));
-+ CPPUNIT_ASSERT(torrent::sap_is_v4mapped(torrent::sap_to_v4mapped(sin_any)));
-+ CPPUNIT_ASSERT(torrent::sap_is_port_any(torrent::sap_to_v4mapped(sin_any)));
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sap_to_v4mapped(sin_bc), sin6_v4_bc));
-+ CPPUNIT_ASSERT(torrent::sap_is_v4mapped(torrent::sap_to_v4mapped(sin_bc)));
-+ CPPUNIT_ASSERT(torrent::sap_is_port_any(torrent::sap_to_v4mapped(sin_bc)));
-+
-+ CPPUNIT_ASSERT(torrent::sap_equal_addr(torrent::sap_to_v4mapped(sin_1), sin6_v4_1));
-+ CPPUNIT_ASSERT(torrent::sap_is_v4mapped(torrent::sap_to_v4mapped(sin_1)));
-+ CPPUNIT_ASSERT(torrent::sap_is_port_any(torrent::sap_to_v4mapped(sin_1)));
-+
-+ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(torrent::sa_make_unspec()), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(torrent::sa_make_inet6()), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(torrent::sa_make_unix("")), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(sin6_any), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(sin6_1), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(sin6_v4_any), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(sin6_v4_bc), torrent::internal_error);
-+ CPPUNIT_ASSERT_THROW(torrent::sap_to_v4mapped(sin6_v4_1), torrent::internal_error);
-+}
-diff --git a/test/torrent/net/test_socket_address.h b/test/torrent/net/test_socket_address.h
-new file mode 100644
-index 00000000..6157f366
---- /dev/null
-+++ b/test/torrent/net/test_socket_address.h
-@@ -0,0 +1,43 @@
-+#include <cppunit/extensions/HelperMacros.h>
-+
-+class test_socket_address : public CppUnit::TestFixture {
-+ CPPUNIT_TEST_SUITE(test_socket_address);
-+
-+ CPPUNIT_TEST(test_sa_is_any);
-+ CPPUNIT_TEST(test_sa_is_broadcast);
-+
-+ CPPUNIT_TEST(test_make);
-+
-+ CPPUNIT_TEST(test_sin_from_sa);
-+ CPPUNIT_TEST(test_sin6_from_sa);
-+
-+ CPPUNIT_TEST(test_sa_equal);
-+ CPPUNIT_TEST(test_sa_equal_addr);
-+ CPPUNIT_TEST(test_sa_copy);
-+ CPPUNIT_TEST(test_sa_copy_addr);
-+
-+ CPPUNIT_TEST(test_sa_from_v4mapped);
-+ CPPUNIT_TEST(test_sa_to_v4mapped);
-+
-+ CPPUNIT_TEST_SUITE_END();
-+
-+public:
-+ void setUp() {}
-+ void tearDown() {}
-+
-+ void test_sa_is_any();
-+ void test_sa_is_broadcast();
-+
-+ void test_make();
-+
-+ void test_sin_from_sa();
-+ void test_sin6_from_sa();
-+
-+ void test_sa_equal();
-+ void test_sa_equal_addr();
-+ void test_sa_copy();
-+ void test_sa_copy_addr();
-+
-+ void test_sa_from_v4mapped();
-+ void test_sa_to_v4mapped();
-+};
-diff --git a/test/torrent/net/test_socket_address_key.cc b/test/torrent/net/test_socket_address_key.cc
-deleted file mode 100644
-index 7892e730..00000000
---- a/test/torrent/net/test_socket_address_key.cc
-+++ /dev/null
-@@ -1,87 +0,0 @@
--#include "config.h"
--
--#include lt_tr1_functional
--#include <sys/types.h>
--#include <sys/socket.h>
--
--#include "test_socket_address_key.h"
--
--#include "torrent/utils/net.h"
--#include "torrent/net/socket_address_key.h"
--
--CPPUNIT_TEST_SUITE_REGISTRATION(test_socket_address_key);
--
--// TODO: Move into a test utilities header:
--
--typedef std::function<struct addrinfo* ()> addrinfo_ftor;
--
--static torrent::socket_address_key
--test_create_valid(const char* hostname, addrinfo_ftor ftor) {
-- struct addrinfo* addr_info;
--
-- try {
-- addr_info = ftor();
-- } catch (torrent::address_info_error& e) {
-- CPPUNIT_ASSERT_MESSAGE("Caught address_info_error for '" + std::string(hostname) + "'", false);
-- }
--
-- CPPUNIT_ASSERT_MESSAGE("test_create_valid could not find '" + std::string(hostname) + "'",
-- addr_info != NULL);
--
-- torrent::socket_address_key sock_key = torrent::socket_address_key::from_sockaddr(addr_info->ai_addr);
--
-- CPPUNIT_ASSERT_MESSAGE("test_create_valid failed to create valid socket_address_key for '" + std::string(hostname) + "'",
-- sock_key.is_valid());
--
-- return sock_key;
--}
--
--static bool
--test_create_throws(const char* hostname, addrinfo_ftor ftor) {
-- try {
-- ftor();
--
-- return false;
-- } catch (torrent::address_info_error& e) {
-- return true;
-- }
--}
--
--static torrent::socket_address_key
--test_create_inet(const char* hostname) {
-- return test_create_valid(hostname, std::bind(&torrent::address_info_lookup, hostname, AF_INET, 0));
--}
--
--static bool
--test_create_inet_throws(const char* hostname) {
-- return test_create_throws(hostname, std::bind(&torrent::address_info_lookup, hostname, AF_INET, 0));
--}
--
--static torrent::socket_address_key
--test_create_inet6(const char* hostname) {
-- return test_create_valid(hostname, std::bind(&torrent::address_info_lookup, hostname, AF_INET6, 0));
--}
--
--static bool
--test_create_inet6_throws(const char* hostname) {
-- return test_create_throws(hostname, std::bind(&torrent::address_info_lookup, hostname, AF_INET6, 0));
--}
--
--//
--// Basic tests:
--//
--
--void
--test_socket_address_key::test_basic() {
-- CPPUNIT_ASSERT(test_create_inet("1.1.1.1").is_valid());
-- CPPUNIT_ASSERT(test_create_inet_throws("1.1.1.300"));
--
-- CPPUNIT_ASSERT(test_create_inet6("ff01::1").is_valid());
-- CPPUNIT_ASSERT(test_create_inet6("2001:0db8:85a3:0000:0000:8a2e:0370:7334").is_valid());
-- CPPUNIT_ASSERT(test_create_inet6("2001:db8:a::123").is_valid());
--
-- CPPUNIT_ASSERT(test_create_inet6_throws("2001:db8:a::22123"));
--}
--
--
--// Test lexical comparison:
-diff --git a/test/torrent/object_stream_test.cc b/test/torrent/object_stream_test.cc
-index c8a17049..5ad0c23e 100644
---- a/test/torrent/object_stream_test.cc
-+++ b/test/torrent/object_stream_test.cc
-@@ -1,10 +1,8 @@
- #include "config.h"
-
--#define __STDC_CONSTANT_MACROS
--
- #include <iostream>
- #include <sstream>
--#include <inttypes.h>
-+#include <cinttypes>
- #include <torrent/object.h>
-
- #include "object_stream_test.h"
-diff --git a/test/torrent/tracker_controller_features.cc b/test/torrent/tracker_controller_features.cc
-index 63f163f5..0a6a57d6 100644
---- a/test/torrent/tracker_controller_features.cc
-+++ b/test/torrent/tracker_controller_features.cc
-@@ -1,7 +1,7 @@
- #include "config.h"
-
-+#include <functional>
- #include <iostream>
--#include lt_tr1_functional
-
- #include "rak/priority_queue_default.h"
-
-diff --git a/test/torrent/tracker_controller_requesting.cc b/test/torrent/tracker_controller_requesting.cc
-index 5bc25169..92e664b3 100644
---- a/test/torrent/tracker_controller_requesting.cc
-+++ b/test/torrent/tracker_controller_requesting.cc
-@@ -1,7 +1,7 @@
- #include "config.h"
-
-+#include <functional>
- #include <iostream>
--#include lt_tr1_functional
-
- #include "rak/priority_queue_default.h"
-
-diff --git a/test/torrent/tracker_controller_test.cc b/test/torrent/tracker_controller_test.cc
-index 823a9d34..9406c99e 100644
---- a/test/torrent/tracker_controller_test.cc
-+++ b/test/torrent/tracker_controller_test.cc
-@@ -1,7 +1,7 @@
- #include "config.h"
-
-+#include <functional>
- #include <iostream>
--#include lt_tr1_functional
-
- #include "rak/priority_queue_default.h"
-
-diff --git a/test/torrent/tracker_list_features_test.cc b/test/torrent/tracker_list_features_test.cc
-index 57c05f40..5257b1a7 100644
---- a/test/torrent/tracker_list_features_test.cc
-+++ b/test/torrent/tracker_list_features_test.cc
-@@ -1,6 +1,6 @@
- #include "config.h"
-
--#include lt_tr1_functional
-+#include <functional>
-
- #include "torrent/http.h"
- #include "net/address_list.h"
-diff --git a/test/torrent/utils/directory_events_test.cc b/test/torrent/utils/directory_events_test.cc
-index 2cea5ab5..b97fd1d4 100644
---- a/test/torrent/utils/directory_events_test.cc
-+++ b/test/torrent/utils/directory_events_test.cc
-@@ -1,6 +1,6 @@
- #include "config.h"
-
--#include <tr1/functional>
-+#include <functional>
- #include <torrent/exceptions.h>
- #include <torrent/utils/directory_events.h>
-
-@@ -8,8 +8,6 @@
-
- CPPUNIT_TEST_SUITE_REGISTRATION(utils_directory_events_test);
-
--namespace tr1 { using namespace std::tr1; }
--
- void
- utils_directory_events_test::setUp() {
- }
-diff --git a/test/torrent/utils/log_buffer_test.h b/test/torrent/utils/log_buffer_test.h
-deleted file mode 100644
-index f2824594..00000000
---- a/test/torrent/utils/log_buffer_test.h
-+++ /dev/null
-@@ -1,17 +0,0 @@
--#include <cppunit/extensions/HelperMacros.h>
--
--#include "torrent/utils/log_buffer.h"
--
--class utils_log_buffer_test : public CppUnit::TestFixture {
-- CPPUNIT_TEST_SUITE(utils_log_buffer_test);
-- CPPUNIT_TEST(test_basic);
-- CPPUNIT_TEST(test_timestamps);
-- CPPUNIT_TEST_SUITE_END();
--
--public:
-- void setUp();
-- void tearDown();
--
-- void test_basic();
-- void test_timestamps();
--};
-diff --git a/test/torrent/utils/log_test.cc b/test/torrent/utils/log_test.cc
-index 9f975636..8cc00ef8 100644
---- a/test/torrent/utils/log_test.cc
-+++ b/test/torrent/utils/log_test.cc
-@@ -3,8 +3,9 @@
- #include <algorithm>
- #include <cstring>
- #include <fstream>
-+#include <functional>
- #include <iostream>
--#include lt_tr1_functional
-+
- #include <torrent/exceptions.h>
- #include <torrent/utils/log.h>
-
-@@ -37,6 +38,7 @@ void
- utils_log_test::setUp() {
- // Don't initialize since this creates the group->child connections.
- // torrent::log_initialize();
-+ torrent::log_cleanup();
- }
-
- void
-diff --git a/test/torrent/utils/net_test.cc b/test/torrent/utils/net_test.cc
-deleted file mode 100644
-index d136e869..00000000
---- a/test/torrent/utils/net_test.cc
-+++ /dev/null
-@@ -1,32 +0,0 @@
--#include "config.h"
--
--#include <torrent/exceptions.h>
--#include <torrent/utils/net.h>
--
--#include "net_test.h"
--
--CPPUNIT_TEST_SUITE_REGISTRATION(utils_net_test);
--
--static void inc_value(int* value) { (*value)++; }
--
--#define LTUNIT_AI_CALL(lt_ai, lt_flags) { \
-- int test_value = 0; \
-- CPPUNIT_ASSERT(torrent::address_info_call(ai, 0, std::bind(&inc_value, &test_value))); \
-- CPPUNIT_ASSERT(test_value); } \
--
--void
--utils_net_test::setUp() {
--}
--
--void
--utils_net_test::tearDown() {
--}
--
--void
--utils_net_test::test_basic() {
-- addrinfo* ai = torrent::address_info_lookup("localhost", AF_INET, SOCK_STREAM);
--
-- LTUNIT_AI_CALL(ai, 0);
--
-- torrent::address_info_free(ai);
--}
-diff --git a/test/torrent/utils/net_test.h b/test/torrent/utils/net_test.h
-deleted file mode 100644
-index e538ab39..00000000
---- a/test/torrent/utils/net_test.h
-+++ /dev/null
-@@ -1,15 +0,0 @@
--#include <cppunit/extensions/HelperMacros.h>
--
--#include "torrent/utils/net.h"
--
--class utils_net_test : public CppUnit::TestFixture {
-- CPPUNIT_TEST_SUITE(utils_net_test);
-- CPPUNIT_TEST(test_basic);
-- CPPUNIT_TEST_SUITE_END();
--
--public:
-- void setUp();
-- void tearDown();
--
-- void test_basic();
--};
-diff --git a/test/torrent/utils/option_strings_test.cc b/test/torrent/utils/option_strings_test.cc
-index c6302f98..a9bdcc89 100644
---- a/test/torrent/utils/option_strings_test.cc
-+++ b/test/torrent/utils/option_strings_test.cc
-@@ -1,8 +1,9 @@
- #include "config.h"
-
- #include <fstream>
-+#include <functional>
- #include <iostream>
--#include lt_tr1_functional
-+
- #include <torrent/exceptions.h>
- #include <torrent/utils/option_strings.h>
-
-diff --git a/test/torrent/utils/test_extents.cc b/test/torrent/utils/test_extents.cc
-index d6b8d11d..87424d62 100644
---- a/test/torrent/utils/test_extents.cc
-+++ b/test/torrent/utils/test_extents.cc
-@@ -2,7 +2,7 @@
-
- #include "test_extents.h"
-
--#include <inttypes.h>
-+#include <cinttypes>
- #include <iostream>
- #include <torrent/utils/extents.h>
-
-diff --git a/test/torrent/utils/log_buffer_test.cc b/test/torrent/utils/test_log_buffer.cc
-similarity index 86%
-rename from test/torrent/utils/log_buffer_test.cc
-rename to test/torrent/utils/test_log_buffer.cc
-index a0ede0a0..a56a5365 100644
---- a/test/torrent/utils/log_buffer_test.cc
-+++ b/test/torrent/utils/test_log_buffer.cc
-@@ -1,23 +1,23 @@
- #include "config.h"
-
--#include <torrent/utils/log_buffer.h>
-+#include "test_log_buffer.h"
-
- #include "globals.h"
--#include "log_buffer_test.h"
-+#include <torrent/utils/log_buffer.h>
-
--CPPUNIT_TEST_SUITE_REGISTRATION(utils_log_buffer_test);
-+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_log_buffer, "torrent/utils");
-
- void
--utils_log_buffer_test::setUp() {
-+test_log_buffer::setUp() {
- torrent::cachedTime = rak::timer::from_seconds(1000);
- }
-
- void
--utils_log_buffer_test::tearDown() {
-+test_log_buffer::tearDown() {
- }
-
- void
--utils_log_buffer_test::test_basic() {
-+test_log_buffer::test_basic() {
- torrent::log_buffer log;
-
- log.lock();
-@@ -44,7 +44,7 @@ utils_log_buffer_test::test_basic() {
- }
-
- void
--utils_log_buffer_test::test_timestamps() {
-+test_log_buffer::test_timestamps() {
- torrent::log_buffer log;
-
- log.lock_and_push_log("foobar", 6, 0);
-diff --git a/test/torrent/utils/test_log_buffer.h b/test/torrent/utils/test_log_buffer.h
-new file mode 100644
-index 00000000..290df4c1
---- /dev/null
-+++ b/test/torrent/utils/test_log_buffer.h
-@@ -0,0 +1,17 @@
-+#include "helpers/test_fixture.h"
-+
-+class test_log_buffer : public test_fixture {
-+ CPPUNIT_TEST_SUITE(test_log_buffer);
-+
-+ CPPUNIT_TEST(test_basic);
-+ CPPUNIT_TEST(test_timestamps);
-+
-+ CPPUNIT_TEST_SUITE_END();
-+
-+public:
-+ void setUp();
-+ void tearDown();
-+
-+ void test_basic();
-+ void test_timestamps();
-+};
-diff --git a/test/torrent/utils/test_uri_parser.cc b/test/torrent/utils/test_uri_parser.cc
-index c3b46eef..1f4bebe8 100644
---- a/test/torrent/utils/test_uri_parser.cc
-+++ b/test/torrent/utils/test_uri_parser.cc
-@@ -2,7 +2,7 @@
-
- #include "test_uri_parser.h"
-
--#include <inttypes.h>
-+#include <cinttypes>
- #include <iostream>
- #include <torrent/utils/uri_parser.h>
-
-diff --git a/test/torrent/utils/thread_base_test.cc b/test/torrent/utils/thread_base_test.cc
-index 5cb7553f..8366c9ba 100644
---- a/test/torrent/utils/thread_base_test.cc
-+++ b/test/torrent/utils/thread_base_test.cc
-@@ -1,7 +1,8 @@
- #include "config.h"
-
-+#include <functional>
- #include <unistd.h>
--#include lt_tr1_functional
-+
- #include <torrent/exceptions.h>
- #include <torrent/poll_select.h>
- #include <torrent/utils/thread_base.h>
deleted file mode 100644
@@ -1,26 +0,0 @@
-From b656a77864bd322d69522f1f9d922404066e5a7c Mon Sep 17 00:00:00 2001
-From: Fabrice Fontaine <fontaine.fabrice@gmail.com>
-Date: Mon, 21 Oct 2019 09:32:15 +0200
-Subject: [PATCH] libtorrent.pc.in: add Libs.Private (#202)
-
-Add Libs.Private: -lz so applications that want to link statically with
-libtorrent (such as rtorrent) will know that they must link with -lz
-
-Fixes:
- - http://autobuild.buildroot.org/results/075598e1699c2ac20a4dfbcb5695bbb7343f9a86
-
-Signed-off-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>
----
- libtorrent.pc.in | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/libtorrent.pc.in b/libtorrent.pc.in
-index cf6612bc..6108f7e9 100644
---- a/libtorrent.pc.in
-+++ b/libtorrent.pc.in
-@@ -7,4 +7,5 @@ Name: libtorrent
- Description: A BitTorrent library
- Version: @VERSION@
- Libs: -L${libdir} -ltorrent
-+Libs.Private: -lz
- Cflags: -I${includedir}
deleted file mode 100644
@@ -1,27 +0,0 @@
-From 7c80dc3e3a47dd996ca0554fce4f69d16761a9c9 Mon Sep 17 00:00:00 2001
-From: Tadej Obrstar <tadej.obrstar@gmail.com>
-Date: Sun, 1 Dec 2019 06:59:25 +0100
-Subject: [PATCH] Fix for inotify missing quickly renamed files (#203)
-
----
- src/torrent/utils/directory_events.cc | 7 +++++--
- 1 file changed, 5 insertions(+), 2 deletions(-)
-
-diff --git a/src/torrent/utils/directory_events.cc b/src/torrent/utils/directory_events.cc
-index 5d789f4e..8dcc2a61 100644
---- a/src/torrent/utils/directory_events.cc
-+++ b/src/torrent/utils/directory_events.cc
-@@ -154,8 +154,11 @@ directory_events::event_read() {
- wd_list::const_iterator itr = std::find_if(m_wd_list.begin(), m_wd_list.end(),
- std::bind(&watch_descriptor::compare_desc, std::placeholders::_1, event->wd));
-
-- if (itr != m_wd_list.end())
-- itr->slot(itr->path + event->name);
-+ if (itr != m_wd_list.end()) {
-+ std::string sname(event->name);
-+ if((sname.substr(sname.find_last_of(".") ) == ".torrent"))
-+ itr->slot(itr->path + event->name);
-+ }
-
- event = (struct inotify_event*)(next_event);
- }
deleted file mode 100644
@@ -1,470 +0,0 @@
-From 81897862edea81e9620493c473f488d1820bcf93 Mon Sep 17 00:00:00 2001
-From: Jari Sundell <sundell.software@gmail.com>
-Date: Tue, 3 Dec 2019 21:53:48 +0900
-Subject: [PATCH] Fix compiler warnings. (#204)
-
----
- configure.ac | 6 ++-
- scripts/ax_execinfo.m4 | 67 +++++++++++++++++++++++++++++++
- scripts/common.m4 | 15 -------
- scripts/rak_execinfo.m4 | 11 +++++
- src/torrent/exceptions.cc | 4 +-
- test/Makefile.am | 15 ++-----
- test/helpers/expect_fd.h | 8 ++--
- test/helpers/mock_compare.h | 6 +--
- test/helpers/progress_listener.cc | 3 +-
- test/main.cc | 4 +-
- test/net/Makefile.am | 40 ++++++++++++++++++
- test/torrent/net/Makefile.am | 44 ++++++++++++++++++++
- test/torrent/net/test_fd.cc | 48 +++++++++++-----------
- 13 files changed, 207 insertions(+), 64 deletions(-)
- create mode 100644 scripts/ax_execinfo.m4
- create mode 100644 scripts/rak_execinfo.m4
- create mode 100644 test/net/Makefile.am
- create mode 100644 test/torrent/net/Makefile.am
-
-diff --git a/configure.ac b/configure.ac
-index 620ca552..b6708366 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -33,6 +33,7 @@ RAK_CHECK_CXXFLAGS
- RAK_ENABLE_DEBUG
- RAK_ENABLE_EXTRA_DEBUG
- RAK_ENABLE_WERROR
-+RAK_DISABLE_BACKTRACE
-
- RAK_CHECK_CXX11
-
-@@ -57,8 +58,8 @@ TORRENT_WITH_INOTIFY
-
- CC_ATTRIBUTE_VISIBILITY
-
--AX_PTHREAD
- AX_CHECK_ZLIB
-+AX_PTHREAD
-
- PKG_CHECK_MODULES([CPPUNIT], [cppunit],, [no_cppunit="yes"])
-
-@@ -74,7 +75,6 @@ AC_CHECK_FUNCS(posix_memalign)
- TORRENT_CHECK_MADVISE()
- TORRENT_CHECK_CACHELINE()
- TORRENT_CHECK_POPCOUNT()
--TORRENT_CHECK_EXECINFO()
- TORRENT_CHECK_PTHREAD_SETNAME_NP()
- TORRENT_MINCORE()
-
-@@ -111,4 +111,6 @@ AC_OUTPUT([
- src/tracker/Makefile
- src/utils/Makefile
- test/Makefile
-+ test/torrent/net/Makefile
-+ test/net/Makefile
- ])
-diff --git a/scripts/ax_execinfo.m4 b/scripts/ax_execinfo.m4
-new file mode 100644
-index 00000000..0ff5fc0e
---- /dev/null
-+++ b/scripts/ax_execinfo.m4
-@@ -0,0 +1,67 @@
-+# ===========================================================================
-+# https://www.gnu.org/software/autoconf-archive/ax_execinfo.html
-+# ===========================================================================
-+#
-+# SYNOPSIS
-+#
-+# AX_EXECINFO([ACTION-IF-EXECINFO-H-IS-FOUND], [ACTION-IF-EXECINFO-H-IS-NOT-FOUND], [ADDITIONAL-TYPES-LIST])
-+#
-+# DESCRIPTION
-+#
-+# Checks for execinfo.h header and if the len parameter/return type can be
-+# found from a list, also define backtrace_size_t to that type.
-+#
-+# By default the list of types to try contains int and size_t, but should
-+# some yet undiscovered system use e.g. unsigned, the 3rd argument can be
-+# used for extensions. I'd like to hear of further suggestions.
-+#
-+# Executes ACTION-IF-EXECINFO-H-IS-FOUND when present and the execinfo.h
-+# header is found or ACTION-IF-EXECINFO-H-IS-NOT-FOUND in case the header
-+# seems unavailable.
-+#
-+# Also adds -lexecinfo to LIBS on BSD if needed.
-+#
-+# LICENSE
-+#
-+# Copyright (c) 2014 Thomas Jahns <jahns@dkrz.de>
-+#
-+# Copying and distribution of this file, with or without modification, are
-+# permitted in any medium without royalty provided the copyright notice
-+# and this notice are preserved. This file is offered as-is, without any
-+# warranty.
-+
-+#serial 2
-+
-+AC_DEFUN([AX_EXECINFO],
-+ [AC_CHECK_HEADERS([execinfo.h])
-+ AS_IF([test x"$ac_cv_header_execinfo_h" = xyes],
-+ [AC_CACHE_CHECK([size parameter type for backtrace()],
-+ [ax_cv_proto_backtrace_type],
-+ [AC_LANG_PUSH([C])
-+ for ax_cv_proto_backtrace_type in size_t int m4_ifnblank([$3],[$3 ])none; do
-+ AS_IF([test "${ax_cv_proto_backtrace_type}" = none],
-+ [ax_cv_proto_backtrace_type= ; break])
-+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
-+#include <execinfo.h>
-+extern
-+${ax_cv_proto_backtrace_type} backtrace(void **addrlist, ${ax_cv_proto_backtrace_type} len);
-+char **backtrace_symbols(void *const *buffer, ${ax_cv_proto_backtrace_type} size);
-+])],
-+ [break])
-+ done
-+ AC_LANG_POP([C])])])
-+ AS_IF([test x${ax_cv_proto_backtrace_type} != x],
-+ [AC_DEFINE_UNQUOTED([backtrace_size_t], [$ax_cv_proto_backtrace_type],
-+ [Defined to return type of backtrace().])])
-+ AC_SEARCH_LIBS([backtrace],[execinfo])
-+ AS_IF([test x"${ax_cv_proto_backtrace_type}" != x -a x"$ac_cv_header_execinfo_h" = xyes -a x"$ac_cv_search_backtrace" != xno],
-+ [AC_DEFINE([HAVE_BACKTRACE],[1],
-+ [Defined if backtrace() could be fully identified.])
-+ ]m4_ifnblank([$1],[$1
-+]),m4_ifnblank([$2],[$2
-+]))])
-+dnl
-+dnl Local Variables:
-+dnl mode: autoconf
-+dnl End:
-+dnl
-diff --git a/scripts/common.m4 b/scripts/common.m4
-index b6d051f5..55e8d66e 100644
---- a/scripts/common.m4
-+++ b/scripts/common.m4
-@@ -150,21 +150,6 @@ dnl Need to fix this so that it uses the stuff defined by the system.
- ])
- ])
-
--AC_DEFUN([TORRENT_CHECK_EXECINFO], [
-- AC_MSG_CHECKING(for execinfo.h)
--
-- AC_COMPILE_IFELSE([AC_LANG_SOURCE([
-- #include <execinfo.h>
-- int main() { backtrace((void**)0, 0); backtrace_symbols((char**)0, 0); return 0;}
-- ])],
-- [
-- AC_MSG_RESULT(yes)
-- AC_DEFINE(USE_EXECINFO, 1, Use execinfo.h)
-- ], [
-- AC_MSG_RESULT(no)
-- ])
--])
--
- AC_DEFUN([TORRENT_CHECK_ALIGNED], [
- AC_MSG_CHECKING(the byte alignment)
-
-diff --git a/scripts/rak_execinfo.m4 b/scripts/rak_execinfo.m4
-new file mode 100644
-index 00000000..c1d9b2f8
---- /dev/null
-+++ b/scripts/rak_execinfo.m4
-@@ -0,0 +1,11 @@
-+AC_DEFUN([RAK_DISABLE_BACKTRACE], [
-+ AC_ARG_ENABLE(backtrace,
-+ AC_HELP_STRING([--disable-backtrace], [disable backtrace information [[default=no]]]),
-+ [
-+ if test "$enableval" = "yes"; then
-+ AX_EXECINFO
-+ fi
-+ ],[
-+ AX_EXECINFO
-+ ])
-+])
-diff --git a/src/torrent/exceptions.cc b/src/torrent/exceptions.cc
-index 2aeca1d7..f834f9fa 100644
---- a/src/torrent/exceptions.cc
-+++ b/src/torrent/exceptions.cc
-@@ -42,7 +42,7 @@
- #include <sstream>
- #include <unistd.h>
-
--#ifdef USE_EXECINFO
-+#ifdef HAVE_BACKTRACE
- #include <execinfo.h>
- #endif
-
-@@ -75,7 +75,7 @@ internal_error::initialize(const std::string& msg) {
-
- std::stringstream output;
-
--#ifdef USE_EXECINFO
-+#ifdef HAVE_BACKTRACE
- void* stackPtrs[20];
-
- // Print the stack and exit.
-diff --git a/test/Makefile.am b/test/Makefile.am
-index b60a86a6..23b260e4 100644
---- a/test/Makefile.am
-+++ b/test/Makefile.am
-@@ -1,3 +1,5 @@
-+SUBDIRS = torrent/net net
-+
- TESTS = LibTorrentTest
- AUTOMAKE_OPTIONS = subdir-objects
-
-@@ -43,19 +45,9 @@ LibTorrentTest_SOURCES = \
- data/hash_queue_test.cc \
- data/hash_queue_test.h \
- \
-- net/test_socket_listen.cc \
-- net/test_socket_listen.h \
-- \
- protocol/test_request_list.cc \
- protocol/test_request_list.h \
- \
-- torrent/net/test_address_info.cc \
-- torrent/net/test_address_info.h \
-- torrent/net/test_fd.cc \
-- torrent/net/test_fd.h \
-- torrent/net/test_socket_address.cc \
-- torrent/net/test_socket_address.h \
-- \
- torrent/utils/log_test.cc \
- torrent/utils/log_test.h \
- torrent/utils/option_strings_test.cc \
-@@ -97,9 +89,10 @@ LibTorrentTest_SOURCES = \
- torrent/tracker_timeout_test.h \
- tracker/tracker_http_test.cc \
- tracker/tracker_http_test.h \
-+ \
- main.cc
-
- LibTorrentTest_CXXFLAGS = $(CPPUNIT_CFLAGS)
--LibTorrentTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl
-+LibTorrentTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl
-
- AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir) -I$(top_srcdir)/src
-diff --git a/test/helpers/expect_fd.h b/test/helpers/expect_fd.h
-index 178cbabc..cc77c34a 100644
---- a/test/helpers/expect_fd.h
-+++ b/test/helpers/expect_fd.h
-@@ -18,15 +18,15 @@ sap_cache_copy_addr_c_ptr(sap_cache_type& sap_cache, const torrent::c_sa_unique_
-
- inline void
- expect_event_open_re(int idx) {
-- mock_expect(&torrent::poll_event_open, mock_compare_map<torrent::Event>::begin_pointer + idx);
-- mock_expect(&torrent::poll_event_insert_read, mock_compare_map<torrent::Event>::begin_pointer + idx);
-- mock_expect(&torrent::poll_event_insert_error, mock_compare_map<torrent::Event>::begin_pointer + idx);
-+ mock_expect(&torrent::poll_event_open, mock_compare_map<torrent::Event>::begin_pointer() + idx);
-+ mock_expect(&torrent::poll_event_insert_read, mock_compare_map<torrent::Event>::begin_pointer() + idx);
-+ mock_expect(&torrent::poll_event_insert_error, mock_compare_map<torrent::Event>::begin_pointer() + idx);
- }
-
- inline void
- expect_event_closed_fd(int idx, int fd) {
- mock_expect(&torrent::fd__close, 0, fd);
-- mock_expect(&torrent::poll_event_closed, mock_compare_map<torrent::Event>::begin_pointer + idx);
-+ mock_expect(&torrent::poll_event_closed, mock_compare_map<torrent::Event>::begin_pointer() + idx);
- }
-
- inline void
-diff --git a/test/helpers/mock_compare.h b/test/helpers/mock_compare.h
-index 3ea90305..3cc8d075 100644
---- a/test/helpers/mock_compare.h
-+++ b/test/helpers/mock_compare.h
-@@ -34,11 +34,11 @@ template <typename T>
- struct mock_compare_map {
- typedef std::map<const T*, const T*> values_type;
-
-- constexpr static T* begin_pointer = reinterpret_cast<T*>(0x1000);
-- constexpr static T* end_pointer = reinterpret_cast<T*>(0x2000);
-+ static T* begin_pointer() { return reinterpret_cast<T*>(0x1000); }
-+ static T* end_pointer() { return reinterpret_cast<T*>(0x2000); }
-
- static bool is_key(const T* k) {
-- return k >= begin_pointer && k < end_pointer;
-+ return k >= begin_pointer() && k < end_pointer();
- }
-
- static bool has_key(const T* k) {
-diff --git a/test/helpers/progress_listener.cc b/test/helpers/progress_listener.cc
-index 02803ffc..c2b60bcd 100644
---- a/test/helpers/progress_listener.cc
-+++ b/test/helpers/progress_listener.cc
-@@ -54,7 +54,8 @@ void
- progress_listener::startSuite(CppUnit::Test *suite) {
- m_test_path.push_back(suite);
-
-- std::cout << std::endl << get_test_path(m_test_path) << suite->getName() << ":" << std::endl;
-+ if (suite->countTestCases() > 0)
-+ std::cout << std::endl << get_test_path(m_test_path) << suite->getName() << ":" << std::endl;
- }
-
- void
-diff --git a/test/main.cc b/test/main.cc
-index da93fead..e8a00e1f 100644
---- a/test/main.cc
-+++ b/test/main.cc
-@@ -12,7 +12,7 @@
- #include <cppunit/extensions/TestFactoryRegistry.h>
- #include <cppunit/ui/text/TestRunner.h>
-
--#ifdef USE_EXECINFO
-+#ifdef HAVE_BACKTRACE
- #include <execinfo.h>
- #endif
-
-@@ -29,7 +29,7 @@ do_test_panic(int signum) {
-
- std::cout << std::endl << std::endl << "Caught " << strsignal(signum) << ", dumping stack:" << std::endl << std::endl;
-
--#ifdef USE_EXECINFO
-+#ifdef HAVE_BACKTRACE
- void* stackPtrs[20];
-
- // Print the stack and exit.
-diff --git a/test/net/Makefile.am b/test/net/Makefile.am
-new file mode 100644
-index 00000000..bb951814
---- /dev/null
-+++ b/test/net/Makefile.am
-@@ -0,0 +1,40 @@
-+TESTS = LibTorrentTestNet
-+AUTOMAKE_OPTIONS = subdir-objects
-+
-+check_PROGRAMS = $(TESTS)
-+LibTorrentTestNet_LDADD = \
-+ ../../src/libtorrent.la \
-+ ../../src/torrent/libsub_torrent.la \
-+ ../../src/torrent/data/libsub_torrentdata.la \
-+ ../../src/torrent/download/libsub_torrentdownload.la \
-+ ../../src/torrent/peer/libsub_torrentpeer.la \
-+ ../../src/data/libsub_data.la \
-+ ../../src/dht/libsub_dht.la \
-+ ../../src/net/libsub_net.la \
-+ ../../src/protocol/libsub_protocol.la \
-+ ../../src/download/libsub_download.la \
-+ ../../src/tracker/libsub_tracker.la \
-+ ../../src/utils/libsub_utils.la \
-+ ../../src/torrent/utils/libsub_torrentutils.la
-+
-+LibTorrentTestNet_SOURCES = \
-+ ../helpers/expect_fd.h \
-+ ../helpers/expect_utils.h \
-+ ../helpers/mock_compare.h \
-+ ../helpers/mock_function.cc \
-+ ../helpers/mock_function.h \
-+ ../helpers/network.h \
-+ ../helpers/progress_listener.cc \
-+ ../helpers/progress_listener.h \
-+ ../helpers/test_fixture.cc \
-+ ../helpers/test_fixture.h \
-+ \
-+ test_socket_listen.cc \
-+ test_socket_listen.h \
-+ \
-+ ../main.cc
-+
-+LibTorrentTestNet_CXXFLAGS = $(CPPUNIT_CFLAGS)
-+LibTorrentTestNet_LDFLAGS = $(CPPUNIT_LIBS) -ldl
-+
-+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/test
-diff --git a/test/torrent/net/Makefile.am b/test/torrent/net/Makefile.am
-new file mode 100644
-index 00000000..8a531cc1
---- /dev/null
-+++ b/test/torrent/net/Makefile.am
-@@ -0,0 +1,44 @@
-+TESTS = LibTorrentTestTorrentNet
-+AUTOMAKE_OPTIONS = subdir-objects
-+
-+check_PROGRAMS = $(TESTS)
-+LibTorrentTestTorrentNet_LDADD = \
-+ ../../../src/libtorrent.la \
-+ ../../../src/torrent/libsub_torrent.la \
-+ ../../../src/torrent/data/libsub_torrentdata.la \
-+ ../../../src/torrent/download/libsub_torrentdownload.la \
-+ ../../../src/torrent/peer/libsub_torrentpeer.la \
-+ ../../../src/data/libsub_data.la \
-+ ../../../src/dht/libsub_dht.la \
-+ ../../../src/net/libsub_net.la \
-+ ../../../src/protocol/libsub_protocol.la \
-+ ../../../src/download/libsub_download.la \
-+ ../../../src/tracker/libsub_tracker.la \
-+ ../../../src/utils/libsub_utils.la \
-+ ../../../src/torrent/utils/libsub_torrentutils.la
-+
-+LibTorrentTestTorrentNet_SOURCES = \
-+ ../../helpers/expect_fd.h \
-+ ../../helpers/expect_utils.h \
-+ ../../helpers/mock_compare.h \
-+ ../../helpers/mock_function.cc \
-+ ../../helpers/mock_function.h \
-+ ../../helpers/network.h \
-+ ../../helpers/progress_listener.cc \
-+ ../../helpers/progress_listener.h \
-+ ../../helpers/test_fixture.cc \
-+ ../../helpers/test_fixture.h \
-+ \
-+ test_address_info.cc \
-+ test_address_info.h \
-+ test_fd.cc \
-+ test_fd.h \
-+ test_socket_address.cc \
-+ test_socket_address.h \
-+ \
-+ ../../main.cc
-+
-+LibTorrentTestTorrentNet_CXXFLAGS = $(CPPUNIT_CFLAGS)
-+LibTorrentTestTorrentNet_LDFLAGS = $(CPPUNIT_LIBS) -ldl
-+
-+AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/src -I$(top_srcdir)/test
-diff --git a/test/torrent/net/test_fd.cc b/test/torrent/net/test_fd.cc
-index 3cab0c5e..5e56f0f3 100644
---- a/test/torrent/net/test_fd.cc
-+++ b/test/torrent/net/test_fd.cc
-@@ -1,24 +1,24 @@
--#include "config.h"
--
--#include "test_fd.h"
--
--#include <torrent/net/fd.h>
--
--CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_fd, "torrent/net");
--
--void
--test_fd::test_valid_flags() {
-- CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream));
-- CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_nonblock));
-- CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_reuse_address));
-- CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only));
-- CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v6only));
--
-- CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_v4only | torrent::fd_flag_v6only));
-- CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only | torrent::fd_flag_v6only));
--
-- CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags()));
-- CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(~torrent::fd_flag_all)));
-- CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(torrent::fd_flag_stream | ~torrent::fd_flag_all)));
-- CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(0x3245132)));
--}
-+#include "config.h"
-+
-+#include "test_fd.h"
-+
-+#include <torrent/net/fd.h>
-+
-+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_fd, "torrent/net");
-+
-+void
-+test_fd::test_valid_flags() {
-+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream));
-+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_nonblock));
-+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_reuse_address));
-+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only));
-+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v6only));
-+
-+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_v4only | torrent::fd_flag_v6only));
-+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only | torrent::fd_flag_v6only));
-+
-+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags()));
-+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(~torrent::fd_flag_all)));
-+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(torrent::fd_flag_stream | ~torrent::fd_flag_all)));
-+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(0x3245132)));
-+}
deleted file mode 100644
@@ -1,33 +0,0 @@
-From e813c344b1e4aa89288febb2f59109972083f1bb Mon Sep 17 00:00:00 2001
-From: Rosen Penev <rosenp@gmail.com>
-Date: Thu, 5 Dec 2019 01:55:53 -0800
-Subject: [PATCH] Fix log format so GCC can check it. (#205)
-
----
- src/torrent/utils/log.cc | 6 +++---
- 1 file changed, 3 insertions(+), 3 deletions(-)
-
-diff --git a/src/torrent/utils/log.cc b/src/torrent/utils/log.cc
-index b855a2c6..24932996 100644
---- a/src/torrent/utils/log.cc
-+++ b/src/torrent/utils/log.cc
-@@ -16,6 +16,8 @@
- #include <functional>
- #include <memory>
-
-+#define GROUPFMT (group >= LOG_NON_CASCADING) ? ("%" PRIi32 " ") : ("%" PRIi32 " %c ")
-+
- namespace torrent {
-
- struct log_cache_entry {
-@@ -356,9 +358,7 @@ log_gz_file_write(std::shared_ptr<log_gz_output>& outfile, const char* data, siz
-
- // Normal groups are nul-terminated strings.
- if (group >= 0) {
-- const char* fmt = (group >= LOG_NON_CASCADING) ? ("%" PRIi32 " ") : ("%" PRIi32 " %c ");
--
-- int buffer_length = snprintf(buffer, 64, fmt,
-+ int buffer_length = snprintf(buffer, 64, GROUPFMT,
- cachedTime.seconds(),
- log_level_char[group % 6]);
-
deleted file mode 100644
@@ -1,843 +0,0 @@
-From 7b85e112ac2f59a39afa344148a946553c776142 Mon Sep 17 00:00:00 2001
-From: Jari Sundell <sundell.software@gmail.com>
-Date: Fri, 6 Dec 2019 00:35:21 +0900
-Subject: [PATCH] Consolidate make script to optimize build. (#206)
-
----
- configure.ac | 14 +--
- src/Makefile.am | 147 ++++++++++++++++++++++++-----
- src/data/Makefile.am | 28 ------
- src/dht/Makefile.am | 18 ----
- src/download/Makefile.am | 19 ----
- src/net/Makefile.am | 30 ------
- src/protocol/Makefile.am | 28 ------
- src/torrent/Makefile.am | 154 ++++++++++++++++++++++++++++---
- src/torrent/download/Makefile.am | 22 -----
- src/torrent/net/Makefile.am | 25 -----
- src/torrent/peer/Makefile.am | 28 ------
- src/torrent/utils/Makefile.am | 41 --------
- src/tracker/Makefile.am | 11 ---
- src/utils/Makefile.am | 14 ---
- test/Makefile.am | 92 +++++++++++++-----
- 15 files changed, 338 insertions(+), 333 deletions(-)
- delete mode 100644 src/data/Makefile.am
- delete mode 100644 src/dht/Makefile.am
- delete mode 100644 src/download/Makefile.am
- delete mode 100644 src/net/Makefile.am
- delete mode 100644 src/protocol/Makefile.am
- delete mode 100644 src/torrent/download/Makefile.am
- delete mode 100644 src/torrent/net/Makefile.am
- delete mode 100644 src/torrent/peer/Makefile.am
- delete mode 100644 src/torrent/utils/Makefile.am
- delete mode 100644 src/tracker/Makefile.am
- delete mode 100644 src/utils/Makefile.am
-
-diff --git a/configure.ac b/configure.ac
-index b6708366..e83710cc 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -17,7 +17,7 @@ AC_SUBST(LIBTORRENT_CURRENT)
- AC_SUBST(LIBTORRENT_INTERFACE_VERSION_INFO)
- AC_SUBST(LIBTORRENT_INTERFACE_VERSION_NO)
-
--AM_INIT_AUTOMAKE([serial-tests])
-+AM_INIT_AUTOMAKE([serial-tests subdir-objects])
- AC_CONFIG_HEADERS(config.h)
-
- AC_PROG_CXX
-@@ -98,18 +98,6 @@ AC_OUTPUT([
- Makefile
- src/Makefile
- src/torrent/Makefile
-- src/torrent/data/Makefile
-- src/torrent/download/Makefile
-- src/torrent/net/Makefile
-- src/torrent/peer/Makefile
-- src/torrent/utils/Makefile
-- src/data/Makefile
-- src/dht/Makefile
-- src/download/Makefile
-- src/net/Makefile
-- src/protocol/Makefile
-- src/tracker/Makefile
-- src/utils/Makefile
- test/Makefile
- test/torrent/net/Makefile
- test/net/Makefile
-diff --git a/src/Makefile.am b/src/Makefile.am
-index 99aaace0..e96bd74b 100644
---- a/src/Makefile.am
-+++ b/src/Makefile.am
-@@ -1,30 +1,12 @@
--SUBDIRS = \
-- torrent \
-- data \
-- dht \
-- download \
-- net \
-- protocol \
-- tracker \
-- utils
-+SUBDIRS = torrent
-
- lib_LTLIBRARIES = libtorrent.la
-+noinst_LTLIBRARIES = libtorrent_other.la
-
- libtorrent_la_LDFLAGS = -version-info $(LIBTORRENT_INTERFACE_VERSION_INFO)
- libtorrent_la_LIBADD = \
-- torrent/libsub_torrent.la \
-- torrent/data/libsub_torrentdata.la \
-- torrent/download/libsub_torrentdownload.la \
-- torrent/net/libsub_torrentnet.la \
-- torrent/peer/libsub_torrentpeer.la \
-- torrent/utils/libsub_torrentutils.la \
-- data/libsub_data.la \
-- dht/libsub_dht.la \
-- download/libsub_download.la \
-- net/libsub_net.la \
-- protocol/libsub_protocol.la \
-- tracker/libsub_tracker.la \
-- utils/libsub_utils.la
-+ torrent/libtorrent_torrent.la \
-+ libtorrent_other.la
-
- libtorrent_la_SOURCES = \
- globals.cc \
-@@ -36,4 +18,125 @@ libtorrent_la_SOURCES = \
- thread_main.cc \
- thread_main.h
-
-+libtorrent_other_la_SOURCES = \
-+ data/chunk.cc \
-+ data/chunk.h \
-+ data/chunk_handle.h \
-+ data/chunk_iterator.h \
-+ data/chunk_list.cc \
-+ data/chunk_list.h \
-+ data/chunk_list_node.h \
-+ data/chunk_part.cc \
-+ data/chunk_part.h \
-+ data/hash_check_queue.cc \
-+ data/hash_check_queue.h \
-+ data/hash_chunk.cc \
-+ data/hash_chunk.h \
-+ data/hash_queue.cc \
-+ data/hash_queue.h \
-+ data/hash_queue_node.cc \
-+ data/hash_queue_node.h \
-+ data/hash_torrent.cc \
-+ data/hash_torrent.h \
-+ data/memory_chunk.cc \
-+ data/memory_chunk.h \
-+ data/socket_file.cc \
-+ data/socket_file.h \
-+ \
-+ dht/dht_bucket.cc \
-+ dht/dht_bucket.h \
-+ dht/dht_hash_map.h \
-+ dht/dht_node.cc \
-+ dht/dht_node.h \
-+ dht/dht_router.cc \
-+ dht/dht_router.h \
-+ dht/dht_server.cc \
-+ dht/dht_server.h \
-+ dht/dht_tracker.cc \
-+ dht/dht_tracker.h \
-+ dht/dht_transaction.cc \
-+ dht/dht_transaction.h \
-+ \
-+ download/available_list.cc \
-+ download/available_list.h \
-+ download/chunk_selector.cc \
-+ download/chunk_selector.h \
-+ download/chunk_statistics.cc \
-+ download/chunk_statistics.h \
-+ download/delegator.cc \
-+ download/delegator.h \
-+ download/download_constructor.cc \
-+ download/download_constructor.h \
-+ download/download_main.cc \
-+ download/download_main.h \
-+ download/download_wrapper.cc \
-+ download/download_wrapper.h \
-+ \
-+ net/address_list.cc \
-+ net/address_list.h \
-+ net/data_buffer.h \
-+ net/local_addr.cc \
-+ net/local_addr.h \
-+ net/listen.cc \
-+ net/listen.h \
-+ net/protocol_buffer.h \
-+ net/socket_base.cc \
-+ net/socket_base.h \
-+ net/socket_datagram.cc \
-+ net/socket_datagram.h \
-+ net/socket_fd.cc \
-+ net/socket_fd.h \
-+ net/socket_listen.cc \
-+ net/socket_listen.h \
-+ net/socket_set.cc \
-+ net/socket_set.h \
-+ net/socket_stream.cc \
-+ net/socket_stream.h \
-+ net/throttle_internal.cc \
-+ net/throttle_internal.h \
-+ net/throttle_list.cc \
-+ net/throttle_list.h \
-+ net/throttle_node.h \
-+ \
-+ protocol/encryption_info.h \
-+ protocol/extensions.cc \
-+ protocol/extensions.h \
-+ protocol/handshake.cc \
-+ protocol/handshake.h \
-+ protocol/handshake_encryption.cc \
-+ protocol/handshake_encryption.h \
-+ protocol/handshake_manager.cc \
-+ protocol/handshake_manager.h \
-+ protocol/initial_seed.cc \
-+ protocol/initial_seed.h \
-+ protocol/peer_chunks.h \
-+ protocol/peer_connection_base.cc \
-+ protocol/peer_connection_base.h \
-+ protocol/peer_connection_leech.cc \
-+ protocol/peer_connection_leech.h \
-+ protocol/peer_connection_metadata.cc \
-+ protocol/peer_connection_metadata.h \
-+ protocol/peer_factory.cc \
-+ protocol/peer_factory.h \
-+ protocol/protocol_base.h \
-+ protocol/request_list.cc \
-+ protocol/request_list.h \
-+ \
-+ tracker/tracker_dht.cc \
-+ tracker/tracker_dht.h \
-+ tracker/tracker_http.cc \
-+ tracker/tracker_http.h \
-+ tracker/tracker_udp.cc \
-+ tracker/tracker_udp.h \
-+ \
-+ utils/diffie_hellman.cc \
-+ utils/diffie_hellman.h \
-+ utils/instrumentation.cc \
-+ utils/instrumentation.h \
-+ utils/rc4.h \
-+ utils/sha1.h \
-+ utils/sha_fast.cc \
-+ utils/sha_fast.h \
-+ utils/queue_buckets.h
-+
- AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir)
-diff --git a/src/data/Makefile.am b/src/data/Makefile.am
-deleted file mode 100644
-index ef41c9bd..00000000
---- a/src/data/Makefile.am
-+++ /dev/null
-@@ -1,28 +0,0 @@
--noinst_LTLIBRARIES = libsub_data.la
--
--libsub_data_la_SOURCES = \
-- chunk.cc \
-- chunk.h \
-- chunk_handle.h \
-- chunk_iterator.h \
-- chunk_list.cc \
-- chunk_list.h \
-- chunk_list_node.h \
-- chunk_part.cc \
-- chunk_part.h \
-- hash_check_queue.cc \
-- hash_check_queue.h \
-- hash_chunk.cc \
-- hash_chunk.h \
-- hash_queue.cc \
-- hash_queue.h \
-- hash_queue_node.cc \
-- hash_queue_node.h \
-- hash_torrent.cc \
-- hash_torrent.h \
-- memory_chunk.cc \
-- memory_chunk.h \
-- socket_file.cc \
-- socket_file.h
--
--AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
-diff --git a/src/dht/Makefile.am b/src/dht/Makefile.am
-deleted file mode 100644
-index a87c57bc..00000000
---- a/src/dht/Makefile.am
-+++ /dev/null
-@@ -1,18 +0,0 @@
--noinst_LTLIBRARIES = libsub_dht.la
--
--libsub_dht_la_SOURCES = \
-- dht_bucket.cc \
-- dht_bucket.h \
-- dht_hash_map.h \
-- dht_node.cc \
-- dht_node.h \
-- dht_router.cc \
-- dht_router.h \
-- dht_server.cc \
-- dht_server.h \
-- dht_tracker.cc \
-- dht_tracker.h \
-- dht_transaction.cc \
-- dht_transaction.h
--
--AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
-diff --git a/src/download/Makefile.am b/src/download/Makefile.am
-deleted file mode 100644
-index 65ceaf97..00000000
---- a/src/download/Makefile.am
-+++ /dev/null
-@@ -1,19 +0,0 @@
--noinst_LTLIBRARIES = libsub_download.la
--
--libsub_download_la_SOURCES = \
-- available_list.cc \
-- available_list.h \
-- chunk_selector.cc \
-- chunk_selector.h \
-- chunk_statistics.cc \
-- chunk_statistics.h \
-- delegator.cc \
-- delegator.h \
-- download_constructor.cc \
-- download_constructor.h \
-- download_main.cc \
-- download_main.h \
-- download_wrapper.cc \
-- download_wrapper.h
--
--AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
-diff --git a/src/net/Makefile.am b/src/net/Makefile.am
-deleted file mode 100644
-index e3a8c7e1..00000000
---- a/src/net/Makefile.am
-+++ /dev/null
-@@ -1,30 +0,0 @@
--noinst_LTLIBRARIES = libsub_net.la
--
--libsub_net_la_SOURCES = \
-- address_list.cc \
-- address_list.h \
-- data_buffer.h \
-- local_addr.cc \
-- local_addr.h \
-- listen.cc \
-- listen.h \
-- protocol_buffer.h \
-- socket_base.cc \
-- socket_base.h \
-- socket_datagram.cc \
-- socket_datagram.h \
-- socket_fd.cc \
-- socket_fd.h \
-- socket_listen.cc \
-- socket_listen.h \
-- socket_set.cc \
-- socket_set.h \
-- socket_stream.cc \
-- socket_stream.h \
-- throttle_internal.cc \
-- throttle_internal.h \
-- throttle_list.cc \
-- throttle_list.h \
-- throttle_node.h
--
--AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
-diff --git a/src/protocol/Makefile.am b/src/protocol/Makefile.am
-deleted file mode 100644
-index 2e9aba7a..00000000
---- a/src/protocol/Makefile.am
-+++ /dev/null
-@@ -1,28 +0,0 @@
--noinst_LTLIBRARIES = libsub_protocol.la
--
--libsub_protocol_la_SOURCES = \
-- encryption_info.h \
-- extensions.cc \
-- extensions.h \
-- handshake.cc \
-- handshake.h \
-- handshake_encryption.cc \
-- handshake_encryption.h \
-- handshake_manager.cc \
-- handshake_manager.h \
-- initial_seed.cc \
-- initial_seed.h \
-- peer_chunks.h \
-- peer_connection_base.cc \
-- peer_connection_base.h \
-- peer_connection_leech.cc \
-- peer_connection_leech.h \
-- peer_connection_metadata.cc \
-- peer_connection_metadata.h \
-- peer_factory.cc \
-- peer_factory.h \
-- protocol_base.h \
-- request_list.cc \
-- request_list.h
--
--AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
-diff --git a/src/torrent/Makefile.am b/src/torrent/Makefile.am
-index 8cd26ce7..30157b95 100644
---- a/src/torrent/Makefile.am
-+++ b/src/torrent/Makefile.am
-@@ -1,13 +1,89 @@
--SUBDIRS = \
-- data \
-- download \
-- net \
-- peer \
-- utils
-+noinst_LTLIBRARIES = libtorrent_torrent.la
-
--noinst_LTLIBRARIES = libsub_torrent.la
--
--libsub_torrent_la_SOURCES = \
-+libtorrent_torrent_la_SOURCES = \
-+ data/block.cc \
-+ data/block.h \
-+ data/block_failed.h \
-+ data/block_list.cc \
-+ data/block_list.h \
-+ data/block_transfer.h \
-+ data/chunk_utils.cc \
-+ data/chunk_utils.h \
-+ data/download_data.cc \
-+ data/download_data.h \
-+ data/file.cc \
-+ data/file.h \
-+ data/file_list.cc \
-+ data/file_list.h \
-+ data/file_list_iterator.cc \
-+ data/file_list_iterator.h \
-+ data/file_manager.cc \
-+ data/file_manager.h \
-+ data/file_utils.cc \
-+ data/file_utils.h \
-+ data/piece.h \
-+ data/transfer_list.cc \
-+ data/transfer_list.h \
-+\
-+ download/choke_group.cc \
-+ download/choke_group.h \
-+ download/choke_queue.cc \
-+ download/choke_queue.h \
-+ download/download_manager.cc \
-+ download/download_manager.h \
-+ download/group_entry.h \
-+ download/resource_manager.cc \
-+ download/resource_manager.h \
-+\
-+ net/address_info.cc \
-+ net/address_info.h \
-+ net/fd.cc \
-+ net/fd.h \
-+ net/socket_address.cc \
-+ net/socket_address.h \
-+ net/socket_address_key.cc \
-+ net/socket_address_key.h \
-+ net/socket_event.cc \
-+ net/socket_event.h \
-+ net/types.h \
-+\
-+ peer/choke_status.h \
-+ peer/client_info.cc \
-+ peer/client_info.h \
-+ peer/client_list.cc \
-+ peer/client_list.h \
-+ peer/connection_list.cc \
-+ peer/connection_list.h \
-+ peer/peer.cc \
-+ peer/peer.h \
-+ peer/peer_info.cc \
-+ peer/peer_info.h \
-+ peer/peer_list.cc \
-+ peer/peer_list.h \
-+\
-+ utils/directory_events.cc \
-+ utils/directory_events.h \
-+ utils/extents.h \
-+ utils/log.cc \
-+ utils/log.h \
-+ utils/log_buffer.cc \
-+ utils/log_buffer.h \
-+ utils/option_strings.cc \
-+ utils/option_strings.h \
-+ utils/random.cc \
-+ utils/random.h \
-+ utils/ranges.h \
-+ utils/resume.cc \
-+ utils/resume.h \
-+ utils/signal_bitfield.cc \
-+ utils/signal_bitfield.h \
-+ utils/thread_base.cc \
-+ utils/thread_base.h \
-+ utils/thread_interrupt.cc \
-+ utils/thread_interrupt.h \
-+ utils/uri_parser.cc \
-+ utils/uri_parser.h \
-+\
- bitfield.cc \
- bitfield.h \
- chunk_manager.cc \
-@@ -61,8 +137,64 @@ libsub_torrent_la_SOURCES = \
-
- AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
-
--libtorrentincludedir = $(includedir)/torrent
--libtorrentinclude_HEADERS = \
-+libtorrent_torrent_data_includedir = $(includedir)/torrent/data
-+libtorrent_torrent_data_include_HEADERS = \
-+ data/block.h \
-+ data/block_list.h \
-+ data/block_transfer.h \
-+ data/chunk_utils.h \
-+ data/download_data.h \
-+ data/file.h \
-+ data/file_list.h \
-+ data/file_list_iterator.h \
-+ data/file_manager.h \
-+ data/file_utils.h \
-+ data/piece.h \
-+ data/transfer_list.h
-+
-+libtorrent_torrent_download_includedir = $(includedir)/torrent/download
-+libtorrent_torrent_download_include_HEADERS = \
-+ download/choke_group.h \
-+ download/choke_queue.h \
-+ download/download_manager.h \
-+ download/group_entry.h \
-+ download/resource_manager.h
-+
-+libtorrent_torrent_net_includedir = $(includedir)/torrent/net
-+libtorrent_torrent_net_include_HEADERS = \
-+ net/address_info.h \
-+ net/fd.h \
-+ net/socket_address.h \
-+ net/socket_address_key.h \
-+ net/socket_event.h \
-+ net/types.h
-+
-+libtorrent_torrent_peer_includedir = $(includedir)/torrent/peer
-+libtorrent_torrent_peer_include_HEADERS = \
-+ peer/choke_status.h \
-+ peer/client_info.h \
-+ peer/client_list.h \
-+ peer/connection_list.h \
-+ peer/peer.h \
-+ peer/peer_info.h \
-+ peer/peer_list.h
-+
-+libtorrent_torrent_utils_includedir = $(includedir)/torrent/utils
-+libtorrent_torrent_utils_include_HEADERS = \
-+ utils/directory_events.h \
-+ utils/extents.h \
-+ utils/log.h \
-+ utils/log_buffer.h \
-+ utils/option_strings.h \
-+ utils/ranges.h \
-+ utils/resume.h \
-+ utils/signal_bitfield.h \
-+ utils/thread_base.h \
-+ utils/thread_interrupt.h \
-+ utils/uri_parser.h
-+
-+libtorrent_torrent_includedir = $(includedir)/torrent
-+libtorrent_torrent_include_HEADERS = \
- bitfield.h \
- chunk_manager.h \
- common.h \
-diff --git a/src/torrent/download/Makefile.am b/src/torrent/download/Makefile.am
-deleted file mode 100644
-index f92c7aa4..00000000
---- a/src/torrent/download/Makefile.am
-+++ /dev/null
-@@ -1,22 +0,0 @@
--noinst_LTLIBRARIES = libsub_torrentdownload.la
--
--libsub_torrentdownload_la_SOURCES = \
-- choke_group.cc \
-- choke_group.h \
-- choke_queue.cc \
-- choke_queue.h \
-- download_manager.cc \
-- download_manager.h \
-- group_entry.h \
-- resource_manager.cc \
-- resource_manager.h
--
--AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../.. -I$(top_srcdir)
--
--libtorrentincludedir = $(includedir)/torrent/download
--libtorrentinclude_HEADERS = \
-- choke_group.h \
-- choke_queue.h \
-- download_manager.h \
-- group_entry.h \
-- resource_manager.h
-diff --git a/src/torrent/net/Makefile.am b/src/torrent/net/Makefile.am
-deleted file mode 100644
-index 35dd4774..00000000
---- a/src/torrent/net/Makefile.am
-+++ /dev/null
-@@ -1,25 +0,0 @@
--noinst_LTLIBRARIES = libsub_torrentnet.la
--
--libsub_torrentnet_la_SOURCES = \
-- address_info.cc \
-- address_info.h \
-- fd.cc \
-- fd.h \
-- socket_address.cc \
-- socket_address.h \
-- socket_address_key.cc \
-- socket_address_key.h \
-- socket_event.cc \
-- socket_event.h \
-- types.h
--
--AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../.. -I$(top_srcdir)
--
--libtorrentincludedir = $(includedir)/torrent/net
--libtorrentinclude_HEADERS = \
-- address_info.h \
-- fd.h \
-- socket_address.h \
-- socket_address_key.h \
-- socket_event.h \
-- types.h
-diff --git a/src/torrent/peer/Makefile.am b/src/torrent/peer/Makefile.am
-deleted file mode 100644
-index 1324e88a..00000000
---- a/src/torrent/peer/Makefile.am
-+++ /dev/null
-@@ -1,28 +0,0 @@
--noinst_LTLIBRARIES = libsub_torrentpeer.la
--
--libsub_torrentpeer_la_SOURCES = \
-- choke_status.h \
-- client_info.cc \
-- client_info.h \
-- client_list.cc \
-- client_list.h \
-- connection_list.cc \
-- connection_list.h \
-- peer.cc \
-- peer.h \
-- peer_info.cc \
-- peer_info.h \
-- peer_list.cc \
-- peer_list.h
--
--AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../.. -I$(top_srcdir)
--
--libtorrentincludedir = $(includedir)/torrent/peer
--libtorrentinclude_HEADERS = \
-- choke_status.h \
-- client_info.h \
-- client_list.h \
-- connection_list.h \
-- peer.h \
-- peer_info.h \
-- peer_list.h
-diff --git a/src/torrent/utils/Makefile.am b/src/torrent/utils/Makefile.am
-deleted file mode 100644
-index a48786c6..00000000
---- a/src/torrent/utils/Makefile.am
-+++ /dev/null
-@@ -1,41 +0,0 @@
--noinst_LTLIBRARIES = libsub_torrentutils.la
--
--libsub_torrentutils_la_SOURCES = \
-- directory_events.cc \
-- directory_events.h \
-- extents.h \
-- log.cc \
-- log.h \
-- log_buffer.cc \
-- log_buffer.h \
-- option_strings.cc \
-- option_strings.h \
-- random.cc \
-- random.h \
-- ranges.h \
-- resume.cc \
-- resume.h \
-- signal_bitfield.cc \
-- signal_bitfield.h \
-- thread_base.cc \
-- thread_base.h \
-- thread_interrupt.cc \
-- thread_interrupt.h \
-- uri_parser.cc \
-- uri_parser.h
--
--AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../.. -I$(top_srcdir)
--
--libtorrentincludedir = $(includedir)/torrent/utils
--libtorrentinclude_HEADERS = \
-- directory_events.h \
-- extents.h \
-- log.h \
-- log_buffer.h \
-- option_strings.h \
-- ranges.h \
-- resume.h \
-- signal_bitfield.h \
-- thread_base.h \
-- thread_interrupt.h \
-- uri_parser.h
-diff --git a/src/tracker/Makefile.am b/src/tracker/Makefile.am
-deleted file mode 100644
-index 2f1ae5cf..00000000
---- a/src/tracker/Makefile.am
-+++ /dev/null
-@@ -1,11 +0,0 @@
--noinst_LTLIBRARIES = libsub_tracker.la
--
--libsub_tracker_la_SOURCES = \
-- tracker_dht.cc \
-- tracker_dht.h \
-- tracker_http.cc \
-- tracker_http.h \
-- tracker_udp.cc \
-- tracker_udp.h
--
--AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
-diff --git a/src/utils/Makefile.am b/src/utils/Makefile.am
-deleted file mode 100644
-index 27ce359b..00000000
---- a/src/utils/Makefile.am
-+++ /dev/null
-@@ -1,14 +0,0 @@
--noinst_LTLIBRARIES = libsub_utils.la
--
--libsub_utils_la_SOURCES = \
-- diffie_hellman.cc \
-- diffie_hellman.h \
-- instrumentation.cc \
-- instrumentation.h \
-- rc4.h \
-- sha1.h \
-- sha_fast.cc \
-- sha_fast.h \
-- queue_buckets.h
--
--AM_CPPFLAGS = -I$(srcdir) -I$(srcdir)/.. -I$(top_srcdir)
-diff --git a/test/Makefile.am b/test/Makefile.am
-index 23b260e4..8b0291bb 100644
---- a/test/Makefile.am
-+++ b/test/Makefile.am
-@@ -1,25 +1,68 @@
--SUBDIRS = torrent/net net
--
--TESTS = LibTorrentTest
--AUTOMAKE_OPTIONS = subdir-objects
-+TESTS = \
-+ LibTorrent_Test_Torrent_Net \
-+ LibTorrent_Test_Net \
-+ LibTorrent_Test
-
- check_PROGRAMS = $(TESTS)
--LibTorrentTest_LDADD = \
-+
-+LibTorrent_Test_LDADD = \
- ../src/libtorrent.la \
-- ../src/torrent/libsub_torrent.la \
-- ../src/torrent/data/libsub_torrentdata.la \
-- ../src/torrent/download/libsub_torrentdownload.la \
-- ../src/torrent/peer/libsub_torrentpeer.la \
-- ../src/data/libsub_data.la \
-- ../src/dht/libsub_dht.la \
-- ../src/net/libsub_net.la \
-- ../src/protocol/libsub_protocol.la \
-- ../src/download/libsub_download.la \
-- ../src/tracker/libsub_tracker.la \
-- ../src/utils/libsub_utils.la \
-- ../src/torrent/utils/libsub_torrentutils.la
-+ ../src/libtorrent_other.la \
-+ ../src/torrent/libtorrent_torrent.la
-+
-+LibTorrent_Test_Net_LDADD = $(LibTorrent_Test_LDADD)
-+LibTorrent_Test_Torrent_Net_LDADD = $(LibTorrent_Test_LDADD)
-+
-+# LibTorrent_Test_SOURCES = \
-+# helpers/expect_fd.h \
-+# helpers/expect_utils.h \
-+# helpers/mock_compare.h \
-+# helpers/mock_function.cc \
-+# helpers/mock_function.h \
-+# helpers/network.h \
-+# helpers/progress_listener.cc \
-+# helpers/progress_listener.h \
-+# helpers/test_fixture.cc \
-+# helpers/test_fixture.h
-+
-+LibTorrent_Test_Torrent_Net_SOURCES = \
-+ main.cc \
-+ helpers/expect_fd.h \
-+ helpers/expect_utils.h \
-+ helpers/mock_compare.h \
-+ helpers/mock_function.cc \
-+ helpers/mock_function.h \
-+ helpers/network.h \
-+ helpers/progress_listener.cc \
-+ helpers/progress_listener.h \
-+ helpers/test_fixture.cc \
-+ helpers/test_fixture.h \
-+ \
-+ torrent/net/test_address_info.cc \
-+ torrent/net/test_address_info.h \
-+ torrent/net/test_fd.cc \
-+ torrent/net/test_fd.h \
-+ torrent/net/test_socket_address.cc \
-+ torrent/net/test_socket_address.h
-
--LibTorrentTest_SOURCES = \
-+LibTorrent_Test_Net_SOURCES = \
-+ main.cc \
-+ helpers/expect_fd.h \
-+ helpers/expect_utils.h \
-+ helpers/mock_compare.h \
-+ helpers/mock_function.cc \
-+ helpers/mock_function.h \
-+ helpers/network.h \
-+ helpers/progress_listener.cc \
-+ helpers/progress_listener.h \
-+ helpers/test_fixture.cc \
-+ helpers/test_fixture.h \
-+ \
-+ net/test_socket_listen.cc \
-+ net/test_socket_listen.h
-+
-+LibTorrent_Test_SOURCES = \
-+ main.cc \
- helpers/expect_fd.h \
- helpers/expect_utils.h \
- helpers/mock_compare.h \
-@@ -87,12 +130,15 @@ LibTorrentTest_SOURCES = \
- torrent/tracker_list_features_test.h \
- torrent/tracker_timeout_test.cc \
- torrent/tracker_timeout_test.h \
-- tracker/tracker_http_test.cc \
-- tracker/tracker_http_test.h \
- \
-- main.cc
-+ tracker/tracker_http_test.cc \
-+ tracker/tracker_http_test.h
-
--LibTorrentTest_CXXFLAGS = $(CPPUNIT_CFLAGS)
--LibTorrentTest_LDFLAGS = $(CPPUNIT_LIBS) -ldl
-+LibTorrent_Test_Torrent_Net_CXXFLAGS = $(CPPUNIT_CFLAGS)
-+LibTorrent_Test_Torrent_Net_LDFLAGS = $(CPPUNIT_LIBS) -ldl
-+LibTorrent_Test_Net_CXXFLAGS = $(CPPUNIT_CFLAGS)
-+LibTorrent_Test_Net_LDFLAGS = $(CPPUNIT_LIBS) -ldl
-+LibTorrent_Test_CXXFLAGS = $(CPPUNIT_CFLAGS)
-+LibTorrent_Test_LDFLAGS = $(CPPUNIT_LIBS) -ldl
-
- AM_CPPFLAGS = -I$(srcdir) -I$(top_srcdir) -I$(top_srcdir)/src
deleted file mode 100644
@@ -1,2710 +0,0 @@
-From 9cdb950c0db2bad1a4d85b48f06419e2920aa114 Mon Sep 17 00:00:00 2001
-From: Jari Sundell <sundell.software@gmail.com>
-Date: Fri, 20 Dec 2019 00:37:38 +0900
-Subject: [PATCH] Refactor make process. (#207)
-
----
- configure.ac | 3 +-
- src/Makefile.am | 3 +-
- src/manager.h | 36 ---
- src/thread_disk.h | 51 +---
- src/torrent/utils/thread_base.cc | 36 ---
- src/torrent/utils/thread_base.h | 48 +---
- test/Makefile.am | 140 +++++------
- ...{chunk_list_test.cc => test_chunk_list.cc} | 16 +-
- .../{chunk_list_test.h => test_chunk_list.h} | 13 +-
- ...queue_test.cc => test_hash_check_queue.cc} | 33 ++-
- ...k_queue_test.h => test_hash_check_queue.h} | 22 +-
- ...{hash_queue_test.cc => test_hash_queue.cc} | 66 +++---
- .../{hash_queue_test.h => test_hash_queue.h} | 11 +-
- test/helpers/progress_listener.cc | 4 +-
- test/helpers/test_fixture.h | 28 +--
- test/helpers/test_thread.cc | 71 ++++++
- test/helpers/test_thread.h | 59 +++++
- test/helpers/test_utils.h | 16 ++
- test/helpers/utils.h | 120 +++++-----
- test/main.cc | 4 +-
- test/torrent/{http_test.cc => test_http.cc} | 17 +-
- test/torrent/{http_test.h => test_http.h} | 11 +-
- test/torrent/utils/option_strings_test.h | 17 --
- test/torrent/utils/signal_bitfield_test.h | 23 --
- test/torrent/utils/test_extents.cc | 63 ++---
- test/torrent/utils/test_extents.h | 9 +-
- .../utils/{log_test.cc => test_log.cc} | 26 +-
- test/torrent/utils/{log_test.h => test_log.h} | 8 +-
- test/torrent/utils/test_log_buffer.cc | 11 +-
- test/torrent/utils/test_log_buffer.h | 5 -
- ...strings_test.cc => test_option_strings.cc} | 29 +--
- test/torrent/utils/test_option_strings.h | 10 +
- test/torrent/utils/test_queue_buckets.cc | 12 +-
- test/torrent/utils/test_queue_buckets.h | 11 +-
- ...tfield_test.cc => test_signal_bitfield.cc} | 31 ++-
- test/torrent/utils/test_signal_bitfield.h | 22 ++
- test/torrent/utils/test_thread_base.cc | 169 +++++++++++++
- test/torrent/utils/test_thread_base.h | 25 ++
- test/torrent/utils/test_uri_parser.cc | 31 +--
- test/torrent/utils/test_uri_parser.h | 11 +-
- test/torrent/utils/thread_base_test.cc | 224 ------------------
- test/torrent/utils/thread_base_test.h | 86 -------
- test/tracker/test_tracker_http.cc | 11 +
- test/tracker/test_tracker_http.h | 12 +
- test/tracker/tracker_http_test.cc | 17 --
- test/tracker/tracker_http_test.h | 18 --
- 46 files changed, 735 insertions(+), 954 deletions(-)
- rename test/data/{chunk_list_test.cc => test_chunk_list.cc} (93%)
- rename test/data/{chunk_list_test.h => test_chunk_list.h} (88%)
- rename test/data/{hash_check_queue_test.cc => test_hash_check_queue.cc} (92%)
- rename test/data/{hash_check_queue_test.h => test_hash_check_queue.h} (63%)
- rename test/data/{hash_queue_test.cc => test_hash_queue.cc} (82%)
- rename test/data/{hash_queue_test.h => test_hash_queue.h} (58%)
- create mode 100755 test/helpers/test_thread.cc
- create mode 100755 test/helpers/test_thread.h
- create mode 100644 test/helpers/test_utils.h
- rename test/torrent/{http_test.cc => test_http.cc} (94%)
- rename test/torrent/{http_test.h => test_http.h} (63%)
- delete mode 100644 test/torrent/utils/option_strings_test.h
- delete mode 100644 test/torrent/utils/signal_bitfield_test.h
- rename test/torrent/utils/{log_test.cc => test_log.cc} (92%)
- rename test/torrent/utils/{log_test.h => test_log.h} (71%)
- rename test/torrent/utils/{option_strings_test.cc => test_option_strings.cc} (65%)
- create mode 100644 test/torrent/utils/test_option_strings.h
- rename test/torrent/utils/{signal_bitfield_test.cc => test_signal_bitfield.cc} (85%)
- create mode 100644 test/torrent/utils/test_signal_bitfield.h
- create mode 100644 test/torrent/utils/test_thread_base.cc
- create mode 100644 test/torrent/utils/test_thread_base.h
- delete mode 100644 test/torrent/utils/thread_base_test.cc
- delete mode 100644 test/torrent/utils/thread_base_test.h
- create mode 100644 test/tracker/test_tracker_http.cc
- create mode 100644 test/tracker/test_tracker_http.h
- delete mode 100644 test/tracker/tracker_http_test.cc
- delete mode 100644 test/tracker/tracker_http_test.h
-
-diff --git a/configure.ac b/configure.ac
-index e83710cc..88a46edd 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -21,6 +21,7 @@ AM_INIT_AUTOMAKE([serial-tests subdir-objects])
- AC_CONFIG_HEADERS(config.h)
-
- AC_PROG_CXX
-+AC_SYS_LARGEFILE
-
- AC_C_BIGENDIAN(
- AC_DEFINE(IS_BIG_ENDIAN, 1, Big endian),
-@@ -37,8 +38,6 @@ RAK_DISABLE_BACKTRACE
-
- RAK_CHECK_CXX11
-
--AC_SYS_LARGEFILE
--
- TORRENT_ENABLE_ALIGNED
- TORRENT_ENABLE_INTERRUPT_SOCKET
-
-diff --git a/src/Makefile.am b/src/Makefile.am
-index e96bd74b..95e6a7ae 100644
---- a/src/Makefile.am
-+++ b/src/Makefile.am
-@@ -1,7 +1,8 @@
- SUBDIRS = torrent
-
- lib_LTLIBRARIES = libtorrent.la
--noinst_LTLIBRARIES = libtorrent_other.la
-+noinst_LTLIBRARIES = \
-+ libtorrent_other.la
-
- libtorrent_la_LDFLAGS = -version-info $(LIBTORRENT_INTERFACE_VERSION_INFO)
- libtorrent_la_LIBADD = \
-diff --git a/src/manager.h b/src/manager.h
-index 1db81e9b..1ada9567 100644
---- a/src/manager.h
-+++ b/src/manager.h
-@@ -1,39 +1,3 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #ifndef LIBTORRENT_MANAGER_H
- #define LIBTORRENT_MANAGER_H
-
-diff --git a/src/thread_disk.h b/src/thread_disk.h
-index fa1fcb7e..7b378915 100644
---- a/src/thread_disk.h
-+++ b/src/thread_disk.h
-@@ -1,39 +1,3 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #ifndef LIBTORRENT_THREAD_DISK_H
- #define LIBTORRENT_THREAD_DISK_H
-
-@@ -42,19 +6,18 @@
-
- namespace torrent {
-
--class thread_disk : public thread_base {
-+class LIBTORRENT_EXPORT thread_disk : public thread_base {
- public:
-- const char* name() const { return "rtorrent disk"; }
--
-- virtual void init_thread();
-+ const char* name() const { return "rtorrent disk"; }
-+ HashCheckQueue* hash_queue() { return &m_hash_queue; }
-
-- HashCheckQueue* hash_queue() { return &m_hash_queue; }
-+ virtual void init_thread();
-
- protected:
-- virtual void call_events();
-- virtual int64_t next_timeout_usec();
-+ virtual void call_events();
-+ virtual int64_t next_timeout_usec();
-
-- HashCheckQueue m_hash_queue;
-+ HashCheckQueue m_hash_queue;
- };
-
- }
-diff --git a/src/torrent/utils/thread_base.cc b/src/torrent/utils/thread_base.cc
-index 778e4c38..99d6355d 100644
---- a/src/torrent/utils/thread_base.cc
-+++ b/src/torrent/utils/thread_base.cc
-@@ -1,39 +1,3 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #include "config.h"
-
- #include <cstring>
-diff --git a/src/torrent/utils/thread_base.h b/src/torrent/utils/thread_base.h
-index b92a98ba..bead9659 100644
---- a/src/torrent/utils/thread_base.h
-+++ b/src/torrent/utils/thread_base.h
-@@ -1,48 +1,12 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #ifndef LIBTORRENT_UTILS_THREAD_BASE_H
- #define LIBTORRENT_UTILS_THREAD_BASE_H
-
--#include <functional>
--#include <pthread.h>
--#include <sys/types.h>
-+#import <functional>
-+#import <pthread.h>
-+#import <sys/types.h>
-
--#include <torrent/common.h>
--#include <torrent/utils/signal_bitfield.h>
-+#import <torrent/common.h>
-+#import <torrent/utils/signal_bitfield.h>
-
- namespace torrent {
-
-@@ -54,7 +18,7 @@ public:
- typedef void* (*pthread_func)(void*);
- typedef std::function<void ()> slot_void;
- typedef std::function<uint64_t ()> slot_timer;
-- typedef class signal_bitfield signal_type;
-+ typedef class signal_bitfield signal_type;
-
- enum state_type {
- STATE_UNKNOWN,
-diff --git a/test/Makefile.am b/test/Makefile.am
-index 8b0291bb..cb00dce3 100644
---- a/test/Makefile.am
-+++ b/test/Makefile.am
-@@ -1,6 +1,10 @@
- TESTS = \
- LibTorrent_Test_Torrent_Net \
-+ LibTorrent_Test_Torrent_Utils \
-+ LibTorrent_Test_Torrent \
-+ LibTorrent_Test_Data \
- LibTorrent_Test_Net \
-+ LibTorrent_Test_Tracker \
- LibTorrent_Test
-
- check_PROGRAMS = $(TESTS)
-@@ -10,22 +14,14 @@ LibTorrent_Test_LDADD = \
- ../src/libtorrent_other.la \
- ../src/torrent/libtorrent_torrent.la
-
--LibTorrent_Test_Net_LDADD = $(LibTorrent_Test_LDADD)
- LibTorrent_Test_Torrent_Net_LDADD = $(LibTorrent_Test_LDADD)
-+LibTorrent_Test_Torrent_Utils_LDADD = $(LibTorrent_Test_LDADD)
-+LibTorrent_Test_Torrent_LDADD = $(LibTorrent_Test_LDADD)
-+LibTorrent_Test_Data_LDADD = $(LibTorrent_Test_LDADD)
-+LibTorrent_Test_Net_LDADD = $(LibTorrent_Test_LDADD)
-+LibTorrent_Test_Tracker_LDADD = $(LibTorrent_Test_LDADD)
-
--# LibTorrent_Test_SOURCES = \
--# helpers/expect_fd.h \
--# helpers/expect_utils.h \
--# helpers/mock_compare.h \
--# helpers/mock_function.cc \
--# helpers/mock_function.h \
--# helpers/network.h \
--# helpers/progress_listener.cc \
--# helpers/progress_listener.h \
--# helpers/test_fixture.cc \
--# helpers/test_fixture.h
--
--LibTorrent_Test_Torrent_Net_SOURCES = \
-+LibTorrent_Test_Common = \
- main.cc \
- helpers/expect_fd.h \
- helpers/expect_utils.h \
-@@ -37,7 +33,10 @@ LibTorrent_Test_Torrent_Net_SOURCES = \
- helpers/progress_listener.h \
- helpers/test_fixture.cc \
- helpers/test_fixture.h \
-- \
-+ helpers/test_thread.cc \
-+ helpers/test_thread.h
-+
-+LibTorrent_Test_Torrent_Net_SOURCES = $(LibTorrent_Test_Common) \
- torrent/net/test_address_info.cc \
- torrent/net/test_address_info.h \
- torrent/net/test_fd.cc \
-@@ -45,71 +44,28 @@ LibTorrent_Test_Torrent_Net_SOURCES = \
- torrent/net/test_socket_address.cc \
- torrent/net/test_socket_address.h
-
--LibTorrent_Test_Net_SOURCES = \
-- main.cc \
-- helpers/expect_fd.h \
-- helpers/expect_utils.h \
-- helpers/mock_compare.h \
-- helpers/mock_function.cc \
-- helpers/mock_function.h \
-- helpers/network.h \
-- helpers/progress_listener.cc \
-- helpers/progress_listener.h \
-- helpers/test_fixture.cc \
-- helpers/test_fixture.h \
-- \
-- net/test_socket_listen.cc \
-- net/test_socket_listen.h
--
--LibTorrent_Test_SOURCES = \
-- main.cc \
-- helpers/expect_fd.h \
-- helpers/expect_utils.h \
-- helpers/mock_compare.h \
-- helpers/mock_function.cc \
-- helpers/mock_function.h \
-- helpers/network.h \
-- helpers/progress_listener.cc \
-- helpers/progress_listener.h \
-- helpers/test_fixture.cc \
-- helpers/test_fixture.h \
-- \
-- ../src/thread_disk.cc \
-- ../src/thread_disk.h \
-- \
-- rak/allocators_test.cc \
-- rak/allocators_test.h \
-- rak/ranges_test.cc \
-- rak/ranges_test.h \
-- data/chunk_list_test.cc \
-- data/chunk_list_test.h \
-- data/hash_check_queue_test.cc \
-- data/hash_check_queue_test.h \
-- data/hash_queue_test.cc \
-- data/hash_queue_test.h \
-- \
-- protocol/test_request_list.cc \
-- protocol/test_request_list.h \
-- \
-- torrent/utils/log_test.cc \
-- torrent/utils/log_test.h \
-- torrent/utils/option_strings_test.cc \
-- torrent/utils/option_strings_test.h \
-+LibTorrent_Test_Torrent_Utils_SOURCES = $(LibTorrent_Test_Common) \
- torrent/utils/test_extents.cc \
- torrent/utils/test_extents.h \
-+ torrent/utils/test_log.cc \
-+ torrent/utils/test_log.h \
- torrent/utils/test_log_buffer.cc \
- torrent/utils/test_log_buffer.h \
-+ torrent/utils/test_option_strings.cc \
-+ torrent/utils/test_option_strings.h \
- torrent/utils/test_queue_buckets.cc \
- torrent/utils/test_queue_buckets.h \
-+ torrent/utils/test_signal_bitfield.cc \
-+ torrent/utils/test_signal_bitfield.h \
-+ torrent/utils/test_thread_base.cc \
-+ torrent/utils/test_thread_base.h \
- torrent/utils/test_uri_parser.cc \
-- torrent/utils/test_uri_parser.h \
-- torrent/utils/signal_bitfield_test.cc \
-- torrent/utils/signal_bitfield_test.h \
-- torrent/utils/thread_base_test.cc \
-- torrent/utils/thread_base_test.h \
-+ torrent/utils/test_uri_parser.h
-+
-+LibTorrent_Test_Torrent_SOURCES = $(LibTorrent_Test_Common) \
-+ torrent/test_http.cc \
-+ torrent/test_http.h \
- \
-- torrent/http_test.cc \
-- torrent/http_test.h \
- torrent/object_test.cc \
- torrent/object_test.h \
- torrent/object_test_utils.cc \
-@@ -129,15 +85,49 @@ LibTorrent_Test_SOURCES = \
- torrent/tracker_list_features_test.cc \
- torrent/tracker_list_features_test.h \
- torrent/tracker_timeout_test.cc \
-- torrent/tracker_timeout_test.h \
-+ torrent/tracker_timeout_test.h
-+
-+LibTorrent_Test_Data_SOURCES = $(LibTorrent_Test_Common) \
-+ data/test_chunk_list.cc \
-+ data/test_chunk_list.h \
-+ data/test_hash_check_queue.cc \
-+ data/test_hash_check_queue.h \
-+ data/test_hash_queue.cc \
-+ data/test_hash_queue.h
-+
-+LibTorrent_Test_Net_SOURCES = $(LibTorrent_Test_Common) \
-+ net/test_socket_listen.cc \
-+ net/test_socket_listen.h
-+
-+LibTorrent_Test_Tracker_SOURCES = $(LibTorrent_Test_Common) \
-+ tracker/test_tracker_http.cc \
-+ tracker/test_tracker_http.h
-+
-+LibTorrent_Test_SOURCES = $(LibTorrent_Test_Common) \
-+ \
-+ ../src/thread_disk.cc \
-+ ../src/thread_disk.h \
- \
-- tracker/tracker_http_test.cc \
-- tracker/tracker_http_test.h
-+ rak/allocators_test.cc \
-+ rak/allocators_test.h \
-+ rak/ranges_test.cc \
-+ rak/ranges_test.h \
-+ \
-+ protocol/test_request_list.cc \
-+ protocol/test_request_list.h
-
- LibTorrent_Test_Torrent_Net_CXXFLAGS = $(CPPUNIT_CFLAGS)
- LibTorrent_Test_Torrent_Net_LDFLAGS = $(CPPUNIT_LIBS) -ldl
-+LibTorrent_Test_Torrent_Utils_CXXFLAGS = $(CPPUNIT_CFLAGS)
-+LibTorrent_Test_Torrent_Utils_LDFLAGS = $(CPPUNIT_LIBS) -ldl
-+LibTorrent_Test_Torrent_CXXFLAGS = $(CPPUNIT_CFLAGS)
-+LibTorrent_Test_Torrent_LDFLAGS = $(CPPUNIT_LIBS) -ldl
-+LibTorrent_Test_Data_CXXFLAGS = $(CPPUNIT_CFLAGS)
-+LibTorrent_Test_Data_LDFLAGS = $(CPPUNIT_LIBS) -ldl
- LibTorrent_Test_Net_CXXFLAGS = $(CPPUNIT_CFLAGS)
- LibTorrent_Test_Net_LDFLAGS = $(CPPUNIT_LIBS) -ldl
-+LibTorrent_Test_Tracker_CXXFLAGS = $(CPPUNIT_CFLAGS)
-+LibTorrent_Test_Tracker_LDFLAGS = $(CPPUNIT_LIBS) -ldl
- LibTorrent_Test_CXXFLAGS = $(CPPUNIT_CFLAGS)
- LibTorrent_Test_LDFLAGS = $(CPPUNIT_LIBS) -ldl
-
-diff --git a/test/data/chunk_list_test.cc b/test/data/test_chunk_list.cc
-similarity index 93%
-rename from test/data/chunk_list_test.cc
-rename to test/data/test_chunk_list.cc
-index 28647db2..18de597e 100644
---- a/test/data/chunk_list_test.cc
-+++ b/test/data/test_chunk_list.cc
-@@ -1,11 +1,11 @@
--#include "config.h"
-+#import "config.h"
-
--#include "chunk_list_test.h"
-+#import "test_chunk_list.h"
-
--#include "torrent/chunk_manager.h"
--#include "torrent/exceptions.h"
-+#import "torrent/chunk_manager.h"
-+#import "torrent/exceptions.h"
-
--CPPUNIT_TEST_SUITE_REGISTRATION(ChunkListTest);
-+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_chunk_list, "data");
-
- torrent::Chunk*
- func_create_chunk(uint32_t index, int prot_flags) {
-@@ -36,7 +36,7 @@ func_storage_error(torrent::ChunkList* chunk_list, const std::string& message) {
- }
-
- void
--ChunkListTest::test_basic() {
-+test_chunk_list::test_basic() {
- torrent::ChunkManager chunk_manager;
- torrent::ChunkList chunk_list;
-
-@@ -55,7 +55,7 @@ ChunkListTest::test_basic() {
- }
-
- void
--ChunkListTest::test_get_release() {
-+test_chunk_list::test_get_release() {
- SETUP_CHUNK_LIST();
-
- CPPUNIT_ASSERT(!(*chunk_list)[0].is_valid());
-@@ -112,7 +112,7 @@ ChunkListTest::test_get_release() {
-
- // Make sure we can't go into writable when blocking, etc.
- void
--ChunkListTest::test_blocking() {
-+test_chunk_list::test_blocking() {
- SETUP_CHUNK_LIST();
-
- torrent::ChunkHandle handle_0_ro = chunk_list->get(0, torrent::ChunkList::get_blocking);
-diff --git a/test/data/chunk_list_test.h b/test/data/test_chunk_list.h
-similarity index 88%
-rename from test/data/chunk_list_test.h
-rename to test/data/test_chunk_list.h
-index 3979982f..85d1f77b 100644
---- a/test/data/chunk_list_test.h
-+++ b/test/data/test_chunk_list.h
-@@ -1,23 +1,22 @@
--#include <cppunit/extensions/HelperMacros.h>
-+#import "helpers/test_fixture.h"
-
--#include "data/chunk_list.h"
-+class test_chunk_list : public test_fixture {
-+ CPPUNIT_TEST_SUITE(test_chunk_list);
-
--class ChunkListTest : public CppUnit::TestFixture {
-- CPPUNIT_TEST_SUITE(ChunkListTest);
- CPPUNIT_TEST(test_basic);
- CPPUNIT_TEST(test_get_release);
- CPPUNIT_TEST(test_blocking);
-+
- CPPUNIT_TEST_SUITE_END();
-
- public:
-- void setUp() {}
-- void tearDown() {}
--
- void test_basic();
- void test_get_release();
- void test_blocking();
- };
-
-+#include "data/chunk_list.h"
-+
- torrent::Chunk* func_create_chunk(uint32_t index, int prot_flags);
- uint64_t func_free_diskspace(torrent::ChunkList* chunk_list);
- void func_storage_error(torrent::ChunkList* chunk_list, const std::string& message);
-diff --git a/test/data/hash_check_queue_test.cc b/test/data/test_hash_check_queue.cc
-similarity index 92%
-rename from test/data/hash_check_queue_test.cc
-rename to test/data/test_hash_check_queue.cc
-index 4b15245e..65931273 100644
---- a/test/data/hash_check_queue_test.cc
-+++ b/test/data/test_hash_check_queue.cc
-@@ -1,20 +1,23 @@
- #include "config.h"
-
-+#include "test_hash_check_queue.h"
-+
-+#include "helpers/test_thread.h"
-+#include "helpers/test_utils.h"
-+
- #include <functional>
- #include <signal.h>
-
--#include "data/hash_queue_node.h"
-+#include "data/chunk_handle.h"
- #include "utils/sha1.h"
- #include "torrent/chunk_manager.h"
- #include "torrent/exceptions.h"
- #include "torrent/poll_select.h"
--#include "torrent/utils/thread_base_test.h"
- #include "thread_disk.h"
-
--#include "chunk_list_test.h"
--#include "hash_check_queue_test.h"
-+#include "test_chunk_list.h"
-
--CPPUNIT_TEST_SUITE_REGISTRATION(HashCheckQueueTest);
-+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_hash_check_queue, "data");
-
- pthread_mutex_t done_chunks_lock = PTHREAD_MUTEX_INITIALIZER;
-
-@@ -68,22 +71,16 @@ static torrent::Poll* create_select_poll() { return torrent::PollSelect::create(
- static void do_nothing() {}
-
- void
--HashCheckQueueTest::setUp() {
-+test_hash_check_queue::setUp() {
-+ test_fixture::setUp();
-+
- torrent::Poll::slot_create_poll() = std::bind(&create_select_poll);
-
- signal(SIGUSR1, (sig_t)&do_nothing);
- }
-
- void
--HashCheckQueueTest::tearDown() {
--}
--
--void
--HashCheckQueueTest::test_basic() {
--}
--
--void
--HashCheckQueueTest::test_single() {
-+test_hash_check_queue::test_single() {
- SETUP_CHUNK_LIST();
- torrent::HashCheckQueue hash_queue;
-
-@@ -110,7 +107,7 @@ HashCheckQueueTest::test_single() {
- }
-
- void
--HashCheckQueueTest::test_multiple() {
-+test_hash_check_queue::test_multiple() {
- SETUP_CHUNK_LIST();
- torrent::HashCheckQueue hash_queue;
-
-@@ -143,7 +140,7 @@ HashCheckQueueTest::test_multiple() {
- }
-
- void
--HashCheckQueueTest::test_erase() {
-+test_hash_check_queue::test_erase() {
- // SETUP_CHUNK_LIST();
- // torrent::HashCheckQueue hash_queue;
-
-@@ -176,7 +173,7 @@ HashCheckQueueTest::test_erase() {
- }
-
- void
--HashCheckQueueTest::test_thread() {
-+test_hash_check_queue::test_thread() {
- SETUP_CHUNK_LIST();
- SETUP_THREAD();
- thread_disk->start_thread();
-diff --git a/test/data/hash_check_queue_test.h b/test/data/test_hash_check_queue.h
-similarity index 63%
-rename from test/data/hash_check_queue_test.h
-rename to test/data/test_hash_check_queue.h
-index 5398a50d..d2d271bb 100644
---- a/test/data/hash_check_queue_test.h
-+++ b/test/data/test_hash_check_queue.h
-@@ -1,26 +1,19 @@
--#include <map>
--#include <vector>
--#include <cppunit/extensions/HelperMacros.h>
-+#import "helpers/test_fixture.h"
-
--#include "data/hash_check_queue.h"
--#include "torrent/hash_string.h"
-+class test_hash_check_queue : public test_fixture {
-+ CPPUNIT_TEST_SUITE(test_hash_check_queue);
-
--
--class HashCheckQueueTest : public CppUnit::TestFixture {
-- CPPUNIT_TEST_SUITE(HashCheckQueueTest);
-- CPPUNIT_TEST(test_basic);
- CPPUNIT_TEST(test_single);
- CPPUNIT_TEST(test_multiple);
- CPPUNIT_TEST(test_erase);
-
- CPPUNIT_TEST(test_thread);
-+
- CPPUNIT_TEST_SUITE_END();
-
- public:
- void setUp();
-- void tearDown();
-
-- void test_basic();
- void test_single();
- void test_multiple();
- void test_erase();
-@@ -28,6 +21,13 @@ public:
- void test_thread();
- };
-
-+#import <map>
-+#import <vector>
-+
-+#import "data/hash_queue_node.h"
-+#import "data/hash_check_queue.h"
-+#import "torrent/hash_string.h"
-+
- typedef std::map<int, torrent::HashString> done_chunks_type;
- typedef std::vector<torrent::ChunkHandle> handle_list;
-
-diff --git a/test/data/hash_queue_test.cc b/test/data/test_hash_queue.cc
-similarity index 82%
-rename from test/data/hash_queue_test.cc
-rename to test/data/test_hash_queue.cc
-index d7ce3ba8..d9a88c8d 100644
---- a/test/data/hash_queue_test.cc
-+++ b/test/data/test_hash_queue.cc
-@@ -1,22 +1,26 @@
--#include "config.h"
-+#import "config.h"
-
--#include <functional>
--#include <signal.h>
-+#import "test_hash_queue.h"
-
--#include "data/hash_queue_node.h"
--#include "torrent/chunk_manager.h"
--#include "torrent/exceptions.h"
--#include "torrent/hash_string.h"
--#include "torrent/poll_select.h"
--#include "torrent/utils/thread_base_test.h"
--#include "globals.h"
--#include "thread_disk.h"
-+#import "helpers/test_thread.h"
-+#import "helpers/test_utils.h"
-
--#include "chunk_list_test.h"
--#include "hash_queue_test.h"
--#include "hash_check_queue_test.h"
-+#import <functional>
-+#import <signal.h>
-
--CPPUNIT_TEST_SUITE_REGISTRATION(HashQueueTest);
-+#import "data/hash_queue.h"
-+#import "data/hash_queue_node.h"
-+#import "torrent/chunk_manager.h"
-+#import "torrent/exceptions.h"
-+#import "torrent/hash_string.h"
-+#import "torrent/poll_select.h"
-+#import "globals.h"
-+#import "thread_disk.h"
-+
-+#import "test_chunk_list.h"
-+#import "test_hash_check_queue.h"
-+
-+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_hash_queue, "data");
-
- typedef std::map<int, torrent::HashString> done_chunks_type;
-
-@@ -39,7 +43,9 @@ static torrent::Poll* create_select_poll() { return torrent::PollSelect::create(
- static void do_nothing() {}
-
- void
--HashQueueTest::setUp() {
-+test_hash_queue::setUp() {
-+ test_fixture::setUp();
-+
- CPPUNIT_ASSERT(torrent::taskScheduler.empty());
-
- torrent::Poll::slot_create_poll() = std::bind(&create_select_poll);
-@@ -47,25 +53,9 @@ HashQueueTest::setUp() {
- }
-
- void
--HashQueueTest::tearDown() {
-+test_hash_queue::tearDown() {
- torrent::taskScheduler.clear();
--}
--
--void
--HashQueueTest::test_basic() {
-- // SETUP_CHUNK_LIST();
-- // SETUP_THREAD();
-- // thread_disk->start_thread();
--
-- // torrent::HashQueue* hash_queue = new torrent::HashQueue(thread_disk);
--
-- // // Do stuff?
--
-- // delete hash_queue;
--
-- // thread_disk->stop_thread();
-- // CLEANUP_THREAD();
-- // CLEANUP_CHUNK_LIST();
-+ test_fixture::tearDown();
- }
-
- static void
-@@ -73,7 +63,7 @@ fill_queue() {
- }
-
- void
--HashQueueTest::test_single() {
-+test_hash_queue::test_single() {
- SETUP_CHUNK_LIST();
- SETUP_THREAD();
- thread_disk->start_thread();
-@@ -105,7 +95,7 @@ HashQueueTest::test_single() {
- }
-
- void
--HashQueueTest::test_multiple() {
-+test_hash_queue::test_multiple() {
- SETUP_CHUNK_LIST();
- SETUP_THREAD();
- thread_disk->start_thread();
-@@ -137,7 +127,7 @@ HashQueueTest::test_multiple() {
- }
-
- void
--HashQueueTest::test_erase() {
-+test_hash_queue::test_erase() {
- SETUP_CHUNK_LIST();
- SETUP_THREAD();
-
-@@ -164,7 +154,7 @@ HashQueueTest::test_erase() {
- }
-
- void
--HashQueueTest::test_erase_stress() {
-+test_hash_queue::test_erase_stress() {
- SETUP_CHUNK_LIST();
- SETUP_THREAD();
- thread_disk->start_thread();
-diff --git a/test/data/hash_queue_test.h b/test/data/test_hash_queue.h
-similarity index 58%
-rename from test/data/hash_queue_test.h
-rename to test/data/test_hash_queue.h
-index cb5b7282..79914484 100644
---- a/test/data/hash_queue_test.h
-+++ b/test/data/test_hash_queue.h
-@@ -1,10 +1,7 @@
--#include <cppunit/extensions/HelperMacros.h>
-+#include "helpers/test_fixture.h"
-
--#include "data/hash_queue.h"
--
--class HashQueueTest : public CppUnit::TestFixture {
-- CPPUNIT_TEST_SUITE(HashQueueTest);
-- CPPUNIT_TEST(test_basic);
-+class test_hash_queue : public test_fixture {
-+ CPPUNIT_TEST_SUITE(test_hash_queue);
-
- CPPUNIT_TEST(test_single);
- CPPUNIT_TEST(test_multiple);
-@@ -17,8 +14,6 @@ public:
- void setUp();
- void tearDown();
-
-- void test_basic();
--
- void test_single();
- void test_multiple();
- void test_erase();
-diff --git a/test/helpers/progress_listener.cc b/test/helpers/progress_listener.cc
-index c2b60bcd..7a6ed047 100644
---- a/test/helpers/progress_listener.cc
-+++ b/test/helpers/progress_listener.cc
-@@ -36,10 +36,10 @@ progress_listener::addFailure(const CppUnit::TestFailure &failure) {
- if (m_current_log_buffer == nullptr)
- return;
-
-- std::cout << " : " << (failure.isError() ? "error" : "assertion");
-+ std::cout << " : " << (failure.isError() ? "error" : "assertion") << std::flush;
-
- m_last_test_failed = true;
-- m_failures.push_back(std::move(failure_type{failure.failedTestName(), std::move(m_current_log_buffer)}));
-+ m_failures.push_back(failure_type{ failure.failedTestName(), std::move(m_current_log_buffer) });
- }
-
- void
-diff --git a/test/helpers/test_fixture.h b/test/helpers/test_fixture.h
-index 312d5009..aa557a5e 100644
---- a/test/helpers/test_fixture.h
-+++ b/test/helpers/test_fixture.h
-@@ -1,14 +1,14 @@
--#ifndef LIBTORRENT_HELPER_TEST_FIXTURE_H
--#define LIBTORRENT_HELPER_TEST_FIXTURE_H
--
--#include <cppunit/extensions/HelperMacros.h>
--
--#include "helpers/mock_function.h"
--
--class test_fixture : public CppUnit::TestFixture {
--public:
-- void setUp();
-- void tearDown();
--};
--
--#endif
-+#ifndef LIBTORRENT_HELPER_TEST_FIXTURE_H
-+#define LIBTORRENT_HELPER_TEST_FIXTURE_H
-+
-+#include <cppunit/extensions/HelperMacros.h>
-+
-+#include "helpers/mock_function.h"
-+
-+class test_fixture : public CppUnit::TestFixture {
-+public:
-+ void setUp();
-+ void tearDown();
-+};
-+
-+#endif
-diff --git a/test/helpers/test_thread.cc b/test/helpers/test_thread.cc
-new file mode 100755
-index 00000000..4b3d4c95
---- /dev/null
-+++ b/test/helpers/test_thread.cc
-@@ -0,0 +1,71 @@
-+#import "config.h"
-+
-+#import "test_thread.h"
-+
-+#import <unistd.h>
-+#import <cppunit/extensions/HelperMacros.h>
-+
-+#import "thread_disk.h"
-+#import "torrent/exceptions.h"
-+#import "torrent/poll_select.h"
-+
-+const int test_thread::test_flag_pre_stop;
-+const int test_thread::test_flag_long_timeout;
-+
-+const int test_thread::test_flag_acquire_global;
-+const int test_thread::test_flag_has_global;
-+
-+const int test_thread::test_flag_do_work;
-+const int test_thread::test_flag_pre_poke;
-+const int test_thread::test_flag_post_poke;
-+
-+test_thread::test_thread() :
-+ m_test_state(TEST_NONE),
-+ m_test_flags(0) {
-+}
-+
-+void
-+test_thread::init_thread() {
-+ m_state = STATE_INITIALIZED;
-+ m_test_state = TEST_PRE_START;
-+ m_poll = torrent::PollSelect::create(256);
-+}
-+
-+void
-+test_thread::call_events() {
-+ if ((m_test_flags & test_flag_pre_stop) && m_test_state == TEST_PRE_START && m_state == STATE_ACTIVE)
-+ __sync_lock_test_and_set(&m_test_state, TEST_PRE_STOP);
-+
-+ if ((m_test_flags & test_flag_acquire_global)) {
-+ acquire_global_lock();
-+ __sync_and_and_fetch(&m_test_flags, ~test_flag_acquire_global);
-+ __sync_or_and_fetch(&m_test_flags, test_flag_has_global);
-+ }
-+
-+ if ((m_flags & flag_do_shutdown)) {
-+ if ((m_flags & flag_did_shutdown))
-+ throw torrent::internal_error("Already trigged shutdown.");
-+
-+ __sync_or_and_fetch(&m_flags, flag_did_shutdown);
-+ throw torrent::shutdown_exception();
-+ }
-+
-+ if ((m_test_flags & test_flag_pre_poke)) {
-+ }
-+
-+ if ((m_test_flags & test_flag_do_work)) {
-+ usleep(10 * 1000); // TODO: Don't just sleep, as that give up core.
-+ __sync_and_and_fetch(&m_test_flags, ~test_flag_do_work);
-+ }
-+
-+ if ((m_test_flags & test_flag_post_poke)) {
-+ }
-+}
-+
-+thread_management_type::thread_management_type() {
-+ CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
-+}
-+
-+thread_management_type::~thread_management_type() {
-+ torrent::thread_base::release_global_lock();
-+}
-diff --git a/test/helpers/test_thread.h b/test/helpers/test_thread.h
-new file mode 100755
-index 00000000..52037036
---- /dev/null
-+++ b/test/helpers/test_thread.h
-@@ -0,0 +1,59 @@
-+#import "torrent/utils/thread_base.h"
-+
-+class test_thread : public torrent::thread_base {
-+public:
-+ enum test_state {
-+ TEST_NONE,
-+ TEST_PRE_START,
-+ TEST_PRE_STOP,
-+ TEST_STOP
-+ };
-+
-+ static const int test_flag_pre_stop = 0x1;
-+ static const int test_flag_long_timeout = 0x2;
-+
-+ static const int test_flag_acquire_global = 0x10;
-+ static const int test_flag_has_global = 0x20;
-+
-+ static const int test_flag_do_work = 0x100;
-+ static const int test_flag_pre_poke = 0x200;
-+ static const int test_flag_post_poke = 0x400;
-+
-+ test_thread();
-+
-+ int test_state() const { return m_test_state; }
-+ bool is_state(int state) const { return m_state == state; }
-+ bool is_test_state(int state) const { return m_test_state == state; }
-+ bool is_test_flags(int flags) const { return (m_test_flags & flags) == flags; }
-+ bool is_not_test_flags(int flags) const { return !(m_test_flags & flags); }
-+
-+ auto name() const -> const char* { return "test_thread"; }
-+
-+ void init_thread();
-+
-+ void set_pre_stop() { __sync_or_and_fetch(&m_test_flags, test_flag_pre_stop); }
-+ void set_acquire_global() { __sync_or_and_fetch(&m_test_flags, test_flag_acquire_global); }
-+
-+ void set_test_flag(int flags) { __sync_or_and_fetch(&m_test_flags, flags); }
-+
-+private:
-+ void call_events();
-+ int64_t next_timeout_usec() { return (m_test_flags & test_flag_long_timeout) ? (10000 * 1000) : (100 * 1000); }
-+
-+ int m_test_state lt_cacheline_aligned;
-+ int m_test_flags lt_cacheline_aligned;
-+};
-+
-+struct thread_management_type {
-+ thread_management_type();
-+ ~thread_management_type();
-+};
-+
-+#define SETUP_THREAD() \
-+ thread_management_type thread_management; \
-+ torrent::thread_disk* thread_disk = new torrent::thread_disk(); \
-+ thread_disk->init_thread();
-+
-+#define CLEANUP_THREAD() \
-+ CPPUNIT_ASSERT(wait_for_true(std::bind(&torrent::thread_base::is_inactive, thread_disk))); \
-+ delete thread_disk;
-diff --git a/test/helpers/test_utils.h b/test/helpers/test_utils.h
-new file mode 100644
-index 00000000..0c8c6b7a
---- /dev/null
-+++ b/test/helpers/test_utils.h
-@@ -0,0 +1,16 @@
-+#include <functional>
-+#include <unistd.h>
-+
-+inline bool
-+wait_for_true(std::function<bool ()> test_function) {
-+ int i = 100;
-+
-+ do {
-+ if (test_function())
-+ return true;
-+
-+ usleep(10 * 1000);
-+ } while (--i);
-+
-+ return false;
-+}
-diff --git a/test/helpers/utils.h b/test/helpers/utils.h
-index d18450c1..e81d22eb 100644
---- a/test/helpers/utils.h
-+++ b/test/helpers/utils.h
-@@ -1,60 +1,60 @@
--#ifndef LIBTORRENT_HELPER_UTILS_H
--#define LIBTORRENT_HELPER_UTILS_H
--
--#include <algorithm>
--#include <iostream>
--#include <cppunit/extensions/TestFactoryRegistry.h>
--#include <torrent/utils/log.h>
--
--static void
--dump_failure_log(const failure_type& failure) {
-- if (failure.log->empty())
-- return;
--
-- std::cout << std::endl << failure.name << std::endl;
--
-- // Doesn't print dump messages as log_buffer drops them.
-- std::for_each(failure.log->begin(), failure.log->end(), [](const torrent::log_entry& entry) {
-- std::cout << entry.timestamp << ' ' << entry.message << '\n';
-- });
--
-- std::cout << std::flush;
--}
--
--static void
--dump_failures(const failure_list_type& failures) {
-- if (failures.empty())
-- return;
--
-- std::cout << std::endl
-- << "=================" << std::endl
-- << "Failed Test Logs:" << std::endl
-- << "=================" << std::endl;
--
-- std::for_each(failures.begin(), failures.end(), [](const failure_type& failure) {
-- dump_failure_log(failure);
-- });
-- std::cout << std::endl;
--}
--
--static
--void add_tests(CppUnit::TextUi::TestRunner& runner, const char* c_test_names) {
-- if (c_test_names == NULL || std::string(c_test_names).empty()) {
-- runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
-- return;
-- }
--
-- const std::string& test_names(c_test_names);
--
-- size_t pos = 0;
-- size_t next = 0;
--
-- while ((next = test_names.find(',', pos)) < test_names.size()) {
-- runner.addTest(CppUnit::TestFactoryRegistry::getRegistry(test_names.substr(pos, next - pos)).makeTest());
-- pos = next + 1;
-- }
--
-- runner.addTest(CppUnit::TestFactoryRegistry::getRegistry(test_names.substr(pos)).makeTest());
--}
--
--#endif
-+#ifndef LIBTORRENT_HELPER_UTILS_H
-+#define LIBTORRENT_HELPER_UTILS_H
-+
-+#include <algorithm>
-+#include <iostream>
-+#include <cppunit/extensions/TestFactoryRegistry.h>
-+#include <torrent/utils/log.h>
-+
-+static void
-+dump_failure_log(const failure_type& failure) {
-+ if (failure.log->empty())
-+ return;
-+
-+ std::cout << std::endl << failure.name << std::endl;
-+
-+ // Doesn't print dump messages as log_buffer drops them.
-+ std::for_each(failure.log->begin(), failure.log->end(), [](const torrent::log_entry& entry) {
-+ std::cout << entry.timestamp << ' ' << entry.message << '\n';
-+ });
-+
-+ std::cout << std::flush;
-+}
-+
-+static void
-+dump_failures(const failure_list_type& failures) {
-+ if (failures.empty())
-+ return;
-+
-+ std::cout << std::endl
-+ << "=================" << std::endl
-+ << "Failed Test Logs:" << std::endl
-+ << "=================" << std::endl;
-+
-+ std::for_each(failures.begin(), failures.end(), [](const failure_type& failure) {
-+ dump_failure_log(failure);
-+ });
-+ std::cout << std::endl;
-+}
-+
-+static
-+void add_tests(CppUnit::TextUi::TestRunner& runner, const char* c_test_names) {
-+ if (c_test_names == NULL || std::string(c_test_names).empty()) {
-+ runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
-+ return;
-+ }
-+
-+ const std::string& test_names(c_test_names);
-+
-+ size_t pos = 0;
-+ size_t next = 0;
-+
-+ while ((next = test_names.find(',', pos)) < test_names.size()) {
-+ runner.addTest(CppUnit::TestFactoryRegistry::getRegistry(test_names.substr(pos, next - pos)).makeTest());
-+ pos = next + 1;
-+ }
-+
-+ runner.addTest(CppUnit::TestFactoryRegistry::getRegistry(test_names.substr(pos)).makeTest());
-+}
-+
-+#endif
-diff --git a/test/main.cc b/test/main.cc
-index e8a00e1f..57ae31a2 100644
---- a/test/main.cc
-+++ b/test/main.cc
-@@ -19,9 +19,11 @@
- #include "helpers/progress_listener.h"
- #include "helpers/utils.h"
-
--CPPUNIT_REGISTRY_ADD_TO_DEFAULT("net");
- CPPUNIT_REGISTRY_ADD_TO_DEFAULT("torrent/net");
- CPPUNIT_REGISTRY_ADD_TO_DEFAULT("torrent/utils");
-+CPPUNIT_REGISTRY_ADD_TO_DEFAULT("torrent");
-+CPPUNIT_REGISTRY_ADD_TO_DEFAULT("net");
-+CPPUNIT_REGISTRY_ADD_TO_DEFAULT("tracker");
-
- void
- do_test_panic(int signum) {
-diff --git a/test/torrent/http_test.cc b/test/torrent/test_http.cc
-similarity index 94%
-rename from test/torrent/http_test.cc
-rename to test/torrent/test_http.cc
-index 27e04552..24ec97b5 100644
---- a/test/torrent/http_test.cc
-+++ b/test/torrent/test_http.cc
-@@ -1,10 +1,11 @@
- #include "config.h"
-
--#include <sstream>
-+#include "test_http.h"
-
--#include "http_test.h"
-+#include <sstream>
-+#include "torrent/http.h"
-
--CPPUNIT_TEST_SUITE_REGISTRATION(HttpTest);
-+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_http, "torrent");
-
- #define HTTP_SETUP() \
- bool http_destroyed = false; \
-@@ -72,7 +73,7 @@ TestHttp* create_test_http() { return new TestHttp; }
- static void increment_value(int* value) { (*value)++; }
-
- void
--HttpTest::test_basic() {
-+test_http::test_basic() {
- torrent::Http::slot_factory() = std::bind(&create_test_http);
-
- torrent::Http* http = torrent::Http::slot_factory()();
-@@ -94,7 +95,7 @@ HttpTest::test_basic() {
- }
-
- void
--HttpTest::test_done() {
-+test_http::test_done() {
- HTTP_SETUP();
- http->start();
-
-@@ -106,7 +107,7 @@ HttpTest::test_done() {
- }
-
- void
--HttpTest::test_failure() {
-+test_http::test_failure() {
- HTTP_SETUP();
- http->start();
-
-@@ -118,7 +119,7 @@ HttpTest::test_failure() {
- }
-
- void
--HttpTest::test_delete_on_done() {
-+test_http::test_delete_on_done() {
- HTTP_SETUP();
- http->start();
- http->set_delete_stream();
-@@ -145,7 +146,7 @@ HttpTest::test_delete_on_done() {
- }
-
- void
--HttpTest::test_delete_on_failure() {
-+test_http::test_delete_on_failure() {
- HTTP_SETUP();
- http->start();
- http->set_delete_stream();
-diff --git a/test/torrent/http_test.h b/test/torrent/test_http.h
-similarity index 63%
-rename from test/torrent/http_test.h
-rename to test/torrent/test_http.h
-index c6c97d08..f4334646 100644
---- a/test/torrent/http_test.h
-+++ b/test/torrent/test_http.h
-@@ -1,21 +1,18 @@
--#include <cppunit/extensions/HelperMacros.h>
-+#import "helpers/test_fixture.h"
-
--#include "torrent/http.h"
-+class test_http : public test_fixture {
-+ CPPUNIT_TEST_SUITE(test_http);
-
--class HttpTest : public CppUnit::TestFixture {
-- CPPUNIT_TEST_SUITE(HttpTest);
- CPPUNIT_TEST(test_basic);
- CPPUNIT_TEST(test_done);
- CPPUNIT_TEST(test_failure);
-
- CPPUNIT_TEST(test_delete_on_done);
- CPPUNIT_TEST(test_delete_on_failure);
-+
- CPPUNIT_TEST_SUITE_END();
-
- public:
-- void setUp() {}
-- void tearDown() {}
--
- void test_basic();
- void test_done();
- void test_failure();
-diff --git a/test/torrent/utils/option_strings_test.h b/test/torrent/utils/option_strings_test.h
-deleted file mode 100644
-index 55df4f19..00000000
---- a/test/torrent/utils/option_strings_test.h
-+++ /dev/null
-@@ -1,17 +0,0 @@
--#include <cppunit/extensions/HelperMacros.h>
--
--#include "torrent/utils/option_strings.h"
--
--class option_strings_test : public CppUnit::TestFixture {
-- CPPUNIT_TEST_SUITE(option_strings_test);
-- CPPUNIT_TEST(test_basic);
-- CPPUNIT_TEST(test_entries);
-- CPPUNIT_TEST_SUITE_END();
--
--public:
-- void setUp() {}
-- void tearDown() {}
--
-- void test_basic();
-- void test_entries();
--};
-diff --git a/test/torrent/utils/signal_bitfield_test.h b/test/torrent/utils/signal_bitfield_test.h
-deleted file mode 100644
-index 4590de41..00000000
---- a/test/torrent/utils/signal_bitfield_test.h
-+++ /dev/null
-@@ -1,23 +0,0 @@
--#include <cppunit/extensions/HelperMacros.h>
--
--#include "torrent/utils/signal_bitfield.h"
--
--class utils_signal_bitfield_test : public CppUnit::TestFixture {
-- CPPUNIT_TEST_SUITE(utils_signal_bitfield_test);
-- CPPUNIT_TEST(test_basic);
-- CPPUNIT_TEST(test_single);
-- CPPUNIT_TEST(test_multiple);
--
-- CPPUNIT_TEST(test_thread);
-- CPPUNIT_TEST_SUITE_END();
--
--public:
-- void setUp();
-- void tearDown();
--
-- void test_basic();
-- void test_single();
-- void test_multiple();
--
-- void test_thread();
--};
-diff --git a/test/torrent/utils/test_extents.cc b/test/torrent/utils/test_extents.cc
-index 87424d62..8e614e10 100644
---- a/test/torrent/utils/test_extents.cc
-+++ b/test/torrent/utils/test_extents.cc
-@@ -2,34 +2,25 @@
-
- #include "test_extents.h"
-
--#include <cinttypes>
--#include <iostream>
- #include <torrent/utils/extents.h>
-+#include <torrent/utils/log.h>
-
--CPPUNIT_TEST_SUITE_REGISTRATION(ExtentsTest);
-+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_extents, "torrent/utils");
-
--void
--ExtentsTest::setUp() {
--}
-+#define TEST_EXTENT_BEGIN(name) \
-+ lt_log_print(torrent::LOG_MOCK_CALLS, "extent: %s", name);
-
--void
--ExtentsTest::tearDown() {
--}
--
--//typedef torrent::extents<uint32_t, int, 8, 16, 4> extent_type_1;
- typedef torrent::extents<uint32_t, int> extent_type_1;
-
--// typedef torrent::extents<uint32_t, int, 0, 256, 16> extent_type_3;
--/*
- template <typename Extent>
- bool
- verify_extent_data(Extent& extent, const uint32_t* idx, const int* val) {
- while (*idx != *(idx + 1)) {
-- if (!extent.is_equal_range(*idx, *(idx + 1) - 1, *val)) {
-- // std::cout << *idx << ' ' << *(idx + 1) << ' ' << *val << std::endl;
-- // std::cout << extent.at(*idx) << std::endl;
-- // std::cout << extent.at(*(idx + 1)) << std::endl;
-- return false;
-+ for (auto i = *idx; i != *(idx + 1); i++) {
-+ lt_log_print(torrent::LOG_MOCK_CALLS, "extent: at %u", i);
-+
-+ if (extent.at(i) != *val)
-+ return false;
- }
-
- idx++;
-@@ -40,34 +31,32 @@ verify_extent_data(Extent& extent, const uint32_t* idx, const int* val) {
- }
-
- static const uint32_t idx_empty[] = {0, 256, 256};
--static const int val_empty[] = {0, 1};
-+static const int val_empty[] = {0};
-
- static const uint32_t idx_basic_1[] = {0, 1, 255, 256, 256};
- static const int val_basic_1[] = {1, 0, 1};
-
--// static const uint32_t idx_basic_2[] = {0, 1, 16, 255, 256, 256};
--// static const int val_basic_2[] = {1, 0, 2, 1};
--*/
- void
--ExtentsTest::test_basic() {
-+test_extents::test_basic() {
- extent_type_1 extent_1;
--/*
-- // Test empty.
-- CPPUNIT_ASSERT(verify_extent_data(extent_1, idx_empty, val_empty));
--
-- CPPUNIT_ASSERT(extent_1.at(0) == int());
-- CPPUNIT_ASSERT(extent_1.at(255) == int());
-+ extent_1.insert(0, 255, int());
-
-- extent_1.insert(0, 0, 1);
-- extent_1.insert(255, 0, 1);
-+ { TEST_EXTENT_BEGIN("empty");
-+ CPPUNIT_ASSERT(verify_extent_data(extent_1, idx_empty, val_empty));
-
-- CPPUNIT_ASSERT(extent_1.at(0) == 1);
-- CPPUNIT_ASSERT(extent_1.at(255) == 1);
-+ CPPUNIT_ASSERT(extent_1.at(0) == int());
-+ CPPUNIT_ASSERT(extent_1.at(255) == int());
-+ };
-+ { TEST_EXTENT_BEGIN("borders");
-
-- CPPUNIT_ASSERT(verify_extent_data(extent_1, idx_basic_1, val_basic_1));
-+ extent_1.insert(0, 0, 1);
-+ extent_1.insert(255, 255, 1);
-+ // This step shouldn't be needed.
-+ extent_1.insert(1, 254, int());
-
-- // extent_1.insert(38, 3, 2);
-+ CPPUNIT_ASSERT(extent_1.at(0) == 1);
-+ CPPUNIT_ASSERT(extent_1.at(255) == 1);
-
-- // CPPUNIT_ASSERT(verify_extent_data(extent_1, idx_basic_2, val_basic_2));
--*/
-+ CPPUNIT_ASSERT(verify_extent_data(extent_1, idx_basic_1, val_basic_1));
-+ };
- }
-diff --git a/test/torrent/utils/test_extents.h b/test/torrent/utils/test_extents.h
-index fd790cf8..e187f6a7 100644
---- a/test/torrent/utils/test_extents.h
-+++ b/test/torrent/utils/test_extents.h
-@@ -1,13 +1,10 @@
--#include <cppunit/extensions/HelperMacros.h>
-+#include "helpers/test_fixture.h"
-
--class ExtentsTest : public CppUnit::TestFixture {
-- CPPUNIT_TEST_SUITE(ExtentsTest);
-+class test_extents : public test_fixture {
-+ CPPUNIT_TEST_SUITE(test_extents);
- CPPUNIT_TEST(test_basic);
- CPPUNIT_TEST_SUITE_END();
-
- public:
-- void setUp();
-- void tearDown();
--
- void test_basic();
- };
-diff --git a/test/torrent/utils/log_test.cc b/test/torrent/utils/test_log.cc
-similarity index 92%
-rename from test/torrent/utils/log_test.cc
-rename to test/torrent/utils/test_log.cc
-index 8cc00ef8..fec7e505 100644
---- a/test/torrent/utils/log_test.cc
-+++ b/test/torrent/utils/test_log.cc
-@@ -1,5 +1,7 @@
- #include "config.h"
-
-+#include "test_log.h"
-+
- #include <algorithm>
- #include <cstring>
- #include <fstream>
-@@ -9,15 +11,13 @@
- #include <torrent/exceptions.h>
- #include <torrent/utils/log.h>
-
--#include "log_test.h"
-+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_log, "torrent/utils");
-
- namespace torrent {
- typedef std::vector<std::pair<std::string, log_slot> > log_output_list;
- extern log_output_list log_outputs;
- }
-
--CPPUNIT_TEST_SUITE_REGISTRATION(utils_log_test);
--
- const char* expected_output = NULL;
- unsigned int output_mask;
-
-@@ -35,19 +35,19 @@ test_output(const char* output, unsigned int length, unsigned int mask) {
- CPPUNIT_ASSERT(output_mask == (mask));
-
- void
--utils_log_test::setUp() {
-+test_log::setUp() {
- // Don't initialize since this creates the group->child connections.
- // torrent::log_initialize();
- torrent::log_cleanup();
- }
-
- void
--utils_log_test::tearDown() {
-+test_log::tearDown() {
- torrent::log_cleanup();
- }
-
- void
--utils_log_test::test_basic() {
-+test_log::test_basic() {
- CPPUNIT_ASSERT(!torrent::log_groups.empty());
- CPPUNIT_ASSERT(torrent::log_groups.size() == torrent::LOG_GROUP_MAX_SIZE);
-
-@@ -61,7 +61,7 @@ open_output(const char* name, int mask = 0) {
- }
-
- void
--utils_log_test::test_output_open() {
-+test_log::test_output_open() {
- CPPUNIT_ASSERT(torrent::log_groups[0].size_outputs() == 0);
-
- // Add test for unknown output names.
-@@ -92,7 +92,7 @@ utils_log_test::test_output_open() {
- // on unused log items.
-
- void
--utils_log_test::test_print() {
-+test_log::test_print() {
- open_output("test_print_1", 0x1);
- open_output("test_print_2", 0x2);
- torrent::log_add_group_output(0, "test_print_1");
-@@ -113,7 +113,7 @@ enum {
- };
-
- void
--utils_log_test::test_children() {
-+test_log::test_children() {
- open_output("test_children_1", 0x1);
- open_output("test_children_2", 0x2);
- torrent::log_add_group_output(GROUP_PARENT_1, "test_children_1");
-@@ -136,8 +136,8 @@ utils_log_test::test_children() {
- }
-
- void
--utils_log_test::test_file_output() {
-- std::string filename = "utils_log_test.XXXXXX";
-+test_log::test_file_output() {
-+ std::string filename = "test_log.XXXXXX";
-
- mktemp(&*filename.begin());
-
-@@ -159,8 +159,8 @@ utils_log_test::test_file_output() {
- }
-
- void
--utils_log_test::test_file_output_append() {
-- std::string filename = "utils_log_test.XXXXXX";
-+test_log::test_file_output_append() {
-+ std::string filename = "test_log.XXXXXX";
-
- mktemp(&*filename.begin());
-
-diff --git a/test/torrent/utils/log_test.h b/test/torrent/utils/test_log.h
-similarity index 71%
-rename from test/torrent/utils/log_test.h
-rename to test/torrent/utils/test_log.h
-index d4cb3bc6..a06c95ae 100644
---- a/test/torrent/utils/log_test.h
-+++ b/test/torrent/utils/test_log.h
-@@ -1,9 +1,7 @@
--#include <cppunit/extensions/HelperMacros.h>
-+#include "helpers/test_fixture.h"
-
--#include "torrent/utils/log.h"
--
--class utils_log_test : public CppUnit::TestFixture {
-- CPPUNIT_TEST_SUITE(utils_log_test);
-+class test_log : public test_fixture {
-+ CPPUNIT_TEST_SUITE(test_log);
- CPPUNIT_TEST(test_basic);
- CPPUNIT_TEST(test_output_open);
-
-diff --git a/test/torrent/utils/test_log_buffer.cc b/test/torrent/utils/test_log_buffer.cc
-index a56a5365..58412750 100644
---- a/test/torrent/utils/test_log_buffer.cc
-+++ b/test/torrent/utils/test_log_buffer.cc
-@@ -7,18 +7,10 @@
-
- CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_log_buffer, "torrent/utils");
-
--void
--test_log_buffer::setUp() {
-- torrent::cachedTime = rak::timer::from_seconds(1000);
--}
--
--void
--test_log_buffer::tearDown() {
--}
--
- void
- test_log_buffer::test_basic() {
- torrent::log_buffer log;
-+ torrent::cachedTime = rak::timer::from_seconds(1000);
-
- log.lock();
- CPPUNIT_ASSERT(log.empty());
-@@ -46,6 +38,7 @@ test_log_buffer::test_basic() {
- void
- test_log_buffer::test_timestamps() {
- torrent::log_buffer log;
-+ torrent::cachedTime = rak::timer::from_seconds(1000);
-
- log.lock_and_push_log("foobar", 6, 0);
- CPPUNIT_ASSERT(log.back().timestamp == 1000);
-diff --git a/test/torrent/utils/test_log_buffer.h b/test/torrent/utils/test_log_buffer.h
-index 290df4c1..39c6b879 100644
---- a/test/torrent/utils/test_log_buffer.h
-+++ b/test/torrent/utils/test_log_buffer.h
-@@ -2,16 +2,11 @@
-
- class test_log_buffer : public test_fixture {
- CPPUNIT_TEST_SUITE(test_log_buffer);
--
- CPPUNIT_TEST(test_basic);
- CPPUNIT_TEST(test_timestamps);
--
- CPPUNIT_TEST_SUITE_END();
-
- public:
-- void setUp();
-- void tearDown();
--
- void test_basic();
- void test_timestamps();
- };
-diff --git a/test/torrent/utils/option_strings_test.cc b/test/torrent/utils/test_option_strings.cc
-similarity index 65%
-rename from test/torrent/utils/option_strings_test.cc
-rename to test/torrent/utils/test_option_strings.cc
-index a9bdcc89..68da1d2b 100644
---- a/test/torrent/utils/option_strings_test.cc
-+++ b/test/torrent/utils/test_option_strings.cc
-@@ -1,35 +1,22 @@
- #include "config.h"
-
--#include <fstream>
--#include <functional>
--#include <iostream>
-+#include "test_option_strings.h"
-
--#include <torrent/exceptions.h>
--#include <torrent/utils/option_strings.h>
--
--#include <torrent/connection_manager.h>
--#include <torrent/object.h>
- #include <torrent/download.h>
--#include <torrent/download/choke_group.h>
--#include <torrent/download/choke_queue.h>
-+#include <torrent/utils/option_strings.h>
- #include <torrent/utils/log.h>
-
--#include "option_strings_test.h"
--
--CPPUNIT_TEST_SUITE_REGISTRATION(option_strings_test);
--
--void
--option_strings_test::test_basic() {
--
--}
-+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_option_strings, "torrent/utils");
-
- #define TEST_ENTRY(group, name, value) \
-- { std::string result(torrent::option_as_string(torrent::group, value)); \
-+ { lt_log_print(torrent::LOG_MOCK_CALLS, "option_string: %s", name); \
-+ std::string result(torrent::option_as_string(torrent::group, value)); \
- CPPUNIT_ASSERT_MESSAGE("Not found '" + result + "'", result == name); \
-- CPPUNIT_ASSERT(torrent::option_find_string(torrent::group, name) == value); }
-+ CPPUNIT_ASSERT(torrent::option_find_string(torrent::group, name) == value); \
-+ }
-
- void
--option_strings_test::test_entries() {
-+test_option_strings::test_entries() {
- TEST_ENTRY(OPTION_CONNECTION_TYPE, "leech", torrent::Download::CONNECTION_LEECH);
- TEST_ENTRY(OPTION_CONNECTION_TYPE, "seed", torrent::Download::CONNECTION_SEED);
- TEST_ENTRY(OPTION_CONNECTION_TYPE, "initial_seed", torrent::Download::CONNECTION_INITIAL_SEED);
-diff --git a/test/torrent/utils/test_option_strings.h b/test/torrent/utils/test_option_strings.h
-new file mode 100644
-index 00000000..dc86e735
---- /dev/null
-+++ b/test/torrent/utils/test_option_strings.h
-@@ -0,0 +1,10 @@
-+#include "helpers/test_fixture.h"
-+
-+class test_option_strings : public test_fixture {
-+ CPPUNIT_TEST_SUITE(test_option_strings);
-+ CPPUNIT_TEST(test_entries);
-+ CPPUNIT_TEST_SUITE_END();
-+
-+public:
-+ void test_entries();
-+};
-diff --git a/test/torrent/utils/test_queue_buckets.cc b/test/torrent/utils/test_queue_buckets.cc
-index a32d17e7..49d1bae6 100644
---- a/test/torrent/utils/test_queue_buckets.cc
-+++ b/test/torrent/utils/test_queue_buckets.cc
-@@ -5,7 +5,7 @@
- #include "utils/instrumentation.h"
- #include "utils/queue_buckets.h"
-
--CPPUNIT_TEST_SUITE_REGISTRATION(TestQueueBuckets);
-+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_queue_buckets, "torrent/utils");
-
- struct test_constants {
- static const int bucket_count = 2;
-@@ -87,7 +87,7 @@ struct test_queue_bucket_compare {
- //
-
- void
--TestQueueBuckets::test_basic() {
-+test_queue_buckets::test_basic() {
- torrent::instrumentation_initialize();
-
- buckets_type buckets;
-@@ -129,7 +129,7 @@ TestQueueBuckets::test_basic() {
- }
-
- void
--TestQueueBuckets::test_erase() {
-+test_queue_buckets::test_erase() {
- items_destroyed = 0;
- torrent::instrumentation_initialize();
-
-@@ -162,7 +162,7 @@ bucket_queue_find_in_any(const buckets_type& buckets, int value) {
- }
-
- void
--TestQueueBuckets::test_find() {
-+test_queue_buckets::test_find() {
- items_destroyed = 0;
- torrent::instrumentation_initialize();
-
-@@ -183,7 +183,7 @@ TestQueueBuckets::test_find() {
- }
-
- void
--TestQueueBuckets::test_destroy_range() {
-+test_queue_buckets::test_destroy_range() {
- items_destroyed = 0;
- torrent::instrumentation_initialize();
-
-@@ -206,7 +206,7 @@ TestQueueBuckets::test_destroy_range() {
- }
-
- void
--TestQueueBuckets::test_move_range() {
-+test_queue_buckets::test_move_range() {
- items_destroyed = 0;
- torrent::instrumentation_initialize();
-
-diff --git a/test/torrent/utils/test_queue_buckets.h b/test/torrent/utils/test_queue_buckets.h
-index 94624573..a7f1c30a 100644
---- a/test/torrent/utils/test_queue_buckets.h
-+++ b/test/torrent/utils/test_queue_buckets.h
-@@ -1,21 +1,18 @@
--#include <cppunit/extensions/HelperMacros.h>
-+#include "helpers/test_fixture.h"
-
--#include "protocol/request_list.h"
-+class test_queue_buckets : public test_fixture {
-+ CPPUNIT_TEST_SUITE(test_queue_buckets);
-
--class TestQueueBuckets : public CppUnit::TestFixture {
-- CPPUNIT_TEST_SUITE(TestQueueBuckets);
- CPPUNIT_TEST(test_basic);
- CPPUNIT_TEST(test_erase);
- CPPUNIT_TEST(test_find);
-
- CPPUNIT_TEST(test_destroy_range);
- CPPUNIT_TEST(test_move_range);
-+
- CPPUNIT_TEST_SUITE_END();
-
- public:
-- void setUp() {}
-- void tearDown() {}
--
- void test_basic();
- void test_erase();
- void test_find();
-diff --git a/test/torrent/utils/signal_bitfield_test.cc b/test/torrent/utils/test_signal_bitfield.cc
-similarity index 85%
-rename from test/torrent/utils/signal_bitfield_test.cc
-rename to test/torrent/utils/test_signal_bitfield.cc
-index 34b622b3..4ecd18c0 100644
---- a/test/torrent/utils/signal_bitfield_test.cc
-+++ b/test/torrent/utils/test_signal_bitfield.cc
-@@ -1,13 +1,15 @@
- #include "config.h"
-
-+#include "test_signal_bitfield.h"
-+
-+#include "helpers/test_thread.h"
-+#include "helpers/test_utils.h"
-+
- #include <torrent/exceptions.h>
- #include <torrent/utils/signal_bitfield.h>
- #include <torrent/utils/thread_base.h>
-
--#include "signal_bitfield_test.h"
--#include "thread_base_test.h"
--
--CPPUNIT_TEST_SUITE_REGISTRATION(utils_signal_bitfield_test);
-+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_signal_bitfield, "torrent/utils");
-
- static void
- mark_index(uint32_t* bitfield, unsigned int index) {
-@@ -20,13 +22,10 @@ check_index(uint32_t* bitfield, unsigned int index) {
- }
-
- void
--utils_signal_bitfield_test::setUp() {
--}
--
--void
--utils_signal_bitfield_test::tearDown() {
-+test_signal_bitfield::tearDown() {
- CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
- torrent::thread_base::release_global_lock();
-+ test_fixture::tearDown();
- }
-
- static bool
-@@ -54,7 +53,7 @@ verify_did_internal_error(std::function<unsigned int ()> func, bool should_throw
- did_throw));
-
- void
--utils_signal_bitfield_test::test_basic() {
-+test_signal_bitfield::test_basic() {
- SETUP_SIGNAL_BITFIELD();
-
- CPPUNIT_ASSERT(torrent::signal_bitfield::max_size == sizeof(torrent::signal_bitfield::bitfield_type) * 8);
-@@ -68,7 +67,7 @@ utils_signal_bitfield_test::test_basic() {
- }
-
- void
--utils_signal_bitfield_test::test_single() {
-+test_signal_bitfield::test_single() {
- SETUP_SIGNAL_BITFIELD();
-
- CPPUNIT_ASSERT(signal_bitfield.add_signal(std::bind(&mark_index, &marked_bitfield, 0)) == 0);
-@@ -86,7 +85,7 @@ utils_signal_bitfield_test::test_single() {
- }
-
- void
--utils_signal_bitfield_test::test_multiple() {
-+test_signal_bitfield::test_multiple() {
- SETUP_SIGNAL_BITFIELD();
-
- for (unsigned int i = 0; i < torrent::signal_bitfield::max_size; i++)
-@@ -106,10 +105,10 @@ utils_signal_bitfield_test::test_multiple() {
- }
-
- void
--utils_signal_bitfield_test::test_thread() {
-+test_signal_bitfield::test_threaded() {
- uint32_t marked_bitfield = 0;
-- thread_test* thread = new thread_test;
-- // thread->set_test_flag(thread_test::test_flag_long_timeout);
-+ test_thread* thread = new test_thread;
-+ // thread->set_test_flag(test_thread::test_flag_long_timeout);
-
- for (unsigned int i = 0; i < torrent::signal_bitfield::max_size; i++)
- CPPUNIT_ASSERT(thread->signal_bitfield()->add_signal(std::bind(&mark_index, &marked_bitfield, i)) == i);
-@@ -131,7 +130,7 @@ utils_signal_bitfield_test::test_thread() {
- }
-
- thread->stop_thread();
-- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_state, thread, thread_test::STATE_INACTIVE)));
-+ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_state, thread, test_thread::STATE_INACTIVE)));
-
- delete thread;
- }
-diff --git a/test/torrent/utils/test_signal_bitfield.h b/test/torrent/utils/test_signal_bitfield.h
-new file mode 100644
-index 00000000..2d24d955
---- /dev/null
-+++ b/test/torrent/utils/test_signal_bitfield.h
-@@ -0,0 +1,22 @@
-+#include "helpers/test_fixture.h"
-+
-+class test_signal_bitfield : public test_fixture {
-+ CPPUNIT_TEST_SUITE(test_signal_bitfield);
-+
-+ CPPUNIT_TEST(test_basic);
-+ CPPUNIT_TEST(test_single);
-+ CPPUNIT_TEST(test_multiple);
-+
-+ CPPUNIT_TEST(test_threaded);
-+
-+ CPPUNIT_TEST_SUITE_END();
-+
-+public:
-+ void tearDown();
-+
-+ void test_basic();
-+ void test_single();
-+ void test_multiple();
-+
-+ void test_threaded();
-+};
-diff --git a/test/torrent/utils/test_thread_base.cc b/test/torrent/utils/test_thread_base.cc
-new file mode 100644
-index 00000000..33519b7c
---- /dev/null
-+++ b/test/torrent/utils/test_thread_base.cc
-@@ -0,0 +1,169 @@
-+#include "config.h"
-+
-+#include "test_thread_base.h"
-+
-+#include "helpers/test_thread.h"
-+#include "helpers/test_utils.h"
-+
-+#include <functional>
-+#include <unistd.h>
-+
-+#include "torrent/exceptions.h"
-+#include "torrent/poll_select.h"
-+#include "torrent/utils/log.h"
-+#include "torrent/utils/thread_base.h"
-+
-+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_thread_base, "torrent/utils");
-+
-+#define TEST_BEGIN(name) \
-+ lt_log_print(torrent::LOG_MOCK_CALLS, "thread_base: %s", name); \
-+
-+void throw_shutdown_exception() { throw torrent::shutdown_exception(); }
-+
-+void
-+test_thread_base::tearDown() {
-+ CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
-+ torrent::thread_base::release_global_lock();
-+ test_fixture::tearDown();
-+}
-+
-+void
-+test_thread_base::test_basic() {
-+ test_thread* thread = new test_thread;
-+
-+ CPPUNIT_ASSERT(thread->flags() == 0);
-+
-+ CPPUNIT_ASSERT(!thread->is_main_polling());
-+ CPPUNIT_ASSERT(!thread->is_active());
-+ CPPUNIT_ASSERT(thread->global_queue_size() == 0);
-+ CPPUNIT_ASSERT(thread->poll() == NULL);
-+
-+ // Check active...
-+}
-+
-+void
-+test_thread_base::test_lifecycle() {
-+ test_thread* thread = new test_thread;
-+
-+ CPPUNIT_ASSERT(thread->state() == torrent::thread_base::STATE_UNKNOWN);
-+ CPPUNIT_ASSERT(thread->test_state() == test_thread::TEST_NONE);
-+
-+ thread->init_thread();
-+ CPPUNIT_ASSERT(thread->state() == torrent::thread_base::STATE_INITIALIZED);
-+ CPPUNIT_ASSERT(thread->is_initialized());
-+ CPPUNIT_ASSERT(thread->test_state() == test_thread::TEST_PRE_START);
-+
-+ thread->set_pre_stop();
-+ CPPUNIT_ASSERT(!wait_for_true(std::bind(&test_thread::is_test_state, thread, test_thread::TEST_PRE_STOP)));
-+
-+ thread->start_thread();
-+ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_state, thread, test_thread::STATE_ACTIVE)));
-+ CPPUNIT_ASSERT(thread->is_active());
-+ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_test_state, thread, test_thread::TEST_PRE_STOP)));
-+
-+ thread->stop_thread();
-+ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_state, thread, test_thread::STATE_INACTIVE)));
-+ CPPUNIT_ASSERT(thread->is_inactive());
-+
-+ delete thread;
-+}
-+
-+void
-+test_thread_base::test_global_lock_basic() {
-+ test_thread* thread = new test_thread;
-+
-+ thread->init_thread();
-+ thread->start_thread();
-+
-+ CPPUNIT_ASSERT(torrent::thread_base::global_queue_size() == 0);
-+
-+ // Acquire main thread...
-+ CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
-+ CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock());
-+
-+ torrent::thread_base::release_global_lock();
-+ CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
-+ CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock());
-+
-+ torrent::thread_base::release_global_lock();
-+ torrent::thread_base::acquire_global_lock();
-+ CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock());
-+
-+ thread->set_acquire_global();
-+ CPPUNIT_ASSERT(!wait_for_true(std::bind(&test_thread::is_test_flags, thread, test_thread::test_flag_has_global)));
-+
-+ torrent::thread_base::release_global_lock();
-+ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_test_flags, thread, test_thread::test_flag_has_global)));
-+
-+ CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock());
-+ torrent::thread_base::release_global_lock();
-+ CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
-+
-+ // Test waive (loop).
-+
-+ CPPUNIT_ASSERT(torrent::thread_base::global_queue_size() == 0);
-+
-+ torrent::thread_base::release_global_lock();
-+ thread->stop_thread();
-+ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_state, thread, test_thread::STATE_INACTIVE)));
-+
-+ delete thread;
-+}
-+
-+void
-+test_thread_base::test_interrupt() {
-+ test_thread* thread = new test_thread;
-+ thread->set_test_flag(test_thread::test_flag_long_timeout);
-+
-+ thread->init_thread();
-+ thread->start_thread();
-+
-+ // Vary the various timeouts.
-+
-+ for (int i = 0; i < 100; i++) {
-+ thread->interrupt();
-+ usleep(0);
-+
-+ thread->set_test_flag(test_thread::test_flag_do_work);
-+ thread->interrupt();
-+
-+ // Wait for flag to clear.
-+ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_not_test_flags, thread, test_thread::test_flag_do_work)));
-+ }
-+
-+ thread->stop_thread();
-+ CPPUNIT_ASSERT(wait_for_true(std::bind(&test_thread::is_state, thread, test_thread::STATE_INACTIVE)));
-+
-+ delete thread;
-+}
-+
-+void
-+test_thread_base::test_stop() {
-+ { TEST_BEGIN("trylock global lock");
-+ CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
-+ // torrent::thread_base::acquire_global_lock();
-+ };
-+
-+ for (int i = 0; i < 20; i++) {
-+ CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock());
-+
-+ test_thread* thread = new test_thread;
-+ thread->set_test_flag(test_thread::test_flag_do_work);
-+
-+ { TEST_BEGIN("init and start thread");
-+ thread->init_thread();
-+ thread->start_thread();
-+ };
-+
-+ { TEST_BEGIN("stop and delete thread");
-+ thread->stop_thread_wait();
-+ CPPUNIT_ASSERT(thread->is_inactive());
-+
-+ delete thread;
-+ }
-+ }
-+
-+ { TEST_BEGIN("release global lock");
-+ torrent::thread_base::release_global_lock();
-+ };
-+}
-diff --git a/test/torrent/utils/test_thread_base.h b/test/torrent/utils/test_thread_base.h
-new file mode 100644
-index 00000000..7b2a3432
---- /dev/null
-+++ b/test/torrent/utils/test_thread_base.h
-@@ -0,0 +1,25 @@
-+#include "helpers/test_fixture.h"
-+
-+class test_thread_base : public test_fixture {
-+ CPPUNIT_TEST_SUITE(test_thread_base);
-+
-+ CPPUNIT_TEST(test_basic);
-+ CPPUNIT_TEST(test_lifecycle);
-+
-+ CPPUNIT_TEST(test_global_lock_basic);
-+ CPPUNIT_TEST(test_interrupt);
-+ CPPUNIT_TEST(test_stop);
-+
-+ CPPUNIT_TEST_SUITE_END();
-+
-+public:
-+ void tearDown();
-+
-+ void test_basic();
-+ void test_lifecycle();
-+
-+ void test_global_lock_basic();
-+ void test_interrupt();
-+ void test_interrupt_legacy();
-+ void test_stop();
-+};
-diff --git a/test/torrent/utils/test_uri_parser.cc b/test/torrent/utils/test_uri_parser.cc
-index 1f4bebe8..66d6cda5 100644
---- a/test/torrent/utils/test_uri_parser.cc
-+++ b/test/torrent/utils/test_uri_parser.cc
-@@ -2,31 +2,22 @@
-
- #include "test_uri_parser.h"
-
--#include <cinttypes>
--#include <iostream>
-+#include <torrent/utils/log.h>
- #include <torrent/utils/uri_parser.h>
-
--CPPUNIT_TEST_SUITE_REGISTRATION(UriParserTest);
--
--void
--UriParserTest::setUp() {
--}
--
--void
--UriParserTest::tearDown() {
--}
-+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_uri_parser, "torrent/utils");
-
- void
- test_print_uri_state(torrent::utils::uri_state state) {
-- std::cerr << "state.uri: " << state.uri << std::endl;
-- std::cerr << "state.scheme: " << state.scheme << std::endl;
-- std::cerr << "state.resource: " << state.resource << std::endl;
-- std::cerr << "state.query: " << state.query << std::endl;
-- std::cerr << "state.fragment: " << state.fragment << std::endl;
-+ lt_log_print(torrent::LOG_MOCK_CALLS, "state.uri: %s", state.uri.c_str());
-+ lt_log_print(torrent::LOG_MOCK_CALLS, "state.scheme: %s", state.scheme.c_str());
-+ lt_log_print(torrent::LOG_MOCK_CALLS, "state.resource: %s", state.resource.c_str());
-+ lt_log_print(torrent::LOG_MOCK_CALLS, "state.query: %s", state.query.c_str());
-+ lt_log_print(torrent::LOG_MOCK_CALLS, "state.fragment: %s", state.fragment.c_str());
- }
-
- void
--UriParserTest::test_basic() {
-+test_uri_parser::test_basic() {
- torrent::utils::uri_state state;
-
- CPPUNIT_ASSERT(state.state == torrent::utils::uri_state::state_empty);
-@@ -37,7 +28,7 @@ UriParserTest::test_basic() {
- #define MAGNET_BASIC "magnet:?xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C"
-
- void
--UriParserTest::test_basic_magnet() {
-+test_uri_parser::test_basic_magnet() {
- torrent::utils::uri_state state;
-
- uri_parse_str(MAGNET_BASIC, state);
-@@ -63,7 +54,7 @@ UriParserTest::test_basic_magnet() {
- #define QUERY_MAGNET "magnet:?" QUERY_MAGNET_QUERY
-
- void
--UriParserTest::test_query_magnet() {
-+test_uri_parser::test_query_magnet() {
- torrent::utils::uri_state state;
- torrent::utils::uri_query_state query_state;
-
-@@ -82,7 +73,7 @@ UriParserTest::test_query_magnet() {
- uri_parse_query_str(state.query, query_state);
-
- for (auto element : query_state.elements)
-- std::cerr << "query_element: " << element << std::endl;
-+ lt_log_print(torrent::LOG_MOCK_CALLS, "query_element: %s", element.c_str());
-
- CPPUNIT_ASSERT(query_state.state == torrent::utils::uri_query_state::state_valid);
-
-diff --git a/test/torrent/utils/test_uri_parser.h b/test/torrent/utils/test_uri_parser.h
-index 4f1c2586..f978c8ad 100644
---- a/test/torrent/utils/test_uri_parser.h
-+++ b/test/torrent/utils/test_uri_parser.h
-@@ -1,16 +1,15 @@
--#include <cppunit/extensions/HelperMacros.h>
-+#include "helpers/test_fixture.h"
-+
-+class test_uri_parser : public test_fixture {
-+ CPPUNIT_TEST_SUITE(test_uri_parser);
-
--class UriParserTest : public CppUnit::TestFixture {
-- CPPUNIT_TEST_SUITE(UriParserTest);
- CPPUNIT_TEST(test_basic);
- CPPUNIT_TEST(test_basic_magnet);
- CPPUNIT_TEST(test_query_magnet);
-+
- CPPUNIT_TEST_SUITE_END();
-
- public:
-- void setUp();
-- void tearDown();
--
- void test_basic();
- void test_basic_magnet();
- void test_query_magnet();
-diff --git a/test/torrent/utils/thread_base_test.cc b/test/torrent/utils/thread_base_test.cc
-deleted file mode 100644
-index 8366c9ba..00000000
---- a/test/torrent/utils/thread_base_test.cc
-+++ /dev/null
-@@ -1,224 +0,0 @@
--#include "config.h"
--
--#include <functional>
--#include <unistd.h>
--
--#include <torrent/exceptions.h>
--#include <torrent/poll_select.h>
--#include <torrent/utils/thread_base.h>
--
--#include "thread_base_test.h"
--
--CPPUNIT_TEST_SUITE_REGISTRATION(utils_thread_base_test);
--
--const int thread_test::test_flag_pre_stop;
--const int thread_test::test_flag_long_timeout;
--
--const int thread_test::test_flag_acquire_global;
--const int thread_test::test_flag_has_global;
--
--const int thread_test::test_flag_do_work;
--const int thread_test::test_flag_pre_poke;
--const int thread_test::test_flag_post_poke;
--
--void throw_shutdown_exception() { throw torrent::shutdown_exception(); }
--
--thread_test::thread_test() :
-- m_test_state(TEST_NONE),
-- m_test_flags(0) {
--}
--
--void
--thread_test::init_thread() {
-- m_state = STATE_INITIALIZED;
-- m_test_state = TEST_PRE_START;
-- m_poll = torrent::PollSelect::create(256);
--}
--
--void
--thread_test::call_events() {
-- if ((m_test_flags & test_flag_pre_stop) && m_test_state == TEST_PRE_START && m_state == STATE_ACTIVE)
-- __sync_lock_test_and_set(&m_test_state, TEST_PRE_STOP);
--
-- if ((m_test_flags & test_flag_acquire_global)) {
-- acquire_global_lock();
-- __sync_and_and_fetch(&m_test_flags, ~test_flag_acquire_global);
-- __sync_or_and_fetch(&m_test_flags, test_flag_has_global);
-- }
--
-- if ((m_flags & flag_do_shutdown)) {
-- if ((m_flags & flag_did_shutdown))
-- throw torrent::internal_error("Already trigged shutdown.");
--
-- __sync_or_and_fetch(&m_flags, flag_did_shutdown);
-- throw torrent::shutdown_exception();
-- }
--
-- if ((m_test_flags & test_flag_pre_poke)) {
-- }
--
-- if ((m_test_flags & test_flag_do_work)) {
-- usleep(10 * 1000); // TODO: Don't just sleep, as that give up core.
-- __sync_and_and_fetch(&m_test_flags, ~test_flag_do_work);
-- }
--
-- if ((m_test_flags & test_flag_post_poke)) {
-- }
--}
--
--bool
--wait_for_true(std::function<bool ()> test_function) {
-- int i = 100;
--
-- do {
-- if (test_function())
-- return true;
--
-- usleep(10 * 1000);
-- } while (--i);
--
-- return false;
--}
--
--void
--utils_thread_base_test::setUp() {
--}
--
--void
--utils_thread_base_test::tearDown() {
-- CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
-- torrent::thread_base::release_global_lock();
--}
--
--void
--utils_thread_base_test::test_basic() {
-- thread_test* thread = new thread_test;
--
-- CPPUNIT_ASSERT(thread->flags() == 0);
--
-- CPPUNIT_ASSERT(!thread->is_main_polling());
-- CPPUNIT_ASSERT(!thread->is_active());
-- CPPUNIT_ASSERT(thread->global_queue_size() == 0);
-- CPPUNIT_ASSERT(thread->poll() == NULL);
--
-- // Check active...
--}
--
--void
--utils_thread_base_test::test_lifecycle() {
-- thread_test* thread = new thread_test;
--
-- CPPUNIT_ASSERT(thread->state() == torrent::thread_base::STATE_UNKNOWN);
-- CPPUNIT_ASSERT(thread->test_state() == thread_test::TEST_NONE);
--
-- thread->init_thread();
-- CPPUNIT_ASSERT(thread->state() == torrent::thread_base::STATE_INITIALIZED);
-- CPPUNIT_ASSERT(thread->is_initialized());
-- CPPUNIT_ASSERT(thread->test_state() == thread_test::TEST_PRE_START);
--
-- thread->set_pre_stop();
-- CPPUNIT_ASSERT(!wait_for_true(std::bind(&thread_test::is_test_state, thread, thread_test::TEST_PRE_STOP)));
--
-- thread->start_thread();
-- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_state, thread, thread_test::STATE_ACTIVE)));
-- CPPUNIT_ASSERT(thread->is_active());
-- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_test_state, thread, thread_test::TEST_PRE_STOP)));
--
-- thread->stop_thread();
-- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_state, thread, thread_test::STATE_INACTIVE)));
-- CPPUNIT_ASSERT(thread->is_inactive());
--
-- delete thread;
--}
--
--void
--utils_thread_base_test::test_global_lock_basic() {
-- thread_test* thread = new thread_test;
--
-- thread->init_thread();
-- thread->start_thread();
--
-- CPPUNIT_ASSERT(torrent::thread_base::global_queue_size() == 0);
--
-- // Acquire main thread...
-- CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
-- CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock());
--
-- torrent::thread_base::release_global_lock();
-- CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
-- CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock());
--
-- torrent::thread_base::release_global_lock();
-- torrent::thread_base::acquire_global_lock();
-- CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock());
--
-- thread->set_acquire_global();
-- CPPUNIT_ASSERT(!wait_for_true(std::bind(&thread_test::is_test_flags, thread, thread_test::test_flag_has_global)));
--
-- torrent::thread_base::release_global_lock();
-- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_test_flags, thread, thread_test::test_flag_has_global)));
--
-- CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock());
-- torrent::thread_base::release_global_lock();
-- CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
--
-- // Test waive (loop).
--
-- CPPUNIT_ASSERT(torrent::thread_base::global_queue_size() == 0);
--
-- torrent::thread_base::release_global_lock();
-- thread->stop_thread();
-- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_state, thread, thread_test::STATE_INACTIVE)));
--
-- delete thread;
--}
--
--void
--utils_thread_base_test::test_interrupt() {
-- thread_test* thread = new thread_test;
-- thread->set_test_flag(thread_test::test_flag_long_timeout);
--
-- thread->init_thread();
-- thread->start_thread();
--
-- // Vary the various timeouts.
--
-- for (int i = 0; i < 100; i++) {
-- thread->interrupt();
-- usleep(0);
--
-- thread->set_test_flag(thread_test::test_flag_do_work);
-- thread->interrupt();
--
-- // Wait for flag to clear.
-- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_not_test_flags, thread, thread_test::test_flag_do_work)));
-- }
--
-- thread->stop_thread();
-- CPPUNIT_ASSERT(wait_for_true(std::bind(&thread_test::is_state, thread, thread_test::STATE_INACTIVE)));
--
-- delete thread;
--}
--
--void
--utils_thread_base_test::test_stop() {
-- CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock());
-- // torrent::thread_base::acquire_global_lock();
--
-- for (int i = 0; i < 20; i++) {
-- CPPUNIT_ASSERT(!torrent::thread_base::trylock_global_lock());
--
-- thread_test* thread = new thread_test;
-- thread->set_test_flag(thread_test::test_flag_do_work);
--
-- thread->init_thread();
-- thread->start_thread();
--
-- thread->stop_thread_wait();
-- CPPUNIT_ASSERT(thread->is_inactive());
--
-- delete thread;
-- }
--
-- torrent::thread_base::release_global_lock();
--}
-diff --git a/test/torrent/utils/thread_base_test.h b/test/torrent/utils/thread_base_test.h
-deleted file mode 100644
-index 22eb99dc..00000000
---- a/test/torrent/utils/thread_base_test.h
-+++ /dev/null
-@@ -1,86 +0,0 @@
--#include <cppunit/extensions/HelperMacros.h>
--
--#include "torrent/utils/thread_base.h"
--
--class utils_thread_base_test : public CppUnit::TestFixture {
-- CPPUNIT_TEST_SUITE(utils_thread_base_test);
-- CPPUNIT_TEST(test_basic);
-- CPPUNIT_TEST(test_lifecycle);
--
-- CPPUNIT_TEST(test_global_lock_basic);
-- CPPUNIT_TEST(test_interrupt);
-- CPPUNIT_TEST(test_stop);
-- CPPUNIT_TEST_SUITE_END();
--
--public:
-- void setUp();
-- void tearDown();
--
-- void test_basic();
-- void test_lifecycle();
--
-- void test_global_lock_basic();
-- void test_interrupt();
-- void test_interrupt_legacy();
-- void test_stop();
--};
--
--struct thread_management_type {
-- thread_management_type() { CPPUNIT_ASSERT(torrent::thread_base::trylock_global_lock()); }
-- ~thread_management_type() { torrent::thread_base::release_global_lock(); }
--};
--
--#define SETUP_THREAD() \
-- thread_management_type thread_management; \
-- torrent::thread_disk* thread_disk = new torrent::thread_disk(); \
-- thread_disk->init_thread();
--
--#define CLEANUP_THREAD() \
-- CPPUNIT_ASSERT(wait_for_true(std::bind(&torrent::thread_base::is_inactive, thread_disk))); \
-- delete thread_disk;
--
--bool wait_for_true(std::function<bool ()> test_function);
--
--class thread_test : public torrent::thread_base {
--public:
-- enum test_state {
-- TEST_NONE,
-- TEST_PRE_START,
-- TEST_PRE_STOP,
-- TEST_STOP
-- };
--
-- static const int test_flag_pre_stop = 0x1;
-- static const int test_flag_long_timeout = 0x2;
--
-- static const int test_flag_acquire_global = 0x10;
-- static const int test_flag_has_global = 0x20;
--
-- static const int test_flag_do_work = 0x100;
-- static const int test_flag_pre_poke = 0x200;
-- static const int test_flag_post_poke = 0x400;
--
-- thread_test();
--
-- int test_state() const { return m_test_state; }
-- bool is_state(int state) const { return m_state == state; }
-- bool is_test_state(int state) const { return m_test_state == state; }
-- bool is_test_flags(int flags) const { return (m_test_flags & flags) == flags; }
-- bool is_not_test_flags(int flags) const { return !(m_test_flags & flags); }
--
-- const char* name() const { return "test_thread"; }
--
-- void init_thread();
--
-- void set_pre_stop() { __sync_or_and_fetch(&m_test_flags, test_flag_pre_stop); }
-- void set_acquire_global() { __sync_or_and_fetch(&m_test_flags, test_flag_acquire_global); }
--
-- void set_test_flag(int flags) { __sync_or_and_fetch(&m_test_flags, flags); }
--
--private:
-- void call_events();
-- int64_t next_timeout_usec() { return (m_test_flags & test_flag_long_timeout) ? (10000 * 1000) : (100 * 1000); }
--
-- int m_test_state lt_cacheline_aligned;
-- int m_test_flags lt_cacheline_aligned;
--};
-diff --git a/test/tracker/test_tracker_http.cc b/test/tracker/test_tracker_http.cc
-new file mode 100644
-index 00000000..399d00d5
---- /dev/null
-+++ b/test/tracker/test_tracker_http.cc
-@@ -0,0 +1,11 @@
-+#include "config.h"
-+
-+#include "test_tracker_http.h"
-+
-+#include "tracker/tracker_http.h"
-+
-+CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_tracker_http, "tracker");
-+
-+void
-+test_tracker_http::test_basic() {
-+}
-diff --git a/test/tracker/test_tracker_http.h b/test/tracker/test_tracker_http.h
-new file mode 100644
-index 00000000..ab11a8f7
---- /dev/null
-+++ b/test/tracker/test_tracker_http.h
-@@ -0,0 +1,12 @@
-+#include "helpers/test_fixture.h"
-+
-+#include "torrent/utils/thread_base.h"
-+
-+class test_tracker_http : public test_fixture {
-+ CPPUNIT_TEST_SUITE(test_tracker_http);
-+ CPPUNIT_TEST(test_basic);
-+ CPPUNIT_TEST_SUITE_END();
-+
-+public:
-+ void test_basic();
-+};
-diff --git a/test/tracker/tracker_http_test.cc b/test/tracker/tracker_http_test.cc
-deleted file mode 100644
-index deda4382..00000000
---- a/test/tracker/tracker_http_test.cc
-+++ /dev/null
-@@ -1,17 +0,0 @@
--#include "config.h"
--
--#include "tracker_http_test.h"
--
--#include "tracker/tracker_http.h"
--
--void
--tracker_http_test::setUp() {
--}
--
--void
--tracker_http_test::tearDown() {
--}
--
--void
--tracker_http_test::test_basic() {
--}
-diff --git a/test/tracker/tracker_http_test.h b/test/tracker/tracker_http_test.h
-deleted file mode 100644
-index 11ff8246..00000000
---- a/test/tracker/tracker_http_test.h
-+++ /dev/null
-@@ -1,18 +0,0 @@
--#include <cppunit/extensions/HelperMacros.h>
--
--#include "tracker/tracker_http.h"
--
--class tracker_http_test : public CppUnit::TestFixture {
-- CPPUNIT_TEST_SUITE(tracker_http_test);
-- CPPUNIT_TEST(test_basic);
-- CPPUNIT_TEST(test_scrape);
-- CPPUNIT_TEST_SUITE_END();
--
--public:
-- void setUp();
-- void tearDown();
--
-- void test_basic();
--
-- void test_scrape();
--};
deleted file mode 100644
@@ -1,22 +0,0 @@
-From 03e1c95987917bf98534e50fdd718a948540ffb2 Mon Sep 17 00:00:00 2001
-From: rakshasa <sundell.software@gmail.com>
-Date: Thu, 25 Feb 2021 00:03:27 +0900
-Subject: [PATCH] Changes automake required files.
-
----
- autogen.sh | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/autogen.sh b/autogen.sh
-index 79afab8e..6def96dd 100755
---- a/autogen.sh
-+++ b/autogen.sh
-@@ -36,7 +36,7 @@ echo automake...
- exit 1
- }
-
--automake --add-missing --copy --gnu || exit 1
-+automake --add-missing --copy --foreign || exit 1
-
- echo autoconf...
- (autoconf --version) < /dev/null > /dev/null 2>&1 || {
deleted file mode 100644
@@ -1,48 +0,0 @@
-From b4a3888bd891d804a83ae1cee623592725975895 Mon Sep 17 00:00:00 2001
-From: rakshasa <sundell.software@gmail.com>
-Date: Sat, 27 Feb 2021 22:11:55 +0900
-Subject: [PATCH] Replaced custom execinfo autoconf test.
-
----
- configure.ac | 2 +-
- scripts/rak_execinfo.m4 | 11 -----------
- 2 files changed, 1 insertion(+), 12 deletions(-)
- delete mode 100644 scripts/rak_execinfo.m4
-
-diff --git a/configure.ac b/configure.ac
-index 88a46edd..197bbc94 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -34,7 +34,6 @@ RAK_CHECK_CXXFLAGS
- RAK_ENABLE_DEBUG
- RAK_ENABLE_EXTRA_DEBUG
- RAK_ENABLE_WERROR
--RAK_DISABLE_BACKTRACE
-
- RAK_CHECK_CXX11
-
-@@ -58,6 +57,7 @@ TORRENT_WITH_INOTIFY
- CC_ATTRIBUTE_VISIBILITY
-
- AX_CHECK_ZLIB
-+AX_EXECINFO
- AX_PTHREAD
-
- PKG_CHECK_MODULES([CPPUNIT], [cppunit],, [no_cppunit="yes"])
-diff --git a/scripts/rak_execinfo.m4 b/scripts/rak_execinfo.m4
-deleted file mode 100644
-index c1d9b2f8..00000000
---- a/scripts/rak_execinfo.m4
-+++ /dev/null
-@@ -1,11 +0,0 @@
--AC_DEFUN([RAK_DISABLE_BACKTRACE], [
-- AC_ARG_ENABLE(backtrace,
-- AC_HELP_STRING([--disable-backtrace], [disable backtrace information [[default=no]]]),
-- [
-- if test "$enableval" = "yes"; then
-- AX_EXECINFO
-- fi
-- ],[
-- AX_EXECINFO
-- ])
--])
deleted file mode 100644
@@ -1,135 +0,0 @@
-From e5ed6301e0d07adeaab10e9924a8c9a2e327cdc5 Mon Sep 17 00:00:00 2001
-From: rakshasa <sundell.software@gmail.com>
-Date: Thu, 29 Apr 2021 19:33:04 +0900
-Subject: [PATCH] Added option to disable pthread_setname_np.
-
----
- configure.ac | 30 +++++++++++++++++++-----------
- scripts/checks.m4 | 18 ++++++++++++++++++
- src/torrent/utils/thread_base.cc | 16 ++++++++++++++--
- 3 files changed, 51 insertions(+), 13 deletions(-)
-
-diff --git a/configure.ac b/configure.ac
-index 197bbc94..73caf712 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -24,9 +24,9 @@ AC_PROG_CXX
- AC_SYS_LARGEFILE
-
- AC_C_BIGENDIAN(
-- AC_DEFINE(IS_BIG_ENDIAN, 1, Big endian),
-- AC_DEFINE(IS_LITTLE_ENDIAN, 1, Little endian),
-- AC_MSG_ERROR([Could not determine endianness])
-+ AC_DEFINE(IS_BIG_ENDIAN, 1, Big endian),
-+ AC_DEFINE(IS_LITTLE_ENDIAN, 1, Little endian),
-+ AC_MSG_ERROR([Could not determine endianness])
- )
-
- RAK_CHECK_CFLAGS
-@@ -54,7 +54,15 @@ TORRENT_WITHOUT_STATVFS
- TORRENT_WITHOUT_STATFS
- TORRENT_WITH_INOTIFY
-
--CC_ATTRIBUTE_VISIBILITY
-+AC_ARG_ENABLE(attribute-visibility,
-+ AC_HELP_STRING([--disable-attribute-visibility], [disable symbol visibility attribute [[default=enable]]]),
-+ [
-+ if test "$enableval" = "yes"; then
-+ CC_ATTRIBUTE_VISIBILITY
-+ fi
-+ ],[
-+ CC_ATTRIBUTE_VISIBILITY
-+ ])
-
- AX_CHECK_ZLIB
- AX_EXECINFO
-@@ -71,11 +79,11 @@ TORRENT_ARG_CYRUS_RC4
-
- AC_CHECK_FUNCS(posix_memalign)
-
--TORRENT_CHECK_MADVISE()
--TORRENT_CHECK_CACHELINE()
--TORRENT_CHECK_POPCOUNT()
--TORRENT_CHECK_PTHREAD_SETNAME_NP()
--TORRENT_MINCORE()
-+TORRENT_CHECK_MADVISE
-+TORRENT_CHECK_CACHELINE
-+TORRENT_CHECK_POPCOUNT
-+TORRENT_DISABLE_PTHREAD_SETNAME_NP
-+TORRENT_MINCORE
-
- TORRENT_DISABLE_INSTRUMENTATION
-
-@@ -88,8 +96,8 @@ AC_SUBST(LIBTORRENT_CFLAGS)
- AC_DEFINE(HAVE_CONFIG_H, 1, true if config.h was included)
-
- CC_ATTRIBUTE_UNUSED(
-- AC_DEFINE([__UNUSED], [__attribute__((unused))], [Wrapper around unused attribute]),
-- AC_DEFINE([__UNUSED], [], [Null-wrapper if unused attribute is unsupported])
-+ AC_DEFINE([__UNUSED], [__attribute__((unused))], [Wrapper around unused attribute]),
-+ AC_DEFINE([__UNUSED], [], [Null-wrapper if unused attribute is unsupported])
- )
-
- AC_OUTPUT([
-diff --git a/scripts/checks.m4 b/scripts/checks.m4
-index 98ef17f8..915a5011 100644
---- a/scripts/checks.m4
-+++ b/scripts/checks.m4
-@@ -490,3 +490,21 @@ AC_DEFUN([TORRENT_CHECK_PTHREAD_SETNAME_NP], [
- ])
- ])
- ])
-+
-+AC_DEFUN([TORRENT_DISABLE_PTHREAD_SETNAME_NP], [
-+ AC_MSG_CHECKING([for pthread_setname_no])
-+
-+ AC_ARG_ENABLE(pthread-setname-np,
-+ AC_HELP_STRING([--disable-pthread-setname-np], [disable pthread_setname_np]),
-+ [
-+ if test "$enableval" = "no"; then
-+ AC_MSG_RESULT(disabled)
-+ else
-+ AC_MSG_RESULT(checking)
-+ TORRENT_CHECK_PTHREAD_SETNAME_NP
-+ fi
-+ ], [
-+ TORRENT_CHECK_PTHREAD_SETNAME_NP
-+ ]
-+ )
-+])
-diff --git a/src/torrent/utils/thread_base.cc b/src/torrent/utils/thread_base.cc
-index 99d6355d..ec0619f3 100644
---- a/src/torrent/utils/thread_base.cc
-+++ b/src/torrent/utils/thread_base.cc
-@@ -41,10 +41,16 @@ thread_base::~thread_base() {
-
- void
- thread_base::start_thread() {
-- if (m_poll == NULL)
-+ if (this == nullptr)
-+ throw internal_error("Called thread_base::start_thread on a nullptr.");
-+
-+ if (m_poll == nullptr)
- throw internal_error("No poll object for thread defined.");
-
-- if (!is_initialized() || pthread_create(&m_thread, NULL, (pthread_func)&thread_base::event_loop, this))
-+ if (!is_initialized())
-+ throw internal_error("Called thread_base::start_thread on an uninitialized object.");
-+
-+ if (pthread_create(&m_thread, NULL, (pthread_func)&thread_base::event_loop, this))
- throw internal_error("Failed to create thread.");
- }
-
-@@ -82,6 +88,12 @@ thread_base::should_handle_sigusr1() {
-
- void*
- thread_base::event_loop(thread_base* thread) {
-+ if (thread == nullptr)
-+ throw internal_error("thread_base::event_loop called with a null pointer thread");
-+
-+ if (!thread->is_initialized())
-+ throw internal_error("thread_base::event_loop call on an uninitialized object");
-+
- __sync_lock_test_and_set(&thread->m_state, STATE_ACTIVE);
-
- #if defined(HAS_PTHREAD_SETNAME_NP_DARWIN)
deleted file mode 100644
@@ -1,594 +0,0 @@
-From f978e68f9d907e25207d0a7d247d2b10935e5d76 Mon Sep 17 00:00:00 2001
-From: rakshasa <sundell.software@gmail.com>
-Date: Thu, 29 Apr 2021 19:34:35 +0900
-Subject: [PATCH] Improved backtrace error checking.
-
----
- src/download/download_main.cc | 36 -------------
- src/download/download_main.h | 36 -------------
- src/download/download_wrapper.cc | 43 ++--------------
- src/torrent/data/download_data.h | 36 -------------
- src/torrent/download/choke_queue.cc | 50 +++++-------------
- src/torrent/download/resource_manager.cc | 53 +++++--------------
- src/torrent/exceptions.cc | 65 +++++++-----------------
- src/torrent/torrent.cc | 1 +
- src/torrent/utils/extents.h | 36 -------------
- src/torrent/utils/signal_bitfield.cc | 36 -------------
- 10 files changed, 48 insertions(+), 344 deletions(-)
-
-diff --git a/src/download/download_main.cc b/src/download/download_main.cc
-index 9a3f9df2..e075038a 100644
---- a/src/download/download_main.cc
-+++ b/src/download/download_main.cc
-@@ -1,39 +1,3 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #include "config.h"
-
- #include <cstring>
-diff --git a/src/download/download_main.h b/src/download/download_main.h
-index da3cf182..4783e863 100644
---- a/src/download/download_main.h
-+++ b/src/download/download_main.h
-@@ -1,39 +1,3 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #ifndef LIBTORRENT_DOWNLOAD_MAIN_H
- #define LIBTORRENT_DOWNLOAD_MAIN_H
-
-diff --git a/src/download/download_wrapper.cc b/src/download/download_wrapper.cc
-index 59e81781..304bddce 100644
---- a/src/download/download_wrapper.cc
-+++ b/src/download/download_wrapper.cc
-@@ -1,39 +1,3 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #include "config.h"
-
- #include <iterator>
-@@ -62,6 +26,8 @@
-
- #include "download_wrapper.h"
-
-+#define LT_LOG_THIS(log_fmt, ...) \
-+ lt_log_print_info(LOG_TORRENT_INFO, this->info(), "download", log_fmt, __VA_ARGS__);
- #define LT_LOG_STORAGE_ERRORS(log_fmt, ...) \
- lt_log_print_info(LOG_PROTOCOL_STORAGE_ERRORS, this->info(), "storage_errors", log_fmt, __VA_ARGS__);
-
-@@ -325,8 +291,8 @@ DownloadWrapper::receive_tick(uint32_t ticks) {
-
- void
- DownloadWrapper::receive_update_priorities() {
-- if (m_main->chunk_selector()->empty())
-- return;
-+ LT_LOG_THIS("update priorities: chunks_selected:%" PRIu32 " wanted_chunks:%" PRIu32,
-+ m_main->chunk_selector()->size(), data()->wanted_chunks());
-
- data()->mutable_high_priority()->clear();
- data()->mutable_normal_priority()->clear();
-@@ -359,7 +325,6 @@ DownloadWrapper::receive_update_priorities() {
- }
-
- bool was_partial = data()->wanted_chunks() != 0;
--
- data()->update_wanted_chunks();
-
- m_main->chunk_selector()->update_priorities();
-diff --git a/src/torrent/data/download_data.h b/src/torrent/data/download_data.h
-index fc212047..c701cb2f 100644
---- a/src/torrent/data/download_data.h
-+++ b/src/torrent/data/download_data.h
-@@ -1,39 +1,3 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #ifndef LIBTORRENT_DATA_DOWNLOAD_DATA_H
- #define LIBTORRENT_DATA_DOWNLOAD_DATA_H
-
-diff --git a/src/torrent/download/choke_queue.cc b/src/torrent/download/choke_queue.cc
-index 7c00b686..edf47795 100644
---- a/src/torrent/download/choke_queue.cc
-+++ b/src/torrent/download/choke_queue.cc
-@@ -1,39 +1,3 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #include "config.h"
-
- #include <algorithm>
-@@ -50,6 +14,10 @@
-
- #include "choke_queue.h"
-
-+// TODO: Add a different logging category.
-+#define LT_LOG_THIS(log_fmt, ...) \
-+ lt_log_print_subsystem(LOG_TORRENT_INFO, "choke_queue", log_fmt, __VA_ARGS__);
-+
- namespace torrent {
-
- struct choke_manager_less {
-@@ -193,6 +161,9 @@ choke_queue::rebuild_containers(container_type* queued, container_type* unchoked
-
- void
- choke_queue::balance() {
-+ LT_LOG_THIS("balancing queue: heuristics:%i currently_unchoked:%" PRIu32 " max_unchoked:%" PRIu32,
-+ m_heuristics, m_currently_unchoked, m_maxUnchoked)
-+
- // Return if no balancing is needed. Don't return if is_unlimited()
- // as we might have just changed the value and have interested that
- // can be unchoked.
-@@ -216,6 +187,9 @@ choke_queue::balance() {
-
- // If we have more unchoked than max global slots allow for,
- // 'can_unchoke' will be negative.
-+ //
-+ // Throws std::bad_function_call if 'set_slot_can_unchoke' is not
-+ // set.
- int can_unchoke = m_slotCanUnchoke();
- int max_unchoked = std::min(m_maxUnchoked, (uint32_t)(1 << 20));
-
-@@ -240,8 +214,8 @@ choke_queue::balance() {
- if (result != 0)
- m_slotUnchoke(result);
-
-- lt_log_print(LOG_PEER_DEBUG, "Called balance; adjust:%i can_unchoke:%i queued:%u unchoked:%u result:%i.",
-- adjust, can_unchoke, (unsigned)queued.size(), (unsigned)unchoked.size(), result);
-+ LT_LOG_THIS("balanced queue: adjust:%i can_unchoke:%i queued:%" PRIu32 " unchoked:%" PRIu32 " result:%i",
-+ adjust, can_unchoke, queued.size(), unchoked.size(), result);
- }
-
- void
-diff --git a/src/torrent/download/resource_manager.cc b/src/torrent/download/resource_manager.cc
-index 51434c91..8ca7b02e 100644
---- a/src/torrent/download/resource_manager.cc
-+++ b/src/torrent/download/resource_manager.cc
-@@ -1,39 +1,3 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #include "config.h"
-
- #include <algorithm>
-@@ -51,6 +15,11 @@
- #include "choke_queue.h"
- #include "resource_manager.h"
-
-+#define LT_LOG_THIS(log_fmt, ...) \
-+ lt_log_print_subsystem(LOG_TORRENT_INFO, "resource_manager", log_fmt, __VA_ARGS__);
-+#define LT_LOG_ITR(log_fmt, ...) \
-+ lt_log_print_info(LOG_TORRENT_INFO, itr->download()->info(), "resource_manager", log_fmt, __VA_ARGS__);
-+
- namespace torrent {
-
- const Rate* resource_manager_entry::up_rate() const { return m_download->info()->up_rate(); }
-@@ -226,6 +195,8 @@ ResourceManager::group_index_of(const std::string& name) {
-
- void
- ResourceManager::set_priority(iterator itr, uint16_t pri) {
-+ LT_LOG_ITR("set priority: %" PRIu16, 0)
-+
- itr->set_priority(pri);
- }
-
-@@ -283,7 +254,7 @@ ResourceManager::set_max_download_unchoked(unsigned int m) {
- // possibly multiple calls of this function.
- void
- ResourceManager::receive_upload_unchoke(int num) {
-- lt_log_print(LOG_PEER_INFO, "Upload unchoked slots adjust; currently:%u adjust:%i", m_currentlyUploadUnchoked, num);
-+ LT_LOG_THIS("adjusting upload unchoked slots; current:%u adjusted:%i", m_currentlyUploadUnchoked, num);
-
- if ((int)m_currentlyUploadUnchoked + num < 0)
- throw internal_error("ResourceManager::receive_upload_unchoke(...) received an invalid value.");
-@@ -293,7 +264,7 @@ ResourceManager::receive_upload_unchoke(int num) {
-
- void
- ResourceManager::receive_download_unchoke(int num) {
-- lt_log_print(LOG_PEER_INFO, "Download unchoked slots adjust; currently:%u adjust:%i", m_currentlyDownloadUnchoked, num);
-+ LT_LOG_THIS("adjusting download unchoked slots; current:%u adjusted:%i", m_currentlyDownloadUnchoked, num);
-
- if ((int)m_currentlyDownloadUnchoked + num < 0)
- throw internal_error("ResourceManager::receive_download_unchoke(...) received an invalid value.");
-@@ -387,12 +358,14 @@ ResourceManager::balance_unchoked(unsigned int weight, unsigned int max_unchoked
- std::sort(group_first, group_last, std::bind(std::less<uint32_t>(),
- std::bind(&choke_group::up_requested, std::placeholders::_1),
- std::bind(&choke_group::up_requested, std::placeholders::_2)));
-- lt_log_print(LOG_PEER_DEBUG, "Upload unchoked slots cycle; currently:%u adjusted:%i max_unchoked:%u", m_currentlyUploadUnchoked, change, max_unchoked);
-+
-+ LT_LOG_THIS("balancing upload unchoked slots; current_unchoked:%u change:%i max_unchoked:%u", m_currentlyUploadUnchoked, change, max_unchoked);
- } else {
- std::sort(group_first, group_last, std::bind(std::less<uint32_t>(),
- std::bind(&choke_group::down_requested, std::placeholders::_1),
- std::bind(&choke_group::down_requested, std::placeholders::_2)));
-- lt_log_print(LOG_PEER_DEBUG, "Download unchoked slots cycle; currently:%u adjusted:%i max_unchoked:%u", m_currentlyDownloadUnchoked, change, max_unchoked);
-+
-+ LT_LOG_THIS("balancing download unchoked slots; current_unchoked:%u change:%i max_unchoked:%u", m_currentlyDownloadUnchoked, change, max_unchoked);
- }
-
- while (group_first != group_last) {
-diff --git a/src/torrent/exceptions.cc b/src/torrent/exceptions.cc
-index f834f9fa..7375ed8e 100644
---- a/src/torrent/exceptions.cc
-+++ b/src/torrent/exceptions.cc
-@@ -1,39 +1,3 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #include "config.h"
-
- #include <cerrno>
-@@ -73,23 +37,30 @@ void
- internal_error::initialize(const std::string& msg) {
- m_msg = msg;
-
-- std::stringstream output;
--
- #ifdef HAVE_BACKTRACE
-- void* stackPtrs[20];
-+ void* stack_ptrs[20];
-+ int stack_size = ::backtrace(stack_ptrs, 20);
-+ char** stack_symbol_names = ::backtrace_symbols(stack_ptrs, stack_size);
-
-- // Print the stack and exit.
-- int stackSize = ::backtrace(stackPtrs, 20);
-- char** stackStrings = backtrace_symbols(stackPtrs, stackSize);
-+ if (stack_symbol_names == nullptr) {
-+ m_backtrace = "backtrace_symbols failed";
-+ return;
-+ }
-
-- for (int i = 0; i < stackSize; ++i)
-- output << stackStrings[i] << std::endl;
-+ std::stringstream output;
-
--#else
-- output << "Stack dump not enabled." << std::endl;
--#endif
-+ for (int i = 0; i < stack_size; ++i) {
-+ if (stack_symbol_names[i] != nullptr && stack_symbol_names[i] > (void*)0x1000)
-+ output << stack_symbol_names[i] << std::endl;
-+ else
-+ output << "stack_symbol: nullptr" << std::endl;
-+ }
-
- m_backtrace = output.str();
-+
-+#else
-+ m_backtrace = "stack dump not enabled";
-+#endif
- }
-
- }
-diff --git a/src/torrent/torrent.cc b/src/torrent/torrent.cc
-index fb70d247..67de4387 100644
---- a/src/torrent/torrent.cc
-+++ b/src/torrent/torrent.cc
-@@ -203,6 +203,7 @@ download_priority(Download d) {
- return itr->priority();
- }
-
-+// TODO: Remove this.
- void
- download_set_priority(Download d, uint32_t pri) {
- ResourceManager::iterator itr = manager->resource_manager()->find(d.ptr()->main());
-diff --git a/src/torrent/utils/extents.h b/src/torrent/utils/extents.h
-index c2b887b1..64605d4a 100644
---- a/src/torrent/utils/extents.h
-+++ b/src/torrent/utils/extents.h
-@@ -1,39 +1,3 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #ifndef LIBTORRENT_UTILS_EXTENTS_H
- #define LIBTORRENT_UTILS_EXTENTS_H
-
-diff --git a/src/torrent/utils/signal_bitfield.cc b/src/torrent/utils/signal_bitfield.cc
-index 82f81e7c..dfc3d1fe 100644
---- a/src/torrent/utils/signal_bitfield.cc
-+++ b/src/torrent/utils/signal_bitfield.cc
-@@ -1,39 +1,3 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #include "config.h"
-
- #include "torrent/exceptions.h"
deleted file mode 100644
@@ -1,199 +0,0 @@
-From cabc557fdf6f12fee7029081de2cf5de88464c21 Mon Sep 17 00:00:00 2001
-From: rakshasa <sundell.software@gmail.com>
-Date: Thu, 29 Apr 2021 21:27:50 +0900
-Subject: [PATCH] Fixed issue with multiple connections from NAT not working.
-
----
- src/protocol/handshake.cc | 36 -------------------
- src/torrent/peer/peer_list.cc | 68 +++++++++++------------------------
- src/torrent/peer/peer_list.h | 36 -------------------
- 3 files changed, 20 insertions(+), 120 deletions(-)
-
-diff --git a/src/protocol/handshake.cc b/src/protocol/handshake.cc
-index 1b877c7a..d6f48e59 100644
---- a/src/protocol/handshake.cc
-+++ b/src/protocol/handshake.cc
-@@ -1,39 +1,3 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #include "config.h"
-
- #include <stdio.h>
-diff --git a/src/torrent/peer/peer_list.cc b/src/torrent/peer/peer_list.cc
-index 080a7f13..6ce630f7 100644
---- a/src/torrent/peer/peer_list.cc
-+++ b/src/torrent/peer/peer_list.cc
-@@ -1,39 +1,3 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #include "config.h"
-
- #include <algorithm>
-@@ -262,8 +226,11 @@ PeerList::available_list_size() const {
- return m_available_list->size();
- }
-
-+// TODO: Rename connecting:
- PeerInfo*
- PeerList::connected(const sockaddr* sa, int flags) {
-+ // TODO: Rewrite to use new socket address api after fixing bug.
-+
- const rak::socket_address* address = rak::socket_address::cast_from(sa);
- socket_address_key sock_key = socket_address_key::from_sockaddr(sa);
-
-@@ -281,13 +248,7 @@ PeerList::connected(const sockaddr* sa, int flags) {
- // We should also remove any PeerInfo objects already for this
- // address.
- if ((filter_value & PeerInfo::flag_unwanted)) {
-- char ipv4_str[INET_ADDRSTRLEN];
-- uint32_t net_order_addr = htonl(host_byte_order_ipv4_addr);
--
-- inet_ntop(AF_INET, &net_order_addr, ipv4_str, INET_ADDRSTRLEN);
--
-- lt_log_print(LOG_PEER_INFO, "Peer %s is unwanted: preventing connection", ipv4_str);
--
-+ LT_LOG_EVENTS("connecting peer rejected, flagged as unwanted: " LT_LOG_SA_FMT, address->address_str().c_str(), address->port());
- return NULL;
- }
-
-@@ -313,12 +274,23 @@ PeerList::connected(const sockaddr* sa, int flags) {
- //
- // This also ensure we can connect to peers running on the same
- // host as the tracker.
-- if (flags & connect_keep_handshakes &&
-- range.first->second->is_handshake() &&
-- rak::socket_address::cast_from(range.first->second->socket_address())->port() != address->port())
-- m_available_list->buffer()->push_back(*address);
-+ // if (flags & connect_keep_handshakes &&
-+ // range.first->second->is_handshake() &&
-+ // rak::socket_address::cast_from(range.first->second->socket_address())->port() != address->port())
-+ // m_available_list->buffer()->push_back(*address);
-
-- return NULL;
-+ LT_LOG_EVENTS("connecting peer rejected, already connected (buggy, fixme): " LT_LOG_SA_FMT, address->address_str().c_str(), address->port());
-+
-+ // TODO: Verify this works properly, possibly add a check/flag
-+ // that allows the handshake manager to notify peer list if the
-+ // incoming connection was a duplicate peer hash.
-+
-+ //return NULL;
-+
-+ peerInfo = new PeerInfo(sa);
-+ peerInfo->set_flags(filter_value & PeerInfo::mask_ip_table);
-+
-+ base_type::insert(range.second, value_type(sock_key, peerInfo));
- }
-
- if (flags & connect_filter_recent &&
-diff --git a/src/torrent/peer/peer_list.h b/src/torrent/peer/peer_list.h
-index 4c2f707d..a9d31a54 100644
---- a/src/torrent/peer/peer_list.h
-+++ b/src/torrent/peer/peer_list.h
-@@ -1,39 +1,3 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
- #ifndef LIBTORRENT_PEER_LIST_H
- #define LIBTORRENT_PEER_LIST_H
-
deleted file mode 100644
@@ -1,32 +0,0 @@
-From 532d3e54b3f012dc81530ebb80ded8b26434fdd9 Mon Sep 17 00:00:00 2001
-From: rakshasa <sundell.software@gmail.com>
-Date: Wed, 16 Jun 2021 23:28:28 +0900
-Subject: [PATCH] Added '--disable-execinfo' option to configure.
-
----
- configure.ac | 11 ++++++++++-
- 1 file changed, 10 insertions(+), 1 deletion(-)
-
-diff --git a/configure.ac b/configure.ac
-index 73caf712..a4f051e4 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -64,8 +64,17 @@ AC_ARG_ENABLE(attribute-visibility,
- CC_ATTRIBUTE_VISIBILITY
- ])
-
-+AC_ARG_ENABLE(execinfo,
-+ AC_HELP_STRING([--disable-execinfo], [disable libexecinfo [[default=enable]]]),
-+ [
-+ if test "$enableval" = "yes"; then
-+ AX_EXECINFO
-+ fi
-+ ],[
-+ AX_EXECINFO
-+ ])
-+
- AX_CHECK_ZLIB
--AX_EXECINFO
- AX_PTHREAD
-
- PKG_CHECK_MODULES([CPPUNIT], [cppunit],, [no_cppunit="yes"])
deleted file mode 100644
@@ -1,457 +0,0 @@
-From 92781533fc4afab67447e8e6d47a649383179c44 Mon Sep 17 00:00:00 2001
-From: rakshasa <sundell.software@gmail.com>
-Date: Sun, 20 Jun 2021 18:10:52 +0900
-Subject: [PATCH] Detect ip address.
-
----
- src/net/local_addr.cc | 6 +-
- src/torrent/Makefile.am | 5 +-
- src/torrent/net/fd.cc | 3 +
- src/torrent/net/fd.h | 14 ++--
- src/torrent/net/socket_address.cc | 2 +-
- src/torrent/net/socket_address.h | 2 +-
- src/torrent/net/utils.cc | 104 ++++++++++++++++++++++++
- src/torrent/net/utils.h | 9 ++
- src/tracker/tracker_http.cc | 104 ++++++++----------------
- test/helpers/network.h | 2 +
- test/torrent/net/test_fd.cc | 9 ++
- test/torrent/net/test_socket_address.cc | 2 +-
- 12 files changed, 181 insertions(+), 81 deletions(-)
- create mode 100755 src/torrent/net/utils.cc
- create mode 100755 src/torrent/net/utils.h
-
-diff --git a/src/net/local_addr.cc b/src/net/local_addr.cc
-index 24413265..0c7116cb 100644
---- a/src/net/local_addr.cc
-+++ b/src/net/local_addr.cc
-@@ -34,6 +34,8 @@
- // Skomakerveien 33
- // 3185 Skoppum, NORWAY
-
-+// TODO: Remove.
-+
- #include "config.h"
-
- #include <stdio.h>
-@@ -241,7 +243,7 @@ bool get_local_address(sa_family_t family, rak::socket_address *address) {
- int plen = IFA_PAYLOAD(nlmsg);
- for (const rtattr *rta = IFA_RTA(ifa);
- RTA_OK(rta, plen);
-- rta = RTA_NEXT(rta, plen)) {
-+ rta = RTA_NEXT(rta, plen)) {
- if (rta->rta_type != IFA_LOCAL &&
- rta->rta_type != IFA_ADDRESS) {
- continue;
-@@ -303,7 +305,7 @@ get_local_address(sa_family_t family, rak::socket_address *address) {
- dummy_dest.set_address_c_str("4.0.0.0");
- break;
- case rak::socket_address::af_inet6:
-- dummy_dest.set_address_c_str("2001:700::");
-+ dummy_dest.set_address_c_str("2001:1::");
- break;
- default:
- throw internal_error("Unknown address family");
-diff --git a/src/torrent/Makefile.am b/src/torrent/Makefile.am
-index 30157b95..5de7e8ae 100644
---- a/src/torrent/Makefile.am
-+++ b/src/torrent/Makefile.am
-@@ -46,6 +46,8 @@ libtorrent_torrent_la_SOURCES = \
- net/socket_event.cc \
- net/socket_event.h \
- net/types.h \
-+ net/utils.cc \
-+ net/utils.h \
- \
- peer/choke_status.h \
- peer/client_info.cc \
-@@ -167,7 +169,8 @@ libtorrent_torrent_net_include_HEADERS = \
- net/socket_address.h \
- net/socket_address_key.h \
- net/socket_event.h \
-- net/types.h
-+ net/types.h \
-+ net/utils.h
-
- libtorrent_torrent_peer_includedir = $(includedir)/torrent/peer
- libtorrent_torrent_peer_include_HEADERS = \
-diff --git a/src/torrent/net/fd.cc b/src/torrent/net/fd.cc
-index 07c91779..6d228181 100644
---- a/src/torrent/net/fd.cc
-+++ b/src/torrent/net/fd.cc
-@@ -64,6 +64,9 @@ fd_open(fd_flags flags) {
- if ((flags & fd_flag_stream)) {
- domain = SOCK_STREAM;
- protocol = IPPROTO_TCP;
-+ } else if ((flags & fd_flag_datagram)) {
-+ domain = SOCK_DGRAM;
-+ protocol = IPPROTO_UDP;
- } else {
- LT_LOG_FLAG("fd_open missing socket type");
- errno = EINVAL;
-diff --git a/src/torrent/net/fd.h b/src/torrent/net/fd.h
-index a7094646..6ab3302d 100644
---- a/src/torrent/net/fd.h
-+++ b/src/torrent/net/fd.h
-@@ -9,11 +9,12 @@ namespace torrent {
-
- enum fd_flags : int {
- fd_flag_stream = 0x1,
-- fd_flag_nonblock = 0x10,
-- fd_flag_reuse_address = 0x20,
-- fd_flag_v4only = 0x40,
-- fd_flag_v6only = 0x80,
-- fd_flag_all = 0xff,
-+ fd_flag_datagram = 0x10,
-+ fd_flag_nonblock = 0x20,
-+ fd_flag_reuse_address = 0x40,
-+ fd_flag_v4only = 0x80,
-+ fd_flag_v6only = 0x100,
-+ fd_flag_all = 0x1ff,
- };
-
- constexpr bool fd_valid_flags(fd_flags flags);
-@@ -53,7 +54,8 @@ operator |=(fd_flags& lhs, fd_flags rhs) {
- constexpr bool
- fd_valid_flags(fd_flags flags) {
- return
-- (flags & fd_flag_stream) &&
-+ ((flags & fd_flag_stream) || (flags & fd_flag_datagram)) &&
-+ !((flags & fd_flag_stream) && (flags & fd_flag_datagram)) &&
- !((flags & fd_flag_v4only) && (flags & fd_flag_v6only)) &&
- !(flags & ~(fd_flag_all));
- }
-diff --git a/src/torrent/net/socket_address.cc b/src/torrent/net/socket_address.cc
-index c36ba0ae..078bee25 100644
---- a/src/torrent/net/socket_address.cc
-+++ b/src/torrent/net/socket_address.cc
-@@ -135,7 +135,7 @@ sa_unique_ptr
- sa_make_unspec() {
- sa_unique_ptr sa(new sockaddr);
-
-- std::memset(sa.get(), 0, sizeof(sa));
-+ std::memset(sa.get(), 0, sizeof(sockaddr));
- sa.get()->sa_family = AF_UNSPEC;
-
- return sa;
-diff --git a/src/torrent/net/socket_address.h b/src/torrent/net/socket_address.h
-index f64aee68..b9586ca1 100644
---- a/src/torrent/net/socket_address.h
-+++ b/src/torrent/net/socket_address.h
-@@ -102,8 +102,8 @@ bool fd_sap_equal(const fd_sap_tuple& lhs, const fd_sap_tuple& rhs) LIBTORRENT_E
-
- inline bool sap_is_unspec(const sa_unique_ptr& sap) { return sa_is_unspec(sap.get()); }
- inline bool sap_is_unspec(const c_sa_unique_ptr& sap) { return sa_is_unspec(sap.get()); }
--inline bool sap_is_inet(const c_sa_unique_ptr& sap) { return sa_is_inet(sap.get()); }
- inline bool sap_is_inet(const sa_unique_ptr& sap) { return sa_is_inet(sap.get()); }
-+inline bool sap_is_inet(const c_sa_unique_ptr& sap) { return sa_is_inet(sap.get()); }
- inline bool sap_is_inet6(const sa_unique_ptr& sap) { return sa_is_inet6(sap.get()); }
- inline bool sap_is_inet6(const c_sa_unique_ptr& sap) { return sa_is_inet6(sap.get()); }
- inline bool sap_is_inet_inet6(const sa_unique_ptr& sap) { return sa_is_inet_inet6(sap.get()); }
-diff --git a/src/torrent/net/utils.cc b/src/torrent/net/utils.cc
-new file mode 100755
-index 00000000..4cb85924
---- /dev/null
-+++ b/src/torrent/net/utils.cc
-@@ -0,0 +1,104 @@
-+#import <torrent/net/utils.h>
-+
-+#import <cerrno>
-+#import <cstring>
-+#import <torrent/net/fd.h>
-+#import <torrent/net/socket_address.h>
-+#import <torrent/utils/log.h>
-+
-+#define LT_LOG_ERROR(log_fmt) \
-+ lt_log_print(LOG_CONNECTION_FD, "fd: " log_fmt " (errno:%i message:'%s')", \
-+ errno, std::strerror(errno));
-+#define LT_LOG_FD(log_fmt) \
-+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt, fd);
-+#define LT_LOG_FD_ERROR(log_fmt) \
-+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (errno:%i message:'%s')", \
-+ fd, errno, std::strerror(errno));
-+#define LT_LOG_FD_SIN(log_fmt) \
-+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (address:%s)", \
-+ fd, sin_pretty_str(sa.get()).c_str());
-+#define LT_LOG_FD_SIN6(log_fmt) \
-+ lt_log_print(LOG_CONNECTION_FD, "fd->%i: " log_fmt " (address:%s)", \
-+ fd, sin6_pretty_str(sa.get()).c_str());
-+
-+namespace torrent {
-+
-+auto detect_local_sin_addr() -> sin_unique_ptr {
-+ int fd = fd_open(fd_flag_v4only | fd_flag_datagram);
-+ if (fd == -1) {
-+ LT_LOG_ERROR("detect_local_sin_addr: open failed");
-+ return sin_unique_ptr();
-+ }
-+
-+ // TODO: Check if unique_ptr works.
-+ std::shared_ptr<void> _fd(nullptr, [fd](...){ fd_close(fd); });
-+
-+ auto connectAddress = sin_make();
-+ connectAddress.get()->sin_addr.s_addr = htonl(0x04000001);
-+ connectAddress.get()->sin_port = 80;
-+
-+ if (!fd_connect(fd, reinterpret_cast<sockaddr*>(connectAddress.get())) && errno != EINPROGRESS) {
-+ LT_LOG_FD_ERROR("detect_local_sin_addr: connect failed");
-+ return sin_unique_ptr();
-+ }
-+
-+ // TODO: Make sa function.
-+ socklen_t socklen = sizeof(sockaddr_in);
-+
-+ auto sa = sin_make();
-+
-+ if (::getsockname(fd, reinterpret_cast<sockaddr*>(sa.get()), &socklen) != 0) {
-+ LT_LOG_FD_ERROR("detect_local_sin_addr: getsockname failed");
-+ return sin_unique_ptr();
-+ }
-+ if (socklen != sizeof(sockaddr_in)) {
-+ LT_LOG_FD("detect_local_sin_addr: getsockname failed, invalid socklen");
-+ return sin_unique_ptr();
-+ }
-+
-+ LT_LOG_FD_SIN("detect_local_sin_addr: success");
-+
-+ return sa;
-+}
-+
-+auto detect_local_sin6_addr() -> sin6_unique_ptr {
-+ int fd = fd_open(fd_flag_v6only | fd_flag_datagram);
-+ if (fd == -1) {
-+ LT_LOG_ERROR("detect_local_sin6_addr: open failed");
-+ return sin6_unique_ptr();
-+ }
-+
-+ // TODO: Check if unique_ptr works.
-+ std::shared_ptr<void> _fd(nullptr, [fd](...){ fd_close(fd); });
-+
-+ auto connectAddress = sin6_make();
-+ connectAddress.get()->sin6_addr.s6_addr[0] = 0x20;
-+ connectAddress.get()->sin6_addr.s6_addr[1] = 0x01;
-+ connectAddress.get()->sin6_addr.s6_addr[15] = 0x01;
-+ connectAddress.get()->sin6_port = 80;
-+
-+ if (!fd_connect(fd, reinterpret_cast<sockaddr*>(connectAddress.get())) && errno != EINPROGRESS) {
-+ LT_LOG_FD_ERROR("detect_local_sin6_addr: connect failed");
-+ return sin6_unique_ptr();
-+ }
-+
-+ // TODO: Make sa function.
-+ socklen_t socklen = sizeof(sockaddr_in6);
-+
-+ auto sa = sin6_make();
-+
-+ if (::getsockname(fd, reinterpret_cast<sockaddr*>(sa.get()), &socklen) != 0) {
-+ LT_LOG_FD_ERROR("detect_local_sin6_addr: getsockname failed");
-+ return sin6_unique_ptr();
-+ }
-+ if (socklen != sizeof(sockaddr_in6)) {
-+ LT_LOG_FD("detect_local_sin6_addr: getsockname failed, invalid socklen");
-+ return sin6_unique_ptr();
-+ }
-+
-+ LT_LOG_FD_SIN6("detect_local_sin6_addr: success");
-+
-+ return sa;
-+}
-+
-+}
-diff --git a/src/torrent/net/utils.h b/src/torrent/net/utils.h
-new file mode 100755
-index 00000000..1d550c51
---- /dev/null
-+++ b/src/torrent/net/utils.h
-@@ -0,0 +1,9 @@
-+#import <torrent/common.h>
-+#import <torrent/net/socket_address.h>
-+
-+namespace torrent {
-+
-+auto detect_local_sin_addr() -> sin_unique_ptr;
-+auto detect_local_sin6_addr() -> sin6_unique_ptr;
-+
-+}
-diff --git a/src/tracker/tracker_http.cc b/src/tracker/tracker_http.cc
-index 1bf94107..de3a39ab 100644
---- a/src/tracker/tracker_http.cc
-+++ b/src/tracker/tracker_http.cc
-@@ -1,63 +1,29 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2011, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
--#include "config.h"
-+#import "config.h"
-
- #define __STDC_FORMAT_MACROS
-
--#include <iomanip>
--#include <sstream>
--#include <rak/functional.h>
--#include <rak/string_manip.h>
--
--#include "net/address_list.h"
--#include "net/local_addr.h"
--#include "torrent/connection_manager.h"
--#include "torrent/download_info.h"
--#include "torrent/exceptions.h"
--#include "torrent/http.h"
--#include "torrent/object_stream.h"
--#include "torrent/tracker_list.h"
--#include "torrent/utils/log.h"
--#include "torrent/utils/option_strings.h"
--
--#include "tracker_http.h"
--
--#include "globals.h"
--#include "manager.h"
-+#import <iomanip>
-+#import <sstream>
-+#import <rak/functional.h>
-+#import <rak/string_manip.h>
-+
-+#import "net/address_list.h"
-+#import "net/local_addr.h"
-+#import "torrent/connection_manager.h"
-+#import "torrent/download_info.h"
-+#import "torrent/exceptions.h"
-+#import "torrent/http.h"
-+#import "torrent/net/utils.h"
-+#import "torrent/net/socket_address.h"
-+#import "torrent/object_stream.h"
-+#import "torrent/tracker_list.h"
-+#import "torrent/utils/log.h"
-+#import "torrent/utils/option_strings.h"
-+
-+#import "tracker_http.h"
-+
-+#import "globals.h"
-+#import "manager.h"
-
- #define LT_LOG_TRACKER(log_level, log_fmt, ...) \
- lt_log_print_info(LOG_TRACKER_##log_level, m_parent->info(), "tracker", "[%u] " log_fmt, group(), __VA_ARGS__);
-@@ -142,19 +108,19 @@ TrackerHttp::send_state(int state) {
-
- const rak::socket_address* localAddress = rak::socket_address::cast_from(manager->connection_manager()->local_address());
-
-- if (!localAddress->is_address_any())
-- s << "&ip=" << localAddress->address_str();
--
-- if (localAddress->is_address_any() && localAddress->family() == rak::socket_address::pf_inet) {
-- rak::socket_address local_v6;
-- if (get_local_address(rak::socket_address::af_inet6, &local_v6))
-- s << "&ipv6=" << rak::copy_escape_html(local_v6.address_str());
-- }
-+ if (localAddress->is_address_any()) {
-+ auto ipv4_address = detect_local_sin_addr();
-+ auto ipv6_address = detect_local_sin6_addr();
-
-- if (localAddress->is_address_any() && localAddress->family() == rak::socket_address::pf_inet6) {
-- rak::socket_address local_v4;
-- if (get_local_address(rak::socket_address::af_inet, &local_v4))
-- s << "&ipv4=" << local_v4.address_str();
-+ if (ipv4_address != nullptr) {
-+ s << "&ipv4=" << sin_addr_str(ipv4_address.get());
-+ }
-+ if (ipv6_address != nullptr) {
-+ s << "&ipv6=" << sin6_addr_str(ipv6_address.get());
-+ }
-+
-+ } else {
-+ s << "&ip=" << localAddress->address_str();
- }
-
- if (info->is_compact())
-diff --git a/test/helpers/network.h b/test/helpers/network.h
-index 6cf2f870..eb188426 100644
---- a/test/helpers/network.h
-+++ b/test/helpers/network.h
-@@ -112,6 +112,7 @@ wrap_ai_get_first_sa(const char* nodename, const char* servname = nullptr, const
-
- CPPUNIT_ASSERT_MESSAGE(("wrap_ai_get_first_sa: nodename:'" + std::string(nodename) + "'").c_str(),
- sa != nullptr);
-+
- return sa;
- }
-
-@@ -121,6 +122,7 @@ wrap_ai_get_first_c_sa(const char* nodename, const char* servname = nullptr, con
-
- CPPUNIT_ASSERT_MESSAGE(("wrap_ai_get_first_sa: nodename:'" + std::string(nodename) + "'").c_str(),
- sa != nullptr);
-+
- return torrent::c_sa_unique_ptr(sa.release());
- }
-
-diff --git a/test/torrent/net/test_fd.cc b/test/torrent/net/test_fd.cc
-index 5e56f0f3..0a00ccd4 100644
---- a/test/torrent/net/test_fd.cc
-+++ b/test/torrent/net/test_fd.cc
-@@ -9,13 +9,22 @@ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(test_fd, "torrent/net");
- void
- test_fd::test_valid_flags() {
- CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream));
-+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_datagram));
-+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_datagram));
-+
- CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_nonblock));
- CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_reuse_address));
- CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only));
- CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v6only));
-
-+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_datagram | torrent::fd_flag_nonblock));
-+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_datagram | torrent::fd_flag_reuse_address));
-+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_datagram | torrent::fd_flag_v4only));
-+ CPPUNIT_ASSERT(torrent::fd_valid_flags(torrent::fd_flag_datagram | torrent::fd_flag_v6only));
-+
- CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_v4only | torrent::fd_flag_v6only));
- CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_stream | torrent::fd_flag_v4only | torrent::fd_flag_v6only));
-+ CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flag_datagram | torrent::fd_flag_v4only | torrent::fd_flag_v6only));
-
- CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags()));
- CPPUNIT_ASSERT(!torrent::fd_valid_flags(torrent::fd_flags(~torrent::fd_flag_all)));
-diff --git a/test/torrent/net/test_socket_address.cc b/test/torrent/net/test_socket_address.cc
-index 8a1b0c8a..a27b38bc 100644
---- a/test/torrent/net/test_socket_address.cc
-+++ b/test/torrent/net/test_socket_address.cc
-@@ -83,7 +83,7 @@ test_socket_address::test_make() {
- CPPUNIT_ASSERT(sin6_inet6->sin6_family == AF_INET6);
- CPPUNIT_ASSERT(sin6_inet6->sin6_port == 0);
- CPPUNIT_ASSERT(sin6_inet6->sin6_flowinfo == 0);
-- CPPUNIT_ASSERT(compare_sin6_addr(sin6_inet6->sin6_addr, in6_addr{0}));
-+ CPPUNIT_ASSERT(compare_sin6_addr(sin6_inet6->sin6_addr, (in6_addr{0})));
- CPPUNIT_ASSERT(sin6_inet6->sin6_scope_id == 0);
-
- torrent::sa_unique_ptr sa_unix = torrent::sa_make_unix("");
deleted file mode 100644
@@ -1,85 +0,0 @@
-From e646ed5427b690b75208510d328457af66b208e8 Mon Sep 17 00:00:00 2001
-From: rakshasa <sundell.software@gmail.com>
-Date: Mon, 21 Jun 2021 21:12:56 +0900
-Subject: [PATCH] Added ipv6 options.
-
----
- src/torrent/connection_manager.cc | 6 +++++-
- src/torrent/connection_manager.h | 13 +++++++++++++
- src/tracker/tracker_http.cc | 13 +++++--------
- 3 files changed, 23 insertions(+), 9 deletions(-)
-
-diff --git a/src/torrent/connection_manager.cc b/src/torrent/connection_manager.cc
-index 972dcbfc..ea5efc58 100644
---- a/src/torrent/connection_manager.cc
-+++ b/src/torrent/connection_manager.cc
-@@ -89,7 +89,11 @@ ConnectionManager::ConnectionManager() :
-
- m_listen(new Listen),
- m_listen_port(0),
-- m_listen_backlog(SOMAXCONN) {
-+ m_listen_backlog(SOMAXCONN),
-+
-+ m_block_ipv4(false),
-+ m_block_ipv6(false),
-+ m_prefer_ipv6(false) {
-
- m_bindAddress = (new rak::socket_address())->c_sockaddr();
- m_localAddress = (new rak::socket_address())->c_sockaddr();
-diff --git a/src/torrent/connection_manager.h b/src/torrent/connection_manager.h
-index cf43b0bf..09ccdd28 100644
---- a/src/torrent/connection_manager.h
-+++ b/src/torrent/connection_manager.h
-@@ -167,6 +167,15 @@ public:
- // For internal usage.
- Listen* listen() { return m_listen; }
-
-+ bool is_block_ipv4() const { return m_block_ipv4; }
-+ void set_block_ipv4(bool v) { m_block_ipv4 = v; }
-+
-+ bool is_block_ipv6() const { return m_block_ipv6; }
-+ void set_block_ipv6(bool v) { m_block_ipv6 = v; }
-+
-+ bool is_prefer_ipv6() const { return m_prefer_ipv6; }
-+ void set_prefer_ipv6(bool v) { m_prefer_ipv6 = v; }
-+
- private:
- ConnectionManager(const ConnectionManager&);
- void operator = (const ConnectionManager&);
-@@ -190,6 +199,10 @@ private:
- slot_filter_type m_slot_filter;
- slot_resolver_type m_slot_resolver;
- slot_throttle_type m_slot_address_throttle;
-+
-+ bool m_block_ipv4;
-+ bool m_block_ipv6;
-+ bool m_prefer_ipv6;
- };
-
- }
-diff --git a/src/tracker/tracker_http.cc b/src/tracker/tracker_http.cc
-index de3a39ab..fdbbd58a 100644
---- a/src/tracker/tracker_http.cc
-+++ b/src/tracker/tracker_http.cc
-@@ -109,16 +109,13 @@ TrackerHttp::send_state(int state) {
- const rak::socket_address* localAddress = rak::socket_address::cast_from(manager->connection_manager()->local_address());
-
- if (localAddress->is_address_any()) {
-- auto ipv4_address = detect_local_sin_addr();
-- auto ipv6_address = detect_local_sin6_addr();
-+ if (manager->connection_manager()->is_prefer_ipv6()) {
-+ auto ipv6_address = detect_local_sin6_addr();
-
-- if (ipv4_address != nullptr) {
-- s << "&ipv4=" << sin_addr_str(ipv4_address.get());
-+ if (ipv6_address != nullptr) {
-+ s << "&ip=" << sin6_addr_str(ipv6_address.get());
-+ }
- }
-- if (ipv6_address != nullptr) {
-- s << "&ipv6=" << sin6_addr_str(ipv6_address.get());
-- }
--
- } else {
- s << "&ip=" << localAddress->address_str();
- }
deleted file mode 100644
@@ -1,444 +0,0 @@
-From 54caef85baca975e0be30b4f3f6de01db19c8e19 Mon Sep 17 00:00:00 2001
-From: rakshasa <sundell.software@gmail.com>
-Date: Mon, 21 Jun 2021 21:28:02 +0900
-Subject: [PATCH] Removed obsolete files.
-
----
- src/Makefile.am | 2 -
- src/net/local_addr.cc | 329 ------------------------------------
- src/net/local_addr.h | 64 -------
- src/tracker/tracker_http.cc | 1 -
- 4 files changed, 396 deletions(-)
- delete mode 100644 src/net/local_addr.cc
- delete mode 100644 src/net/local_addr.h
-
-diff --git a/src/Makefile.am b/src/Makefile.am
-index 95e6a7ae..925e7e15 100644
---- a/src/Makefile.am
-+++ b/src/Makefile.am
-@@ -76,8 +76,6 @@ libtorrent_other_la_SOURCES = \
- net/address_list.cc \
- net/address_list.h \
- net/data_buffer.h \
-- net/local_addr.cc \
-- net/local_addr.h \
- net/listen.cc \
- net/listen.h \
- net/protocol_buffer.h \
-diff --git a/src/net/local_addr.cc b/src/net/local_addr.cc
-deleted file mode 100644
-index 0c7116cb..00000000
---- a/src/net/local_addr.cc
-+++ /dev/null
-@@ -1,329 +0,0 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2007, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
--// TODO: Remove.
--
--#include "config.h"
--
--#include <stdio.h>
--#include <rak/socket_address.h>
--#include <sys/types.h>
--#include <errno.h>
--
--#ifdef __linux__
--#include <linux/netlink.h>
--#include <linux/rtnetlink.h>
--#endif
--
--#include "torrent/exceptions.h"
--#include "socket_fd.h"
--#include "local_addr.h"
--
--namespace torrent {
--
--#ifdef __linux__
--
--namespace {
--
--// IPv4 priority, from highest to lowest:
--//
--// 1. Everything else (global address)
--// 2. Private address space (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16)
--// 3. Empty/INADDR_ANY (0.0.0.0)
--// 4. Link-local address (169.254.0.0/16)
--// 5. Localhost (127.0.0.0/8)
--int
--get_priority_ipv4(const in_addr& addr) {
-- if ((addr.s_addr & htonl(0xff000000U)) == htonl(0x7f000000U)) {
-- return 5;
-- }
-- if ((addr.s_addr & htonl(0xffff0000U)) == htonl(0xa9fe0000U)) {
-- return 4;
-- }
-- if (addr.s_addr == htonl(0)) {
-- return 3;
-- }
-- if ((addr.s_addr & htonl(0xff000000U)) == htonl(0x0a000000U) ||
-- (addr.s_addr & htonl(0xfff00000U)) == htonl(0xac100000U) ||
-- (addr.s_addr & htonl(0xffff0000U)) == htonl(0xc0a80000U)) {
-- return 2;
-- }
-- return 1;
--}
--
--// IPv6 priority, from highest to lowest:
--//
--// 1. Global address (2000::/16 not in 6to4 or Teredo)
--// 2. 6to4 (2002::/16)
--// 3. Teredo (2001::/32)
--// 4. Empty/INADDR_ANY (::)
--// 5. Everything else (link-local, ULA, etc.)
--int
--get_priority_ipv6(const in6_addr& addr) {
-- const uint32_t *addr32 = reinterpret_cast<const uint32_t *>(addr.s6_addr);
-- if (addr32[0] == htonl(0) &&
-- addr32[1] == htonl(0) &&
-- addr32[2] == htonl(0) &&
-- addr32[3] == htonl(0)) {
-- return 4;
-- }
-- if (addr32[0] == htonl(0x20010000)) {
-- return 3;
-- }
-- if ((addr32[0] & htonl(0xffff0000)) == htonl(0x20020000)) {
-- return 2;
-- }
-- if ((addr32[0] & htonl(0xe0000000)) == htonl(0x20000000)) {
-- return 1;
-- }
-- return 5;
--}
--
--int
--get_priority(const rak::socket_address& addr) {
-- switch (addr.family()) {
-- case AF_INET:
-- return get_priority_ipv4(addr.c_sockaddr_inet()->sin_addr);
-- case AF_INET6:
-- return get_priority_ipv6(addr.c_sockaddr_inet6()->sin6_addr);
-- default:
-- throw torrent::internal_error("Unknown address family given to compare");
-- }
--}
--
--}
--
--// Linux-specific implementation that understands how to filter away
--// understands how to filter away secondary addresses.
--bool get_local_address(sa_family_t family, rak::socket_address *address) {
-- rak::socket_address best_addr;
-- switch (family) {
-- case AF_INET:
-- best_addr.sa_inet()->clear();
-- break;
-- case AF_INET6:
-- best_addr.sa_inet6()->clear();
-- break;
-- default:
-- throw torrent::internal_error("Unknown address family given to get_local_address");
-- }
--
-- // The bottom bit of the priority is used to hold if the address is
-- // a secondary address (e.g. with IPv6 privacy extensions) or not;
-- // secondary addresses have lower priority (higher number).
-- int best_addr_pri = get_priority(best_addr) * 2;
--
-- // Get all the addresses via Linux' netlink interface.
-- int fd = ::socket(PF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
-- if (fd == -1) {
-- return false;
-- }
--
-- struct sockaddr_nl nladdr;
-- memset(&nladdr, 0, sizeof(nladdr));
-- nladdr.nl_family = AF_NETLINK;
-- if (::bind(fd, (sockaddr *)&nladdr, sizeof(nladdr))) {
-- ::close(fd);
-- return false;
-- }
--
-- const int seq_no = 1;
-- struct {
-- nlmsghdr nh;
-- rtgenmsg g;
-- } req;
-- memset(&req, 0, sizeof(req));
--
-- req.nh.nlmsg_len = sizeof(req);
-- req.nh.nlmsg_type = RTM_GETADDR;
-- req.nh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
-- req.nh.nlmsg_pid = getpid();
-- req.nh.nlmsg_seq = seq_no;
-- req.g.rtgen_family = AF_UNSPEC;
--
-- int ret;
-- do {
-- ret = ::sendto(fd, &req, sizeof(req), 0, (sockaddr *)&nladdr, sizeof(nladdr));
-- } while (ret == -1 && errno == EINTR);
--
-- if (ret == -1) {
-- ::close(fd);
-- return false;
-- }
--
-- bool done = false;
-- do {
-- char buf[4096];
-- socklen_t len = sizeof(nladdr);
-- do {
-- ret = ::recvfrom(fd, buf, sizeof(buf), 0, (sockaddr *)&nladdr, &len);
-- } while (ret == -1 && errno == EINTR);
--
-- if (ret < 0) {
-- ::close(fd);
-- return false;
-- }
--
-- for (const nlmsghdr *nlmsg = (const nlmsghdr *)buf;
-- NLMSG_OK(nlmsg, ret);
-- nlmsg = NLMSG_NEXT(nlmsg, ret)) {
-- if (nlmsg->nlmsg_seq != seq_no)
-- continue;
-- if (nlmsg->nlmsg_type == NLMSG_DONE) {
-- done = true;
-- break;
-- }
-- if (nlmsg->nlmsg_type == NLMSG_ERROR) {
-- ::close(fd);
-- return false;
-- }
-- if (nlmsg->nlmsg_type != RTM_NEWADDR)
-- continue;
--
-- const ifaddrmsg *ifa = (const ifaddrmsg *)NLMSG_DATA(nlmsg);
--
-- if (ifa->ifa_family != family)
-- continue;
--
--#ifdef IFA_F_OPTIMISTIC
-- if ((ifa->ifa_flags & IFA_F_OPTIMISTIC) != 0)
-- continue;
--#endif
--#ifdef IFA_F_DADFAILED
-- if ((ifa->ifa_flags & IFA_F_DADFAILED) != 0)
-- continue;
--#endif
--#ifdef IFA_F_DEPRECATED
-- if ((ifa->ifa_flags & IFA_F_DEPRECATED) != 0)
-- continue;
--#endif
--#ifdef IFA_F_TENTATIVE
-- if ((ifa->ifa_flags & IFA_F_TENTATIVE) != 0)
-- continue;
--#endif
--
-- // Since there can be point-to-point links on the machine, we need to keep
-- // track of the addresses we've seen for this interface; if we see both
-- // IFA_LOCAL and IFA_ADDRESS for an interface, keep only the IFA_LOCAL.
-- rak::socket_address this_addr;
-- bool seen_addr = false;
-- int plen = IFA_PAYLOAD(nlmsg);
-- for (const rtattr *rta = IFA_RTA(ifa);
-- RTA_OK(rta, plen);
-- rta = RTA_NEXT(rta, plen)) {
-- if (rta->rta_type != IFA_LOCAL &&
-- rta->rta_type != IFA_ADDRESS) {
-- continue;
-- }
-- if (rta->rta_type == IFA_ADDRESS && seen_addr) {
-- continue;
-- }
-- seen_addr = true;
-- switch (ifa->ifa_family) {
-- case AF_INET:
-- this_addr.sa_inet()->clear();
-- this_addr.sa_inet()->set_address(*(const in_addr *)RTA_DATA(rta));
-- break;
-- case AF_INET6:
-- this_addr.sa_inet6()->clear();
-- this_addr.sa_inet6()->set_address(*(const in6_addr *)RTA_DATA(rta));
-- break;
-- }
-- }
-- if (!seen_addr)
-- continue;
--
-- int this_addr_pri = get_priority(this_addr) * 2;
-- if ((ifa->ifa_flags & IFA_F_SECONDARY) == IFA_F_SECONDARY) {
-- ++this_addr_pri;
-- }
--
-- if (this_addr_pri < best_addr_pri) {
-- best_addr = this_addr;
-- best_addr_pri = this_addr_pri;
-- }
-- }
-- } while (!done);
--
-- ::close(fd);
-- if (!best_addr.is_address_any()) {
-- *address = best_addr;
-- return true;
-- } else {
-- return false;
-- }
--}
--
--#else
--
--// Generic POSIX variant.
--bool
--get_local_address(sa_family_t family, rak::socket_address *address) {
-- SocketFd sock;
-- if (!sock.open_datagram()) {
-- return false;
-- }
--
-- rak::socket_address dummy_dest;
-- dummy_dest.clear();
--
-- switch (family) {
-- case rak::socket_address::af_inet:
-- dummy_dest.set_address_c_str("4.0.0.0");
-- break;
-- case rak::socket_address::af_inet6:
-- dummy_dest.set_address_c_str("2001:1::");
-- break;
-- default:
-- throw internal_error("Unknown address family");
-- }
--
-- dummy_dest.set_port(80);
--
-- if (!sock.connect(dummy_dest)) {
-- sock.close();
-- return false;
-- }
--
-- bool ret = sock.getsockname(address);
-- sock.close();
--
-- return ret;
--}
--
--#endif
--
--}
-diff --git a/src/net/local_addr.h b/src/net/local_addr.h
-deleted file mode 100644
-index 43bc8206..00000000
---- a/src/net/local_addr.h
-+++ /dev/null
-@@ -1,64 +0,0 @@
--// libTorrent - BitTorrent library
--// Copyright (C) 2005-2007, Jari Sundell
--//
--// This program is free software; you can redistribute it and/or modify
--// it under the terms of the GNU General Public License as published by
--// the Free Software Foundation; either version 2 of the License, or
--// (at your option) any later version.
--//
--// This program is distributed in the hope that it will be useful,
--// but WITHOUT ANY WARRANTY; without even the implied warranty of
--// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
--// GNU General Public License for more details.
--//
--// You should have received a copy of the GNU General Public License
--// along with this program; if not, write to the Free Software
--// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
--//
--// In addition, as a special exception, the copyright holders give
--// permission to link the code of portions of this program with the
--// OpenSSL library under certain conditions as described in each
--// individual source file, and distribute linked combinations
--// including the two.
--//
--// You must obey the GNU General Public License in all respects for
--// all of the code used other than OpenSSL. If you modify file(s)
--// with this exception, you may extend this exception to your version
--// of the file(s), but you are not obligated to do so. If you do not
--// wish to do so, delete this exception statement from your version.
--// If you delete this exception statement from all source files in the
--// program, then also delete it here.
--//
--// Contact: Jari Sundell <jaris@ifi.uio.no>
--//
--// Skomakerveien 33
--// 3185 Skoppum, NORWAY
--
--// A routine to get a local IP address that can be presented to a tracker.
--// (Does not use UPnP etc., so will not understand NAT.)
--// On a machine with multiple network cards, address selection can be a
--// complex process, and in general what's selected is a source/destination
--// address pair. However, this routine will give an approximation that will
--// be good enough for most purposes and users.
--
--#ifndef LIBTORRENT_NET_LOCAL_ADDR_H
--#define LIBTORRENT_NET_LOCAL_ADDR_H
--
--#include <unistd.h>
--
--namespace rak {
-- class socket_address;
--}
--
--namespace torrent {
--
--// Note: family must currently be rak::af_inet or rak::af_inet6
--// (rak::af_unspec won't do); anything else will throw an exception.
--// Returns false if no address of the given family could be found,
--// either because there are none, or because something went wrong in
--// the process (e.g., no free file descriptors).
--bool get_local_address(sa_family_t family, rak::socket_address *address);
--
--}
--
--#endif /* LIBTORRENT_NET_LOCAL_ADDR_H */
-diff --git a/src/tracker/tracker_http.cc b/src/tracker/tracker_http.cc
-index fdbbd58a..22c409a1 100644
---- a/src/tracker/tracker_http.cc
-+++ b/src/tracker/tracker_http.cc
-@@ -8,7 +8,6 @@
- #import <rak/string_manip.h>
-
- #import "net/address_list.h"
--#import "net/local_addr.h"
- #import "torrent/connection_manager.h"
- #import "torrent/download_info.h"
- #import "torrent/exceptions.h"
deleted file mode 100644
@@ -1,2979 +0,0 @@
-From 4cfe9b1dc1349ad167969d6cf87f557600f34a2e Mon Sep 17 00:00:00 2001
-From: Jari Sundell <sundell.software@gmail.com>
-Date: Sat, 7 Aug 2021 17:49:35 +0900
-Subject: [PATCH] Updated and cleaned up automake. (#224)
-
----
- INSTALL | 371 +++++++----
- autogen.sh | 51 --
- configure.ac | 32 +-
- scripts/ax_check_zlib.m4 | 11 +-
- scripts/ax_cxx_compile_stdcxx.m4 | 962 ++++++++++++++++++++++++++++
- scripts/ax_cxx_compile_stdcxx_0x.m4 | 106 ---
- scripts/ax_cxx_compile_stdcxx_11.m4 | 147 -----
- scripts/ax_pthread.m4 | 453 +++++++++----
- scripts/checks.m4 | 104 ++-
- scripts/common.m4 | 29 +-
- scripts/rak_compiler.m4 | 6 +-
- scripts/rak_cxx.m4 | 14 -
- 12 files changed, 1642 insertions(+), 644 deletions(-)
- delete mode 100755 autogen.sh
- mode change 100644 => 100755 scripts/ax_check_zlib.m4
- create mode 100755 scripts/ax_cxx_compile_stdcxx.m4
- delete mode 100644 scripts/ax_cxx_compile_stdcxx_0x.m4
- delete mode 100644 scripts/ax_cxx_compile_stdcxx_11.m4
- mode change 100644 => 100755 scripts/ax_pthread.m4
- delete mode 100644 scripts/rak_cxx.m4
-
-diff --git a/INSTALL b/INSTALL
-index 54caf7c1..8865734f 100644
---- a/INSTALL
-+++ b/INSTALL
-@@ -1,81 +1,109 @@
--Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
-+Installation Instructions
-+*************************
-+
-+ Copyright (C) 1994-1996, 1999-2002, 2004-2016 Free Software
- Foundation, Inc.
-
-- This file is free documentation; the Free Software Foundation gives
--unlimited permission to copy, distribute and modify it.
-+ Copying and distribution of this file, with or without modification,
-+are permitted in any medium without royalty provided the copyright
-+notice and this notice are preserved. This file is offered as-is,
-+without warranty of any kind.
-
- Basic Installation
- ==================
-
-- These are generic installation instructions.
-+ Briefly, the shell command './configure && make && make install'
-+should configure, build, and install this package. The following
-+more-detailed instructions are generic; see the 'README' file for
-+instructions specific to this package. Some packages provide this
-+'INSTALL' file but do not implement all of the features documented
-+below. The lack of an optional feature in a given package is not
-+necessarily a bug. More recommendations for GNU packages can be found
-+in *note Makefile Conventions: (standards)Makefile Conventions.
-
-- The `configure' shell script attempts to guess correct values for
-+ The 'configure' shell script attempts to guess correct values for
- various system-dependent variables used during compilation. It uses
--those values to create a `Makefile' in each directory of the package.
--It may also create one or more `.h' files containing system-dependent
--definitions. Finally, it creates a shell script `config.status' that
-+those values to create a 'Makefile' in each directory of the package.
-+It may also create one or more '.h' files containing system-dependent
-+definitions. Finally, it creates a shell script 'config.status' that
- you can run in the future to recreate the current configuration, and a
--file `config.log' containing compiler output (useful mainly for
--debugging `configure').
-+file 'config.log' containing compiler output (useful mainly for
-+debugging 'configure').
-
-- It can also use an optional file (typically called `config.cache'
--and enabled with `--cache-file=config.cache' or simply `-C') that saves
--the results of its tests to speed up reconfiguring. (Caching is
--disabled by default to prevent problems with accidental use of stale
--cache files.)
-+ It can also use an optional file (typically called 'config.cache' and
-+enabled with '--cache-file=config.cache' or simply '-C') that saves the
-+results of its tests to speed up reconfiguring. Caching is disabled by
-+default to prevent problems with accidental use of stale cache files.
-
- If you need to do unusual things to compile the package, please try
--to figure out how `configure' could check whether to do them, and mail
--diffs or instructions to the address given in the `README' so they can
-+to figure out how 'configure' could check whether to do them, and mail
-+diffs or instructions to the address given in the 'README' so they can
- be considered for the next release. If you are using the cache, and at
--some point `config.cache' contains results you don't want to keep, you
-+some point 'config.cache' contains results you don't want to keep, you
- may remove or edit it.
-
-- The file `configure.ac' (or `configure.in') is used to create
--`configure' by a program called `autoconf'. You only need
--`configure.ac' if you want to change it or regenerate `configure' using
--a newer version of `autoconf'.
-+ The file 'configure.ac' (or 'configure.in') is used to create
-+'configure' by a program called 'autoconf'. You need 'configure.ac' if
-+you want to change it or regenerate 'configure' using a newer version of
-+'autoconf'.
-+
-+ The simplest way to compile this package is:
-
--The simplest way to compile this package is:
-+ 1. 'cd' to the directory containing the package's source code and type
-+ './configure' to configure the package for your system.
-
-- 1. `cd' to the directory containing the package's source code and type
-- `./configure' to configure the package for your system. If you're
-- using `csh' on an old version of System V, you might need to type
-- `sh ./configure' instead to prevent `csh' from trying to execute
-- `configure' itself.
-+ Running 'configure' might take a while. While running, it prints
-+ some messages telling which features it is checking for.
-
-- Running `configure' takes awhile. While running, it prints some
-- messages telling which features it is checking for.
-+ 2. Type 'make' to compile the package.
-
-- 2. Type `make' to compile the package.
-+ 3. Optionally, type 'make check' to run any self-tests that come with
-+ the package, generally using the just-built uninstalled binaries.
-
-- 3. Optionally, type `make check' to run any self-tests that come with
-- the package.
-+ 4. Type 'make install' to install the programs and any data files and
-+ documentation. When installing into a prefix owned by root, it is
-+ recommended that the package be configured and built as a regular
-+ user, and only the 'make install' phase executed with root
-+ privileges.
-
-- 4. Type `make install' to install the programs and any data files and
-- documentation.
-+ 5. Optionally, type 'make installcheck' to repeat any self-tests, but
-+ this time using the binaries in their final installed location.
-+ This target does not install anything. Running this target as a
-+ regular user, particularly if the prior 'make install' required
-+ root privileges, verifies that the installation completed
-+ correctly.
-
-- 5. You can remove the program binaries and object files from the
-- source code directory by typing `make clean'. To also remove the
-- files that `configure' created (so you can compile the package for
-- a different kind of computer), type `make distclean'. There is
-- also a `make maintainer-clean' target, but that is intended mainly
-+ 6. You can remove the program binaries and object files from the
-+ source code directory by typing 'make clean'. To also remove the
-+ files that 'configure' created (so you can compile the package for
-+ a different kind of computer), type 'make distclean'. There is
-+ also a 'make maintainer-clean' target, but that is intended mainly
- for the package's developers. If you use it, you may have to get
- all sorts of other programs in order to regenerate files that came
- with the distribution.
-
-+ 7. Often, you can also type 'make uninstall' to remove the installed
-+ files again. In practice, not all packages have tested that
-+ uninstallation works correctly, even though it is required by the
-+ GNU Coding Standards.
-+
-+ 8. Some packages, particularly those that use Automake, provide 'make
-+ distcheck', which can by used by developers to test that all other
-+ targets like 'make install' and 'make uninstall' work correctly.
-+ This target is generally not run by end users.
-+
- Compilers and Options
- =====================
-
- Some systems require unusual options for compilation or linking that
--the `configure' script does not know about. Run `./configure --help'
-+the 'configure' script does not know about. Run './configure --help'
- for details on some of the pertinent environment variables.
-
-- You can give `configure' initial values for configuration parameters
--by setting variables in the command line or in the environment. Here
--is an example:
-+ You can give 'configure' initial values for configuration parameters
-+by setting variables in the command line or in the environment. Here is
-+an example:
-
-- ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
-+ ./configure CC=c99 CFLAGS=-g LIBS=-lposix
-
- *Note Defining Variables::, for more details.
-
-@@ -84,146 +112,257 @@ Compiling For Multiple Architectures
-
- You can compile the package for more than one kind of computer at the
- same time, by placing the object files for each architecture in their
--own directory. To do this, you must use a version of `make' that
--supports the `VPATH' variable, such as GNU `make'. `cd' to the
-+own directory. To do this, you can use GNU 'make'. 'cd' to the
- directory where you want the object files and executables to go and run
--the `configure' script. `configure' automatically checks for the
--source code in the directory that `configure' is in and in `..'.
-+the 'configure' script. 'configure' automatically checks for the source
-+code in the directory that 'configure' is in and in '..'. This is known
-+as a "VPATH" build.
-+
-+ With a non-GNU 'make', it is safer to compile the package for one
-+architecture at a time in the source code directory. After you have
-+installed the package for one architecture, use 'make distclean' before
-+reconfiguring for another architecture.
-+
-+ On MacOS X 10.5 and later systems, you can create libraries and
-+executables that work on multiple system types--known as "fat" or
-+"universal" binaries--by specifying multiple '-arch' options to the
-+compiler but only a single '-arch' option to the preprocessor. Like
-+this:
-+
-+ ./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
-+ CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
-+ CPP="gcc -E" CXXCPP="g++ -E"
-
-- If you have to use a `make' that does not support the `VPATH'
--variable, you have to compile the package for one architecture at a
--time in the source code directory. After you have installed the
--package for one architecture, use `make distclean' before reconfiguring
--for another architecture.
-+ This is not guaranteed to produce working output in all cases, you
-+may have to build one architecture at a time and combine the results
-+using the 'lipo' tool if you have problems.
-
- Installation Names
- ==================
-
-- By default, `make install' will install the package's files in
--`/usr/local/bin', `/usr/local/man', etc. You can specify an
--installation prefix other than `/usr/local' by giving `configure' the
--option `--prefix=PATH'.
-+ By default, 'make install' installs the package's commands under
-+'/usr/local/bin', include files under '/usr/local/include', etc. You
-+can specify an installation prefix other than '/usr/local' by giving
-+'configure' the option '--prefix=PREFIX', where PREFIX must be an
-+absolute file name.
-
- You can specify separate installation prefixes for
- architecture-specific files and architecture-independent files. If you
--give `configure' the option `--exec-prefix=PATH', the package will use
--PATH as the prefix for installing programs and libraries.
--Documentation and other data files will still use the regular prefix.
-+pass the option '--exec-prefix=PREFIX' to 'configure', the package uses
-+PREFIX as the prefix for installing programs and libraries.
-+Documentation and other data files still use the regular prefix.
-
- In addition, if you use an unusual directory layout you can give
--options like `--bindir=PATH' to specify different values for particular
--kinds of files. Run `configure --help' for a list of the directories
--you can set and what kinds of files go in them.
--
-- If the package supports it, you can cause programs to be installed
--with an extra prefix or suffix on their names by giving `configure' the
--option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
-+options like '--bindir=DIR' to specify different values for particular
-+kinds of files. Run 'configure --help' for a list of the directories
-+you can set and what kinds of files go in them. In general, the default
-+for these options is expressed in terms of '${prefix}', so that
-+specifying just '--prefix' will affect all of the other directory
-+specifications that were not explicitly provided.
-+
-+ The most portable way to affect installation locations is to pass the
-+correct locations to 'configure'; however, many packages provide one or
-+both of the following shortcuts of passing variable assignments to the
-+'make install' command line to change installation locations without
-+having to reconfigure or recompile.
-+
-+ The first method involves providing an override variable for each
-+affected directory. For example, 'make install
-+prefix=/alternate/directory' will choose an alternate location for all
-+directory configuration variables that were expressed in terms of
-+'${prefix}'. Any directories that were specified during 'configure',
-+but not in terms of '${prefix}', must each be overridden at install time
-+for the entire installation to be relocated. The approach of makefile
-+variable overrides for each directory variable is required by the GNU
-+Coding Standards, and ideally causes no recompilation. However, some
-+platforms have known limitations with the semantics of shared libraries
-+that end up requiring recompilation when using this method, particularly
-+noticeable in packages that use GNU Libtool.
-+
-+ The second method involves providing the 'DESTDIR' variable. For
-+example, 'make install DESTDIR=/alternate/directory' will prepend
-+'/alternate/directory' before all installation names. The approach of
-+'DESTDIR' overrides is not required by the GNU Coding Standards, and
-+does not work on platforms that have drive letters. On the other hand,
-+it does better at avoiding recompilation issues, and works well even
-+when some directory options were not specified in terms of '${prefix}'
-+at 'configure' time.
-
- Optional Features
- =================
-
-- Some packages pay attention to `--enable-FEATURE' options to
--`configure', where FEATURE indicates an optional part of the package.
--They may also pay attention to `--with-PACKAGE' options, where PACKAGE
--is something like `gnu-as' or `x' (for the X Window System). The
--`README' should mention any `--enable-' and `--with-' options that the
-+ If the package supports it, you can cause programs to be installed
-+with an extra prefix or suffix on their names by giving 'configure' the
-+option '--program-prefix=PREFIX' or '--program-suffix=SUFFIX'.
-+
-+ Some packages pay attention to '--enable-FEATURE' options to
-+'configure', where FEATURE indicates an optional part of the package.
-+They may also pay attention to '--with-PACKAGE' options, where PACKAGE
-+is something like 'gnu-as' or 'x' (for the X Window System). The
-+'README' should mention any '--enable-' and '--with-' options that the
- package recognizes.
-
-- For packages that use the X Window System, `configure' can usually
-+ For packages that use the X Window System, 'configure' can usually
- find the X include and library files automatically, but if it doesn't,
--you can use the `configure' options `--x-includes=DIR' and
--`--x-libraries=DIR' to specify their locations.
-+you can use the 'configure' options '--x-includes=DIR' and
-+'--x-libraries=DIR' to specify their locations.
-+
-+ Some packages offer the ability to configure how verbose the
-+execution of 'make' will be. For these packages, running './configure
-+--enable-silent-rules' sets the default to minimal output, which can be
-+overridden with 'make V=1'; while running './configure
-+--disable-silent-rules' sets the default to verbose, which can be
-+overridden with 'make V=0'.
-+
-+Particular systems
-+==================
-+
-+ On HP-UX, the default C compiler is not ANSI C compatible. If GNU CC
-+is not installed, it is recommended to use the following options in
-+order to use an ANSI C compiler:
-+
-+ ./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
-+
-+and if that doesn't work, install pre-built binaries of GCC for HP-UX.
-+
-+ HP-UX 'make' updates targets which have the same time stamps as their
-+prerequisites, which makes it generally unusable when shipped generated
-+files such as 'configure' are involved. Use GNU 'make' instead.
-+
-+ On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
-+parse its '<wchar.h>' header file. The option '-nodtk' can be used as a
-+workaround. If GNU CC is not installed, it is therefore recommended to
-+try
-+
-+ ./configure CC="cc"
-+
-+and if that doesn't work, try
-+
-+ ./configure CC="cc -nodtk"
-+
-+ On Solaris, don't put '/usr/ucb' early in your 'PATH'. This
-+directory contains several dysfunctional programs; working variants of
-+these programs are available in '/usr/bin'. So, if you need '/usr/ucb'
-+in your 'PATH', put it _after_ '/usr/bin'.
-+
-+ On Haiku, software installed for all users goes in '/boot/common',
-+not '/usr/local'. It is recommended to use the following options:
-+
-+ ./configure --prefix=/boot/common
-
- Specifying the System Type
- ==========================
-
-- There may be some features `configure' cannot figure out
-+ There may be some features 'configure' cannot figure out
- automatically, but needs to determine by the type of machine the package
- will run on. Usually, assuming the package is built to be run on the
--_same_ architectures, `configure' can figure that out, but if it prints
-+_same_ architectures, 'configure' can figure that out, but if it prints
- a message saying it cannot guess the machine type, give it the
--`--build=TYPE' option. TYPE can either be a short name for the system
--type, such as `sun4', or a canonical name which has the form:
-+'--build=TYPE' option. TYPE can either be a short name for the system
-+type, such as 'sun4', or a canonical name which has the form:
-
- CPU-COMPANY-SYSTEM
-
- where SYSTEM can have one of these forms:
-
-- OS KERNEL-OS
-+ OS
-+ KERNEL-OS
-
-- See the file `config.sub' for the possible values of each field. If
--`config.sub' isn't included in this package, then this package doesn't
-+ See the file 'config.sub' for the possible values of each field. If
-+'config.sub' isn't included in this package, then this package doesn't
- need to know the machine type.
-
- If you are _building_ compiler tools for cross-compiling, you should
--use the `--target=TYPE' option to select the type of system they will
-+use the option '--target=TYPE' to select the type of system they will
- produce code for.
-
- If you want to _use_ a cross compiler, that generates code for a
- platform different from the build platform, you should specify the
- "host" platform (i.e., that on which the generated programs will
--eventually be run) with `--host=TYPE'.
-+eventually be run) with '--host=TYPE'.
-
- Sharing Defaults
- ================
-
-- If you want to set default values for `configure' scripts to share,
--you can create a site shell script called `config.site' that gives
--default values for variables like `CC', `cache_file', and `prefix'.
--`configure' looks for `PREFIX/share/config.site' if it exists, then
--`PREFIX/etc/config.site' if it exists. Or, you can set the
--`CONFIG_SITE' environment variable to the location of the site script.
--A warning: not all `configure' scripts look for a site script.
-+ If you want to set default values for 'configure' scripts to share,
-+you can create a site shell script called 'config.site' that gives
-+default values for variables like 'CC', 'cache_file', and 'prefix'.
-+'configure' looks for 'PREFIX/share/config.site' if it exists, then
-+'PREFIX/etc/config.site' if it exists. Or, you can set the
-+'CONFIG_SITE' environment variable to the location of the site script.
-+A warning: not all 'configure' scripts look for a site script.
-
- Defining Variables
- ==================
-
- Variables not defined in a site shell script can be set in the
--environment passed to `configure'. However, some packages may run
-+environment passed to 'configure'. However, some packages may run
- configure again during the build, and the customized values of these
- variables may be lost. In order to avoid this problem, you should set
--them in the `configure' command line, using `VAR=value'. For example:
-+them in the 'configure' command line, using 'VAR=value'. For example:
-
- ./configure CC=/usr/local2/bin/gcc
-
--will cause the specified gcc to be used as the C compiler (unless it is
-+causes the specified 'gcc' to be used as the C compiler (unless it is
- overridden in the site shell script).
-
--`configure' Invocation
-+Unfortunately, this technique does not work for 'CONFIG_SHELL' due to an
-+Autoconf limitation. Until the limitation is lifted, you can use this
-+workaround:
-+
-+ CONFIG_SHELL=/bin/bash ./configure CONFIG_SHELL=/bin/bash
-+
-+'configure' Invocation
- ======================
-
-- `configure' recognizes the following options to control how it
-+ 'configure' recognizes the following options to control how it
- operates.
-
--`--help'
--`-h'
-- Print a summary of the options to `configure', and exit.
-+'--help'
-+'-h'
-+ Print a summary of all of the options to 'configure', and exit.
-+
-+'--help=short'
-+'--help=recursive'
-+ Print a summary of the options unique to this package's
-+ 'configure', and exit. The 'short' variant lists options used only
-+ in the top level, while the 'recursive' variant lists options also
-+ present in any nested packages.
-
--`--version'
--`-V'
-- Print the version of Autoconf used to generate the `configure'
-+'--version'
-+'-V'
-+ Print the version of Autoconf used to generate the 'configure'
- script, and exit.
-
--`--cache-file=FILE'
-+'--cache-file=FILE'
- Enable the cache: use and save the results of the tests in FILE,
-- traditionally `config.cache'. FILE defaults to `/dev/null' to
-+ traditionally 'config.cache'. FILE defaults to '/dev/null' to
- disable caching.
-
--`--config-cache'
--`-C'
-- Alias for `--cache-file=config.cache'.
-+'--config-cache'
-+'-C'
-+ Alias for '--cache-file=config.cache'.
-
--`--quiet'
--`--silent'
--`-q'
-+'--quiet'
-+'--silent'
-+'-q'
- Do not print messages saying which checks are being made. To
-- suppress all normal output, redirect it to `/dev/null' (any error
-+ suppress all normal output, redirect it to '/dev/null' (any error
- messages will still be shown).
-
--`--srcdir=DIR'
-+'--srcdir=DIR'
- Look for the package's source code in directory DIR. Usually
-- `configure' can determine that directory automatically.
-+ 'configure' can determine that directory automatically.
-+
-+'--prefix=DIR'
-+ Use DIR as the installation prefix. *note Installation Names:: for
-+ more details, including other options available for fine-tuning the
-+ installation locations.
-
--`configure' also accepts some other, not widely useful, options. Run
--`configure --help' for more details.
-+'--no-create'
-+'-n'
-+ Run the configure checks, but stop before creating any output
-+ files.
-
-+'configure' also accepts some other, not widely useful, options. Run
-+'configure --help' for more details.
-diff --git a/autogen.sh b/autogen.sh
-deleted file mode 100755
-index 6def96dd..00000000
---- a/autogen.sh
-+++ /dev/null
-@@ -1,51 +0,0 @@
--#! /bin/sh
--
--echo aclocal...
--(aclocal --version) < /dev/null > /dev/null 2>&1 || {
-- echo aclocal not found
-- exit 1
--}
--
--aclocal -I ./scripts -I . ${ACLOCAL_FLAGS} || exit 1
--
--echo autoheader...
--(autoheader --version) < /dev/null > /dev/null 2>&1 || {
-- echo autoheader not found
-- exit 1
--}
--
--autoheader || exit 1
--
--echo -n "libtoolize... "
--if ( (glibtoolize --version) < /dev/null > /dev/null 2>&1 ); then
-- echo "using glibtoolize"
-- glibtoolize --automake --copy --force || exit 1
--
--elif ( (libtoolize --version) < /dev/null > /dev/null 2>&1 ) ; then
-- echo "using libtoolize"
-- libtoolize --automake --copy --force || exit 1
--
--else
-- echo "libtoolize nor glibtoolize not found"
-- exit 1
--fi
--
--echo automake...
--(automake --version) < /dev/null > /dev/null 2>&1 || {
-- echo automake not found
-- exit 1
--}
--
--automake --add-missing --copy --foreign || exit 1
--
--echo autoconf...
--(autoconf --version) < /dev/null > /dev/null 2>&1 || {
-- echo autoconf not found
-- exit 1
--}
--
--autoconf || exit 1
--
--echo ready to configure
--
--exit 0
-diff --git a/configure.ac b/configure.ac
-index a4f051e4..453e2936 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -1,10 +1,14 @@
--AC_INIT(libtorrent, 0.13.8, sundell.software@gmail.com)
-+AC_INIT([[libtorrent]],[[0.13.8]],[[sundell.software@gmail.com]])
-
--LT_INIT([disable-static])
-+AC_CONFIG_HEADERS([config.h])
-+AC_CONFIG_MACRO_DIRS([scripts])
-+AM_INIT_AUTOMAKE([serial-tests subdir-objects foreign])
-+
-+LT_INIT([[disable-static]])
-
- dnl Find a better way to do this
--AC_DEFINE(PEER_NAME, "-lt0D80-", Identifier that is part of the default peer id)
--AC_DEFINE(PEER_VERSION, "lt\x0D\x80", 4 byte client and version identifier for DHT)
-+AC_DEFINE([[PEER_NAME]], [["-lt0D80-"]], [[Identifier that is part of the default peer id.]])
-+AC_DEFINE([[PEER_VERSION]], [["lt\x0D\x80"]], [[4 byte client and version identifier for DHT.]])
-
- LIBTORRENT_CURRENT=21
- LIBTORRENT_REVISION=0
-@@ -17,9 +21,6 @@ AC_SUBST(LIBTORRENT_CURRENT)
- AC_SUBST(LIBTORRENT_INTERFACE_VERSION_INFO)
- AC_SUBST(LIBTORRENT_INTERFACE_VERSION_NO)
-
--AM_INIT_AUTOMAKE([serial-tests subdir-objects])
--AC_CONFIG_HEADERS(config.h)
--
- AC_PROG_CXX
- AC_SYS_LARGEFILE
-
-@@ -29,14 +30,14 @@ AC_C_BIGENDIAN(
- AC_MSG_ERROR([Could not determine endianness])
- )
-
-+AX_CXX_COMPILE_STDCXX(14, noext, mandatory)
-+
- RAK_CHECK_CFLAGS
- RAK_CHECK_CXXFLAGS
- RAK_ENABLE_DEBUG
- RAK_ENABLE_EXTRA_DEBUG
- RAK_ENABLE_WERROR
-
--RAK_CHECK_CXX11
--
- TORRENT_ENABLE_ALIGNED
- TORRENT_ENABLE_INTERRUPT_SOCKET
-
-@@ -55,7 +56,7 @@ TORRENT_WITHOUT_STATFS
- TORRENT_WITH_INOTIFY
-
- AC_ARG_ENABLE(attribute-visibility,
-- AC_HELP_STRING([--disable-attribute-visibility], [disable symbol visibility attribute [[default=enable]]]),
-+ AS_HELP_STRING([--disable-attribute-visibility],[disable symbol visibility attribute [[default=enable]]]),
- [
- if test "$enableval" = "yes"; then
- CC_ATTRIBUTE_VISIBILITY
-@@ -65,7 +66,7 @@ AC_ARG_ENABLE(attribute-visibility,
- ])
-
- AC_ARG_ENABLE(execinfo,
-- AC_HELP_STRING([--disable-execinfo], [disable libexecinfo [[default=enable]]]),
-+ AS_HELP_STRING([--disable-execinfo],[disable libexecinfo [[default=enable]]]),
- [
- if test "$enableval" = "yes"; then
- AX_EXECINFO
-@@ -109,12 +110,13 @@ CC_ATTRIBUTE_UNUSED(
- AC_DEFINE([__UNUSED], [], [Null-wrapper if unused attribute is unsupported])
- )
-
--AC_OUTPUT([
-+AC_CONFIG_FILES([
- libtorrent.pc
- Makefile
- src/Makefile
- src/torrent/Makefile
-- test/Makefile
-- test/torrent/net/Makefile
-- test/net/Makefile
-+ test/Makefile
-+ test/torrent/net/Makefile
-+ test/net/Makefile
- ])
-+AC_OUTPUT
-diff --git a/scripts/ax_check_zlib.m4 b/scripts/ax_check_zlib.m4
-old mode 100644
-new mode 100755
-index ae5705f6..1a168430
---- a/scripts/ax_check_zlib.m4
-+++ b/scripts/ax_check_zlib.m4
-@@ -1,5 +1,5 @@
- # ===========================================================================
--# http://www.gnu.org/software/autoconf-archive/ax_check_zlib.html
-+# https://www.gnu.org/software/autoconf-archive/ax_check_zlib.html
- # ===========================================================================
- #
- # SYNOPSIS
-@@ -47,7 +47,7 @@
- # Public License for more details.
- #
- # You should have received a copy of the GNU General Public License along
--# with this program. If not, see <http://www.gnu.org/licenses/>.
-+# with this program. If not, see <https://www.gnu.org/licenses/>.
- #
- # As a special exception, the respective Autoconf Macro's copyright owner
- # gives unlimited permission to copy, distribute and modify the configure
-@@ -62,7 +62,7 @@
- # modified version of the Autoconf Macro, you may extend this special
- # exception to the GPL to apply to your modified version as well.
-
--#serial 14
-+#serial 16
-
- AU_ALIAS([CHECK_ZLIB], [AX_CHECK_ZLIB])
- AC_DEFUN([AX_CHECK_ZLIB],
-@@ -108,11 +108,10 @@ then
- LDFLAGS="$LDFLAGS -L${ZLIB_HOME}/lib"
- CPPFLAGS="$CPPFLAGS -I${ZLIB_HOME}/include"
- fi
-- AC_LANG_SAVE
-- AC_LANG_C
-+ AC_LANG_PUSH([C])
- AC_CHECK_LIB([z], [inflateEnd], [zlib_cv_libz=yes], [zlib_cv_libz=no])
- AC_CHECK_HEADER([zlib.h], [zlib_cv_zlib_h=yes], [zlib_cv_zlib_h=no])
-- AC_LANG_RESTORE
-+ AC_LANG_POP([C])
- if test "$zlib_cv_libz" = "yes" && test "$zlib_cv_zlib_h" = "yes"
- then
- #
-diff --git a/scripts/ax_cxx_compile_stdcxx.m4 b/scripts/ax_cxx_compile_stdcxx.m4
-new file mode 100755
-index 00000000..9413da62
---- /dev/null
-+++ b/scripts/ax_cxx_compile_stdcxx.m4
-@@ -0,0 +1,962 @@
-+# ===========================================================================
-+# https://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx.html
-+# ===========================================================================
-+#
-+# SYNOPSIS
-+#
-+# AX_CXX_COMPILE_STDCXX(VERSION, [ext|noext], [mandatory|optional])
-+#
-+# DESCRIPTION
-+#
-+# Check for baseline language coverage in the compiler for the specified
-+# version of the C++ standard. If necessary, add switches to CXX and
-+# CXXCPP to enable support. VERSION may be '11' (for the C++11 standard)
-+# or '14' (for the C++14 standard).
-+#
-+# The second argument, if specified, indicates whether you insist on an
-+# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
-+# -std=c++11). If neither is specified, you get whatever works, with
-+# preference for no added switch, and then for an extended mode.
-+#
-+# The third argument, if specified 'mandatory' or if left unspecified,
-+# indicates that baseline support for the specified C++ standard is
-+# required and that the macro should error out if no mode with that
-+# support is found. If specified 'optional', then configuration proceeds
-+# regardless, after defining HAVE_CXX${VERSION} if and only if a
-+# supporting mode is found.
-+#
-+# LICENSE
-+#
-+# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
-+# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
-+# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
-+# Copyright (c) 2014, 2015 Google Inc.; contributed by Alexey Sokolov <sokolov@google.com>
-+# Copyright (c) 2015 Paul Norman <penorman@mac.com>
-+# Copyright (c) 2015 Moritz Klammler <moritz@klammler.eu>
-+# Copyright (c) 2016, 2018 Krzesimir Nowak <qdlacz@gmail.com>
-+# Copyright (c) 2019 Enji Cooper <yaneurabeya@gmail.com>
-+# Copyright (c) 2020 Jason Merrill <jason@redhat.com>
-+#
-+# Copying and distribution of this file, with or without modification, are
-+# permitted in any medium without royalty provided the copyright notice
-+# and this notice are preserved. This file is offered as-is, without any
-+# warranty.
-+
-+#serial 12
-+
-+dnl This macro is based on the code from the AX_CXX_COMPILE_STDCXX_11 macro
-+dnl (serial version number 13).
-+
-+AC_DEFUN([AX_CXX_COMPILE_STDCXX], [dnl
-+ m4_if([$1], [11], [ax_cxx_compile_alternatives="11 0x"],
-+ [$1], [14], [ax_cxx_compile_alternatives="14 1y"],
-+ [$1], [17], [ax_cxx_compile_alternatives="17 1z"],
-+ [m4_fatal([invalid first argument `$1' to AX_CXX_COMPILE_STDCXX])])dnl
-+ m4_if([$2], [], [],
-+ [$2], [ext], [],
-+ [$2], [noext], [],
-+ [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX])])dnl
-+ m4_if([$3], [], [ax_cxx_compile_cxx$1_required=true],
-+ [$3], [mandatory], [ax_cxx_compile_cxx$1_required=true],
-+ [$3], [optional], [ax_cxx_compile_cxx$1_required=false],
-+ [m4_fatal([invalid third argument `$3' to AX_CXX_COMPILE_STDCXX])])
-+ AC_LANG_PUSH([C++])dnl
-+ ac_success=no
-+
-+ m4_if([$2], [], [dnl
-+ AC_CACHE_CHECK(whether $CXX supports C++$1 features by default,
-+ ax_cv_cxx_compile_cxx$1,
-+ [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
-+ [ax_cv_cxx_compile_cxx$1=yes],
-+ [ax_cv_cxx_compile_cxx$1=no])])
-+ if test x$ax_cv_cxx_compile_cxx$1 = xyes; then
-+ ac_success=yes
-+ fi])
-+
-+ m4_if([$2], [noext], [], [dnl
-+ if test x$ac_success = xno; then
-+ for alternative in ${ax_cxx_compile_alternatives}; do
-+ switch="-std=gnu++${alternative}"
-+ cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
-+ AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
-+ $cachevar,
-+ [ac_save_CXX="$CXX"
-+ CXX="$CXX $switch"
-+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
-+ [eval $cachevar=yes],
-+ [eval $cachevar=no])
-+ CXX="$ac_save_CXX"])
-+ if eval test x\$$cachevar = xyes; then
-+ CXX="$CXX $switch"
-+ if test -n "$CXXCPP" ; then
-+ CXXCPP="$CXXCPP $switch"
-+ fi
-+ ac_success=yes
-+ break
-+ fi
-+ done
-+ fi])
-+
-+ m4_if([$2], [ext], [], [dnl
-+ if test x$ac_success = xno; then
-+ dnl HP's aCC needs +std=c++11 according to:
-+ dnl http://h21007.www2.hp.com/portal/download/files/unprot/aCxx/PDF_Release_Notes/769149-001.pdf
-+ dnl Cray's crayCC needs "-h std=c++11"
-+ for alternative in ${ax_cxx_compile_alternatives}; do
-+ for switch in -std=c++${alternative} +std=c++${alternative} "-h std=c++${alternative}"; do
-+ cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx$1_$switch])
-+ AC_CACHE_CHECK(whether $CXX supports C++$1 features with $switch,
-+ $cachevar,
-+ [ac_save_CXX="$CXX"
-+ CXX="$CXX $switch"
-+ AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_testbody_$1])],
-+ [eval $cachevar=yes],
-+ [eval $cachevar=no])
-+ CXX="$ac_save_CXX"])
-+ if eval test x\$$cachevar = xyes; then
-+ CXX="$CXX $switch"
-+ if test -n "$CXXCPP" ; then
-+ CXXCPP="$CXXCPP $switch"
-+ fi
-+ ac_success=yes
-+ break
-+ fi
-+ done
-+ if test x$ac_success = xyes; then
-+ break
-+ fi
-+ done
-+ fi])
-+ AC_LANG_POP([C++])
-+ if test x$ax_cxx_compile_cxx$1_required = xtrue; then
-+ if test x$ac_success = xno; then
-+ AC_MSG_ERROR([*** A compiler with support for C++$1 language features is required.])
-+ fi
-+ fi
-+ if test x$ac_success = xno; then
-+ HAVE_CXX$1=0
-+ AC_MSG_NOTICE([No compiler with C++$1 support was found])
-+ else
-+ HAVE_CXX$1=1
-+ AC_DEFINE(HAVE_CXX$1,1,
-+ [define if the compiler supports basic C++$1 syntax])
-+ fi
-+ AC_SUBST(HAVE_CXX$1)
-+])
-+
-+
-+dnl Test body for checking C++11 support
-+
-+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_11],
-+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
-+)
-+
-+
-+dnl Test body for checking C++14 support
-+
-+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_14],
-+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
-+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
-+)
-+
-+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_17],
-+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_11
-+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_14
-+ _AX_CXX_COMPILE_STDCXX_testbody_new_in_17
-+)
-+
-+dnl Tests for new features in C++11
-+
-+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_11], [[
-+
-+// If the compiler admits that it is not ready for C++11, why torture it?
-+// Hopefully, this will speed up the test.
-+
-+#ifndef __cplusplus
-+
-+#error "This is not a C++ compiler"
-+
-+#elif __cplusplus < 201103L
-+
-+#error "This is not a C++11 compiler"
-+
-+#else
-+
-+namespace cxx11
-+{
-+
-+ namespace test_static_assert
-+ {
-+
-+ template <typename T>
-+ struct check
-+ {
-+ static_assert(sizeof(int) <= sizeof(T), "not big enough");
-+ };
-+
-+ }
-+
-+ namespace test_final_override
-+ {
-+
-+ struct Base
-+ {
-+ virtual ~Base() {}
-+ virtual void f() {}
-+ };
-+
-+ struct Derived : public Base
-+ {
-+ virtual ~Derived() override {}
-+ virtual void f() override {}
-+ };
-+
-+ }
-+
-+ namespace test_double_right_angle_brackets
-+ {
-+
-+ template < typename T >
-+ struct check {};
-+
-+ typedef check<void> single_type;
-+ typedef check<check<void>> double_type;
-+ typedef check<check<check<void>>> triple_type;
-+ typedef check<check<check<check<void>>>> quadruple_type;
-+
-+ }
-+
-+ namespace test_decltype
-+ {
-+
-+ int
-+ f()
-+ {
-+ int a = 1;
-+ decltype(a) b = 2;
-+ return a + b;
-+ }
-+
-+ }
-+
-+ namespace test_type_deduction
-+ {
-+
-+ template < typename T1, typename T2 >
-+ struct is_same
-+ {
-+ static const bool value = false;
-+ };
-+
-+ template < typename T >
-+ struct is_same<T, T>
-+ {
-+ static const bool value = true;
-+ };
-+
-+ template < typename T1, typename T2 >
-+ auto
-+ add(T1 a1, T2 a2) -> decltype(a1 + a2)
-+ {
-+ return a1 + a2;
-+ }
-+
-+ int
-+ test(const int c, volatile int v)
-+ {
-+ static_assert(is_same<int, decltype(0)>::value == true, "");
-+ static_assert(is_same<int, decltype(c)>::value == false, "");
-+ static_assert(is_same<int, decltype(v)>::value == false, "");
-+ auto ac = c;
-+ auto av = v;
-+ auto sumi = ac + av + 'x';
-+ auto sumf = ac + av + 1.0;
-+ static_assert(is_same<int, decltype(ac)>::value == true, "");
-+ static_assert(is_same<int, decltype(av)>::value == true, "");
-+ static_assert(is_same<int, decltype(sumi)>::value == true, "");
-+ static_assert(is_same<int, decltype(sumf)>::value == false, "");
-+ static_assert(is_same<int, decltype(add(c, v))>::value == true, "");
-+ return (sumf > 0.0) ? sumi : add(c, v);
-+ }
-+
-+ }
-+
-+ namespace test_noexcept
-+ {
-+
-+ int f() { return 0; }
-+ int g() noexcept { return 0; }
-+
-+ static_assert(noexcept(f()) == false, "");
-+ static_assert(noexcept(g()) == true, "");
-+
-+ }
-+
-+ namespace test_constexpr
-+ {
-+
-+ template < typename CharT >
-+ unsigned long constexpr
-+ strlen_c_r(const CharT *const s, const unsigned long acc) noexcept
-+ {
-+ return *s ? strlen_c_r(s + 1, acc + 1) : acc;
-+ }
-+
-+ template < typename CharT >
-+ unsigned long constexpr
-+ strlen_c(const CharT *const s) noexcept
-+ {
-+ return strlen_c_r(s, 0UL);
-+ }
-+
-+ static_assert(strlen_c("") == 0UL, "");
-+ static_assert(strlen_c("1") == 1UL, "");
-+ static_assert(strlen_c("example") == 7UL, "");
-+ static_assert(strlen_c("another\0example") == 7UL, "");
-+
-+ }
-+
-+ namespace test_rvalue_references
-+ {
-+
-+ template < int N >
-+ struct answer
-+ {
-+ static constexpr int value = N;
-+ };
-+
-+ answer<1> f(int&) { return answer<1>(); }
-+ answer<2> f(const int&) { return answer<2>(); }
-+ answer<3> f(int&&) { return answer<3>(); }
-+
-+ void
-+ test()
-+ {
-+ int i = 0;
-+ const int c = 0;
-+ static_assert(decltype(f(i))::value == 1, "");
-+ static_assert(decltype(f(c))::value == 2, "");
-+ static_assert(decltype(f(0))::value == 3, "");
-+ }
-+
-+ }
-+
-+ namespace test_uniform_initialization
-+ {
-+
-+ struct test
-+ {
-+ static const int zero {};
-+ static const int one {1};
-+ };
-+
-+ static_assert(test::zero == 0, "");
-+ static_assert(test::one == 1, "");
-+
-+ }
-+
-+ namespace test_lambdas
-+ {
-+
-+ void
-+ test1()
-+ {
-+ auto lambda1 = [](){};
-+ auto lambda2 = lambda1;
-+ lambda1();
-+ lambda2();
-+ }
-+
-+ int
-+ test2()
-+ {
-+ auto a = [](int i, int j){ return i + j; }(1, 2);
-+ auto b = []() -> int { return '0'; }();
-+ auto c = [=](){ return a + b; }();
-+ auto d = [&](){ return c; }();
-+ auto e = [a, &b](int x) mutable {
-+ const auto identity = [](int y){ return y; };
-+ for (auto i = 0; i < a; ++i)
-+ a += b--;
-+ return x + identity(a + b);
-+ }(0);
-+ return a + b + c + d + e;
-+ }
-+
-+ int
-+ test3()
-+ {
-+ const auto nullary = [](){ return 0; };
-+ const auto unary = [](int x){ return x; };
-+ using nullary_t = decltype(nullary);
-+ using unary_t = decltype(unary);
-+ const auto higher1st = [](nullary_t f){ return f(); };
-+ const auto higher2nd = [unary](nullary_t f1){
-+ return [unary, f1](unary_t f2){ return f2(unary(f1())); };
-+ };
-+ return higher1st(nullary) + higher2nd(nullary)(unary);
-+ }
-+
-+ }
-+
-+ namespace test_variadic_templates
-+ {
-+
-+ template <int...>
-+ struct sum;
-+
-+ template <int N0, int... N1toN>
-+ struct sum<N0, N1toN...>
-+ {
-+ static constexpr auto value = N0 + sum<N1toN...>::value;
-+ };
-+
-+ template <>
-+ struct sum<>
-+ {
-+ static constexpr auto value = 0;
-+ };
-+
-+ static_assert(sum<>::value == 0, "");
-+ static_assert(sum<1>::value == 1, "");
-+ static_assert(sum<23>::value == 23, "");
-+ static_assert(sum<1, 2>::value == 3, "");
-+ static_assert(sum<5, 5, 11>::value == 21, "");
-+ static_assert(sum<2, 3, 5, 7, 11, 13>::value == 41, "");
-+
-+ }
-+
-+ // http://stackoverflow.com/questions/13728184/template-aliases-and-sfinae
-+ // Clang 3.1 fails with headers of libstd++ 4.8.3 when using std::function
-+ // because of this.
-+ namespace test_template_alias_sfinae
-+ {
-+
-+ struct foo {};
-+
-+ template<typename T>
-+ using member = typename T::member_type;
-+
-+ template<typename T>
-+ void func(...) {}
-+
-+ template<typename T>
-+ void func(member<T>*) {}
-+
-+ void test();
-+
-+ void test() { func<foo>(0); }
-+
-+ }
-+
-+} // namespace cxx11
-+
-+#endif // __cplusplus >= 201103L
-+
-+]])
-+
-+
-+dnl Tests for new features in C++14
-+
-+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_14], [[
-+
-+// If the compiler admits that it is not ready for C++14, why torture it?
-+// Hopefully, this will speed up the test.
-+
-+#ifndef __cplusplus
-+
-+#error "This is not a C++ compiler"
-+
-+#elif __cplusplus < 201402L
-+
-+#error "This is not a C++14 compiler"
-+
-+#else
-+
-+namespace cxx14
-+{
-+
-+ namespace test_polymorphic_lambdas
-+ {
-+
-+ int
-+ test()
-+ {
-+ const auto lambda = [](auto&&... args){
-+ const auto istiny = [](auto x){
-+ return (sizeof(x) == 1UL) ? 1 : 0;
-+ };
-+ const int aretiny[] = { istiny(args)... };
-+ return aretiny[0];
-+ };
-+ return lambda(1, 1L, 1.0f, '1');
-+ }
-+
-+ }
-+
-+ namespace test_binary_literals
-+ {
-+
-+ constexpr auto ivii = 0b0000000000101010;
-+ static_assert(ivii == 42, "wrong value");
-+
-+ }
-+
-+ namespace test_generalized_constexpr
-+ {
-+
-+ template < typename CharT >
-+ constexpr unsigned long
-+ strlen_c(const CharT *const s) noexcept
-+ {
-+ auto length = 0UL;
-+ for (auto p = s; *p; ++p)
-+ ++length;
-+ return length;
-+ }
-+
-+ static_assert(strlen_c("") == 0UL, "");
-+ static_assert(strlen_c("x") == 1UL, "");
-+ static_assert(strlen_c("test") == 4UL, "");
-+ static_assert(strlen_c("another\0test") == 7UL, "");
-+
-+ }
-+
-+ namespace test_lambda_init_capture
-+ {
-+
-+ int
-+ test()
-+ {
-+ auto x = 0;
-+ const auto lambda1 = [a = x](int b){ return a + b; };
-+ const auto lambda2 = [a = lambda1(x)](){ return a; };
-+ return lambda2();
-+ }
-+
-+ }
-+
-+ namespace test_digit_separators
-+ {
-+
-+ constexpr auto ten_million = 100'000'000;
-+ static_assert(ten_million == 100000000, "");
-+
-+ }
-+
-+ namespace test_return_type_deduction
-+ {
-+
-+ auto f(int& x) { return x; }
-+ decltype(auto) g(int& x) { return x; }
-+
-+ template < typename T1, typename T2 >
-+ struct is_same
-+ {
-+ static constexpr auto value = false;
-+ };
-+
-+ template < typename T >
-+ struct is_same<T, T>
-+ {
-+ static constexpr auto value = true;
-+ };
-+
-+ int
-+ test()
-+ {
-+ auto x = 0;
-+ static_assert(is_same<int, decltype(f(x))>::value, "");
-+ static_assert(is_same<int&, decltype(g(x))>::value, "");
-+ return x;
-+ }
-+
-+ }
-+
-+} // namespace cxx14
-+
-+#endif // __cplusplus >= 201402L
-+
-+]])
-+
-+
-+dnl Tests for new features in C++17
-+
-+m4_define([_AX_CXX_COMPILE_STDCXX_testbody_new_in_17], [[
-+
-+// If the compiler admits that it is not ready for C++17, why torture it?
-+// Hopefully, this will speed up the test.
-+
-+#ifndef __cplusplus
-+
-+#error "This is not a C++ compiler"
-+
-+#elif __cplusplus < 201703L
-+
-+#error "This is not a C++17 compiler"
-+
-+#else
-+
-+#include <initializer_list>
-+#include <utility>
-+#include <type_traits>
-+
-+namespace cxx17
-+{
-+
-+ namespace test_constexpr_lambdas
-+ {
-+
-+ constexpr int foo = [](){return 42;}();
-+
-+ }
-+
-+ namespace test::nested_namespace::definitions
-+ {
-+
-+ }
-+
-+ namespace test_fold_expression
-+ {
-+
-+ template<typename... Args>
-+ int multiply(Args... args)
-+ {
-+ return (args * ... * 1);
-+ }
-+
-+ template<typename... Args>
-+ bool all(Args... args)
-+ {
-+ return (args && ...);
-+ }
-+
-+ }
-+
-+ namespace test_extended_static_assert
-+ {
-+
-+ static_assert (true);
-+
-+ }
-+
-+ namespace test_auto_brace_init_list
-+ {
-+
-+ auto foo = {5};
-+ auto bar {5};
-+
-+ static_assert(std::is_same<std::initializer_list<int>, decltype(foo)>::value);
-+ static_assert(std::is_same<int, decltype(bar)>::value);
-+ }
-+
-+ namespace test_typename_in_template_template_parameter
-+ {
-+
-+ template<template<typename> typename X> struct D;
-+
-+ }
-+
-+ namespace test_fallthrough_nodiscard_maybe_unused_attributes
-+ {
-+
-+ int f1()
-+ {
-+ return 42;
-+ }
-+
-+ [[nodiscard]] int f2()
-+ {
-+ [[maybe_unused]] auto unused = f1();
-+
-+ switch (f1())
-+ {
-+ case 17:
-+ f1();
-+ [[fallthrough]];
-+ case 42:
-+ f1();
-+ }
-+ return f1();
-+ }
-+
-+ }
-+
-+ namespace test_extended_aggregate_initialization
-+ {
-+
-+ struct base1
-+ {
-+ int b1, b2 = 42;
-+ };
-+
-+ struct base2
-+ {
-+ base2() {
-+ b3 = 42;
-+ }
-+ int b3;
-+ };
-+
-+ struct derived : base1, base2
-+ {
-+ int d;
-+ };
-+
-+ derived d1 {{1, 2}, {}, 4}; // full initialization
-+ derived d2 {{}, {}, 4}; // value-initialized bases
-+
-+ }
-+
-+ namespace test_general_range_based_for_loop
-+ {
-+
-+ struct iter
-+ {
-+ int i;
-+
-+ int& operator* ()
-+ {
-+ return i;
-+ }
-+
-+ const int& operator* () const
-+ {
-+ return i;
-+ }
-+
-+ iter& operator++()
-+ {
-+ ++i;
-+ return *this;
-+ }
-+ };
-+
-+ struct sentinel
-+ {
-+ int i;
-+ };
-+
-+ bool operator== (const iter& i, const sentinel& s)
-+ {
-+ return i.i == s.i;
-+ }
-+
-+ bool operator!= (const iter& i, const sentinel& s)
-+ {
-+ return !(i == s);
-+ }
-+
-+ struct range
-+ {
-+ iter begin() const
-+ {
-+ return {0};
-+ }
-+
-+ sentinel end() const
-+ {
-+ return {5};
-+ }
-+ };
-+
-+ void f()
-+ {
-+ range r {};
-+
-+ for (auto i : r)
-+ {
-+ [[maybe_unused]] auto v = i;
-+ }
-+ }
-+
-+ }
-+
-+ namespace test_lambda_capture_asterisk_this_by_value
-+ {
-+
-+ struct t
-+ {
-+ int i;
-+ int foo()
-+ {
-+ return [*this]()
-+ {
-+ return i;
-+ }();
-+ }
-+ };
-+
-+ }
-+
-+ namespace test_enum_class_construction
-+ {
-+
-+ enum class byte : unsigned char
-+ {};
-+
-+ byte foo {42};
-+
-+ }
-+
-+ namespace test_constexpr_if
-+ {
-+
-+ template <bool cond>
-+ int f ()
-+ {
-+ if constexpr(cond)
-+ {
-+ return 13;
-+ }
-+ else
-+ {
-+ return 42;
-+ }
-+ }
-+
-+ }
-+
-+ namespace test_selection_statement_with_initializer
-+ {
-+
-+ int f()
-+ {
-+ return 13;
-+ }
-+
-+ int f2()
-+ {
-+ if (auto i = f(); i > 0)
-+ {
-+ return 3;
-+ }
-+
-+ switch (auto i = f(); i + 4)
-+ {
-+ case 17:
-+ return 2;
-+
-+ default:
-+ return 1;
-+ }
-+ }
-+
-+ }
-+
-+ namespace test_template_argument_deduction_for_class_templates
-+ {
-+
-+ template <typename T1, typename T2>
-+ struct pair
-+ {
-+ pair (T1 p1, T2 p2)
-+ : m1 {p1},
-+ m2 {p2}
-+ {}
-+
-+ T1 m1;
-+ T2 m2;
-+ };
-+
-+ void f()
-+ {
-+ [[maybe_unused]] auto p = pair{13, 42u};
-+ }
-+
-+ }
-+
-+ namespace test_non_type_auto_template_parameters
-+ {
-+
-+ template <auto n>
-+ struct B
-+ {};
-+
-+ B<5> b1;
-+ B<'a'> b2;
-+
-+ }
-+
-+ namespace test_structured_bindings
-+ {
-+
-+ int arr[2] = { 1, 2 };
-+ std::pair<int, int> pr = { 1, 2 };
-+
-+ auto f1() -> int(&)[2]
-+ {
-+ return arr;
-+ }
-+
-+ auto f2() -> std::pair<int, int>&
-+ {
-+ return pr;
-+ }
-+
-+ struct S
-+ {
-+ int x1 : 2;
-+ volatile double y1;
-+ };
-+
-+ S f3()
-+ {
-+ return {};
-+ }
-+
-+ auto [ x1, y1 ] = f1();
-+ auto& [ xr1, yr1 ] = f1();
-+ auto [ x2, y2 ] = f2();
-+ auto& [ xr2, yr2 ] = f2();
-+ const auto [ x3, y3 ] = f3();
-+
-+ }
-+
-+ namespace test_exception_spec_type_system
-+ {
-+
-+ struct Good {};
-+ struct Bad {};
-+
-+ void g1() noexcept;
-+ void g2();
-+
-+ template<typename T>
-+ Bad
-+ f(T*, T*);
-+
-+ template<typename T1, typename T2>
-+ Good
-+ f(T1*, T2*);
-+
-+ static_assert (std::is_same_v<Good, decltype(f(g1, g2))>);
-+
-+ }
-+
-+ namespace test_inline_variables
-+ {
-+
-+ template<class T> void f(T)
-+ {}
-+
-+ template<class T> inline T g(T)
-+ {
-+ return T{};
-+ }
-+
-+ template<> inline void f<>(int)
-+ {}
-+
-+ template<> int g<>(int)
-+ {
-+ return 5;
-+ }
-+
-+ }
-+
-+} // namespace cxx17
-+
-+#endif // __cplusplus < 201703L
-+
-+]])
-diff --git a/scripts/ax_cxx_compile_stdcxx_0x.m4 b/scripts/ax_cxx_compile_stdcxx_0x.m4
-deleted file mode 100644
-index 5ff134a6..00000000
---- a/scripts/ax_cxx_compile_stdcxx_0x.m4
-+++ /dev/null
-@@ -1,106 +0,0 @@
--# ============================================================================
--# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_0x.html
--# ============================================================================
--#
--# SYNOPSIS
--#
--# AX_CXX_COMPILE_STDCXX_0X
--#
--# DESCRIPTION
--#
--# Check for baseline language coverage in the compiler for the C++0x
--# standard.
--#
--# LICENSE
--#
--# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
--#
--# Copying and distribution of this file, with or without modification, are
--# permitted in any medium without royalty provided the copyright notice
--# and this notice are preserved. This file is offered as-is, without any
--# warranty.
--
--#serial 7 (+1)
--
--AU_ALIAS([AC_CXX_COMPILE_STDCXX_0X], [AX_CXX_COMPILE_STDCXX_0X])
--AC_DEFUN([AX_CXX_COMPILE_STDCXX_0X], [
-- AC_CACHE_CHECK(if g++ supports C++0x features without additional flags,
-- ax_cv_cxx_compile_cxx0x_native,
-- [AC_LANG_SAVE
-- AC_LANG_CPLUSPLUS
-- AC_TRY_COMPILE([
-- template <typename T>
-- struct check
-- {
-- static_assert(sizeof(int) <= sizeof(T), "not big enough");
-- };
--
-- typedef check<check<bool>> right_angle_brackets;
--
-- int a;
-- decltype(a) b;
--
-- typedef check<int> check_type;
-- check_type c;
-- check_type&& cr = static_cast<check_type&&>(c);],,
-- ax_cv_cxx_compile_cxx0x_native=yes, ax_cv_cxx_compile_cxx0x_native=no)
-- AC_LANG_RESTORE
-- ])
--
-- AC_CACHE_CHECK(if g++ supports C++0x features with -std=c++0x,
-- ax_cv_cxx_compile_cxx0x_cxx,
-- [AC_LANG_SAVE
-- AC_LANG_CPLUSPLUS
-- ac_save_CXXFLAGS="$CXXFLAGS"
-- CXXFLAGS="$CXXFLAGS -std=c++0x"
-- AC_TRY_COMPILE([
-- template <typename T>
-- struct check
-- {
-- static_assert(sizeof(int) <= sizeof(T), "not big enough");
-- };
--
-- typedef check<check<bool>> right_angle_brackets;
--
-- int a;
-- decltype(a) b;
--
-- typedef check<int> check_type;
-- check_type c;
-- check_type&& cr = static_cast<check_type&&>(c);],,
-- ax_cv_cxx_compile_cxx0x_cxx=yes, ax_cv_cxx_compile_cxx0x_cxx=no)
-- CXXFLAGS="$ac_save_CXXFLAGS"
-- AC_LANG_RESTORE
-- ])
--
-- AC_CACHE_CHECK(if g++ supports C++0x features with -std=gnu++0x,
-- ax_cv_cxx_compile_cxx0x_gxx,
-- [AC_LANG_SAVE
-- AC_LANG_CPLUSPLUS
-- ac_save_CXXFLAGS="$CXXFLAGS"
-- CXXFLAGS="$CXXFLAGS -std=gnu++0x"
-- AC_TRY_COMPILE([
-- template <typename T>
-- struct check
-- {
-- static_assert(sizeof(int) <= sizeof(T), "not big enough");
-- };
--
-- typedef check<check<bool>> right_angle_brackets;
--
-- int a;
-- decltype(a) b;
--
-- typedef check<int> check_type;
-- check_type c;
-- check_type&& cr = static_cast<check_type&&>(c);],,
-- ax_cv_cxx_compile_cxx0x_gxx=yes, ax_cv_cxx_compile_cxx0x_gxx=no)
-- CXXFLAGS="$ac_save_CXXFLAGS"
-- AC_LANG_RESTORE
-- ])
--
-- if test "$ax_cv_cxx_compile_cxx0x_cxx" = yes; then
-- AC_DEFINE(HAVE_STDCXX_0X,, [Define if compiler supports C++0x features.])
-- CXXFLAGS="$CXXFLAGS -std=c++0x"
-- fi
--])
-diff --git a/scripts/ax_cxx_compile_stdcxx_11.m4 b/scripts/ax_cxx_compile_stdcxx_11.m4
-deleted file mode 100644
-index 5cf70eb6..00000000
---- a/scripts/ax_cxx_compile_stdcxx_11.m4
-+++ /dev/null
-@@ -1,147 +0,0 @@
--# ============================================================================
--# http://www.gnu.org/software/autoconf-archive/ax_cxx_compile_stdcxx_11.html
--# ============================================================================
--#
--# SYNOPSIS
--#
--# AX_CXX_COMPILE_STDCXX_11([ext|noext],[mandatory|optional])
--#
--# DESCRIPTION
--#
--# Check for baseline language coverage in the compiler for the C++11
--# standard; if necessary, add switches to CXXFLAGS to enable support.
--#
--# The first argument, if specified, indicates whether you insist on an
--# extended mode (e.g. -std=gnu++11) or a strict conformance mode (e.g.
--# -std=c++11). If neither is specified, you get whatever works, with
--# preference for an extended mode.
--#
--# The second argument, if specified 'mandatory' or if left unspecified,
--# indicates that baseline C++11 support is required and that the macro
--# should error out if no mode with that support is found. If specified
--# 'optional', then configuration proceeds regardless, after defining
--# HAVE_CXX11 if and only if a supporting mode is found.
--#
--# LICENSE
--#
--# Copyright (c) 2008 Benjamin Kosnik <bkoz@redhat.com>
--# Copyright (c) 2012 Zack Weinberg <zackw@panix.com>
--# Copyright (c) 2013 Roy Stogner <roystgnr@ices.utexas.edu>
--# Copyright (c) 2014 Alexey Sokolov <sokolov@google.com>
--# Copyright (c) 2014 Jari Sundell <sundell.software@gmail.com>
--#
--# Copying and distribution of this file, with or without modification, are
--# permitted in any medium without royalty provided the copyright notice
--# and this notice are preserved. This file is offered as-is, without any
--# warranty.
--
--#serial 5
--
--m4_define([_AX_CXX_COMPILE_STDCXX_11_testbody], [[
-- template <typename T>
-- struct check
-- {
-- static_assert(sizeof(int) <= sizeof(T), "not big enough");
-- };
--
-- struct Base {
-- virtual void f() {}
-- };
-- struct Child : public Base {
-- virtual void f() override {}
-- };
--
-- typedef check<check<bool>> right_angle_brackets;
--
-- int a;
-- decltype(a) b;
--
-- typedef check<int> check_type;
-- check_type c;
-- check_type&& cr = static_cast<check_type&&>(c);
--
-- auto d = a;
-- auto l = [](){};
--
-- void unused() {
-- l();
-- }
--]])
--
--AC_DEFUN([AX_CXX_COMPILE_STDCXX_11], [dnl
-- m4_if([$1], [], [],
-- [$1], [ext], [],
-- [$1], [noext], [],
-- [m4_fatal([invalid argument `$1' to AX_CXX_COMPILE_STDCXX_11])])dnl
-- m4_if([$2], [], [ax_cxx_compile_cxx11_required=true],
-- [$2], [mandatory], [ax_cxx_compile_cxx11_required=true],
-- [$2], [optional], [ax_cxx_compile_cxx11_required=false],
-- [m4_fatal([invalid second argument `$2' to AX_CXX_COMPILE_STDCXX_11])])
-- AC_LANG_PUSH([C++])dnl
-- ac_success=no
-- AC_CACHE_CHECK(whether $CXX supports C++11 features by default,
-- ax_cv_cxx_compile_cxx11,
-- [AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
-- [ax_cv_cxx_compile_cxx11=yes],
-- [ax_cv_cxx_compile_cxx11=no])])
-- if test x$ax_cv_cxx_compile_cxx11 = xyes; then
-- ac_success=yes
-- fi
--
-- m4_if([$1], [noext], [], [dnl
-- if test x$ac_success = xno; then
-- for switch in -std=gnu++11 -std=gnu++0x; do
-- cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
-- AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
-- $cachevar,
-- [ac_save_CXXFLAGS="$CXXFLAGS"
-- CXXFLAGS="$CXXFLAGS $switch"
-- AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
-- [eval $cachevar=yes],
-- [eval $cachevar=no])
-- CXXFLAGS="$ac_save_CXXFLAGS"])
-- if eval test x\$$cachevar = xyes; then
-- CXXFLAGS="$CXXFLAGS $switch"
-- ac_success=yes
-- break
-- fi
-- done
-- fi])
--
-- m4_if([$1], [ext], [], [dnl
-- if test x$ac_success = xno; then
-- for switch in -std=c++11 -std=c++0x; do
-- cachevar=AS_TR_SH([ax_cv_cxx_compile_cxx11_$switch])
-- AC_CACHE_CHECK(whether $CXX supports C++11 features with $switch,
-- $cachevar,
-- [ac_save_CXXFLAGS="$CXXFLAGS"
-- CXXFLAGS="$CXXFLAGS $switch"
-- AC_COMPILE_IFELSE([AC_LANG_SOURCE([_AX_CXX_COMPILE_STDCXX_11_testbody])],
-- [eval $cachevar=yes],
-- [eval $cachevar=no])
-- CXXFLAGS="$ac_save_CXXFLAGS"])
-- if eval test x\$$cachevar = xyes; then
-- CXXFLAGS="$CXXFLAGS $switch"
-- ac_success=yes
-- break
-- fi
-- done
-- fi])
-- AC_LANG_POP([C++])
-- if test x$ax_cxx_compile_cxx11_required = xtrue; then
-- if test x$ac_success = xno; then
-- AC_MSG_ERROR([*** A compiler with support for C++11 language features is required.])
-- fi
-- else
-- if test x$ac_success = xno; then
-- HAVE_CXX11=0
-- AC_MSG_NOTICE([No compiler with C++11 support was found])
-- else
-- HAVE_CXX11=1
-- AC_DEFINE(HAVE_CXX11,1,
-- [define if the compiler supports basic C++11 syntax])
-- fi
--
-- AC_SUBST(HAVE_CXX11)
-- fi
--])
-diff --git a/scripts/ax_pthread.m4 b/scripts/ax_pthread.m4
-old mode 100644
-new mode 100755
-index 27f2533c..9f35d139
---- a/scripts/ax_pthread.m4
-+++ b/scripts/ax_pthread.m4
-@@ -1,5 +1,5 @@
- # ===========================================================================
--# http://www.gnu.org/software/autoconf-archive/ax_pthread.html
-+# https://www.gnu.org/software/autoconf-archive/ax_pthread.html
- # ===========================================================================
- #
- # SYNOPSIS
-@@ -14,24 +14,28 @@
- # flags that are needed. (The user can also force certain compiler
- # flags/libs to be tested by setting these environment variables.)
- #
--# Also sets PTHREAD_CC to any special C compiler that is needed for
--# multi-threaded programs (defaults to the value of CC otherwise). (This
--# is necessary on AIX to use the special cc_r compiler alias.)
-+# Also sets PTHREAD_CC and PTHREAD_CXX to any special C compiler that is
-+# needed for multi-threaded programs (defaults to the value of CC
-+# respectively CXX otherwise). (This is necessary on e.g. AIX to use the
-+# special cc_r/CC_r compiler alias.)
- #
- # NOTE: You are assumed to not only compile your program with these flags,
--# but also link it with them as well. e.g. you should link with
-+# but also to link with them as well. For example, you might link with
- # $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
-+# $PTHREAD_CXX $CXXFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS $LIBS
- #
--# If you are only building threads programs, you may wish to use these
-+# If you are only building threaded programs, you may wish to use these
- # variables in your default LIBS, CFLAGS, and CC:
- #
- # LIBS="$PTHREAD_LIBS $LIBS"
- # CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-+# CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
- # CC="$PTHREAD_CC"
-+# CXX="$PTHREAD_CXX"
- #
- # In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute constant
--# has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to that name
--# (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
-+# has a nonstandard name, this macro defines PTHREAD_CREATE_JOINABLE to
-+# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
- #
- # Also HAVE_PTHREAD_PRIO_INHERIT is defined if pthread is found and the
- # PTHREAD_PRIO_INHERIT symbol is defined when compiling with
-@@ -55,6 +59,7 @@
- #
- # Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
- # Copyright (c) 2011 Daniel Richard G. <skunk@iSKUNK.ORG>
-+# Copyright (c) 2019 Marc Stevens <marc.stevens@cwi.nl>
- #
- # This program is free software: you can redistribute it and/or modify it
- # under the terms of the GNU General Public License as published by the
-@@ -67,7 +72,7 @@
- # Public License for more details.
- #
- # You should have received a copy of the GNU General Public License along
--# with this program. If not, see <http://www.gnu.org/licenses/>.
-+# with this program. If not, see <https://www.gnu.org/licenses/>.
- #
- # As a special exception, the respective Autoconf Macro's copyright owner
- # gives unlimited permission to copy, distribute and modify the configure
-@@ -82,35 +87,41 @@
- # modified version of the Autoconf Macro, you may extend this special
- # exception to the GPL to apply to your modified version as well.
-
--#serial 17
-+#serial 31
-
- AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD])
- AC_DEFUN([AX_PTHREAD], [
- AC_REQUIRE([AC_CANONICAL_HOST])
-+AC_REQUIRE([AC_PROG_CC])
-+AC_REQUIRE([AC_PROG_SED])
- AC_LANG_PUSH([C])
- ax_pthread_ok=no
-
- # We used to check for pthread.h first, but this fails if pthread.h
--# requires special compiler flags (e.g. on True64 or Sequent).
-+# requires special compiler flags (e.g. on Tru64 or Sequent).
- # It gets checked for in the link test anyway.
-
- # First of all, check if the user has set any of the PTHREAD_LIBS,
- # etcetera environment variables, and if threads linking works using
- # them:
--if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
-- save_CFLAGS="$CFLAGS"
-+if test "x$PTHREAD_CFLAGS$PTHREAD_LIBS" != "x"; then
-+ ax_pthread_save_CC="$CC"
-+ ax_pthread_save_CFLAGS="$CFLAGS"
-+ ax_pthread_save_LIBS="$LIBS"
-+ AS_IF([test "x$PTHREAD_CC" != "x"], [CC="$PTHREAD_CC"])
-+ AS_IF([test "x$PTHREAD_CXX" != "x"], [CXX="$PTHREAD_CXX"])
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-- save_LIBS="$LIBS"
- LIBS="$PTHREAD_LIBS $LIBS"
-- AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
-- AC_TRY_LINK_FUNC(pthread_join, ax_pthread_ok=yes)
-- AC_MSG_RESULT($ax_pthread_ok)
-- if test x"$ax_pthread_ok" = xno; then
-+ AC_MSG_CHECKING([for pthread_join using $CC $PTHREAD_CFLAGS $PTHREAD_LIBS])
-+ AC_LINK_IFELSE([AC_LANG_CALL([], [pthread_join])], [ax_pthread_ok=yes])
-+ AC_MSG_RESULT([$ax_pthread_ok])
-+ if test "x$ax_pthread_ok" = "xno"; then
- PTHREAD_LIBS=""
- PTHREAD_CFLAGS=""
- fi
-- LIBS="$save_LIBS"
-- CFLAGS="$save_CFLAGS"
-+ CC="$ax_pthread_save_CC"
-+ CFLAGS="$ax_pthread_save_CFLAGS"
-+ LIBS="$ax_pthread_save_LIBS"
- fi
-
- # We must check for the threads library under a number of different
-@@ -118,12 +129,14 @@ fi
- # (e.g. DEC) have both -lpthread and -lpthreads, where one of the
- # libraries is broken (non-POSIX).
-
--# Create a list of thread flags to try. Items starting with a "-" are
--# C compiler flags, and other items are library names, except for "none"
--# which indicates that we try without any flags at all, and "pthread-config"
--# which is a program returning the flags for the Pth emulation library.
-+# Create a list of thread flags to try. Items with a "," contain both
-+# C compiler flags (before ",") and linker flags (after ","). Other items
-+# starting with a "-" are C compiler flags, and remaining items are
-+# library names, except for "none" which indicates that we try without
-+# any flags at all, and "pthread-config" which is a program returning
-+# the flags for the Pth emulation library.
-
--ax_pthread_flags="none pthreads -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
-+ax_pthread_flags="pthreads none -Kthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
-
- # The ordering *is* (sometimes) important. Some notes on the
- # individual items follow:
-@@ -132,68 +145,163 @@ ax_pthread_flags="none pthreads -Kthread -kthread lthread -pthread -pthreads -mt
- # none: in case threads are in libc; should be tried before -Kthread and
- # other compiler flags to prevent continual compiler warnings
- # -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
--# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
--# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
--# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
--# -pthreads: Solaris/gcc
--# -mthreads: Mingw32/gcc, Lynx/gcc
-+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads), Tru64
-+# (Note: HP C rejects this with "bad form for `-t' option")
-+# -pthreads: Solaris/gcc (Note: HP C also rejects)
- # -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
--# doesn't hurt to check since this sometimes defines pthreads too;
--# also defines -D_REENTRANT)
--# ... -mt is also the pthreads flag for HP/aCC
-+# doesn't hurt to check since this sometimes defines pthreads and
-+# -D_REENTRANT too), HP C (must be checked before -lpthread, which
-+# is present but should not be used directly; and before -mthreads,
-+# because the compiler interprets this as "-mt" + "-hreads")
-+# -mthreads: Mingw32/gcc, Lynx/gcc
- # pthread: Linux, etcetera
- # --thread-safe: KAI C++
- # pthread-config: use pthread-config program (for GNU Pth library)
-
--case "${host_cpu}-${host_os}" in
-- *solaris*)
-+case $host_os in
-+
-+ freebsd*)
-+
-+ # -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
-+ # lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
-+
-+ ax_pthread_flags="-kthread lthread $ax_pthread_flags"
-+ ;;
-+
-+ hpux*)
-+
-+ # From the cc(1) man page: "[-mt] Sets various -D flags to enable
-+ # multi-threading and also sets -lpthread."
-+
-+ ax_pthread_flags="-mt -pthread pthread $ax_pthread_flags"
-+ ;;
-+
-+ openedition*)
-+
-+ # IBM z/OS requires a feature-test macro to be defined in order to
-+ # enable POSIX threads at all, so give the user a hint if this is
-+ # not set. (We don't define these ourselves, as they can affect
-+ # other portions of the system API in unpredictable ways.)
-+
-+ AC_EGREP_CPP([AX_PTHREAD_ZOS_MISSING],
-+ [
-+# if !defined(_OPEN_THREADS) && !defined(_UNIX03_THREADS)
-+ AX_PTHREAD_ZOS_MISSING
-+# endif
-+ ],
-+ [AC_MSG_WARN([IBM z/OS requires -D_OPEN_THREADS or -D_UNIX03_THREADS to enable pthreads support.])])
-+ ;;
-+
-+ solaris*)
-
- # On Solaris (at least, for some versions), libc contains stubbed
- # (non-functional) versions of the pthreads routines, so link-based
-- # tests will erroneously succeed. (We need to link with -pthreads/-mt/
-- # -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
-- # a function called by this macro, so we could check for that, but
-- # who knows whether they'll stub that too in a future libc.) So,
-- # we'll just look for -pthreads and -lpthread first:
-+ # tests will erroneously succeed. (N.B.: The stubs are missing
-+ # pthread_cleanup_push, or rather a function called by this macro,
-+ # so we could check for that, but who knows whether they'll stub
-+ # that too in a future libc.) So we'll check first for the
-+ # standard Solaris way of linking pthreads (-mt -lpthread).
-
-- ax_pthread_flags="-pthreads pthread -mt -pthread $ax_pthread_flags"
-+ ax_pthread_flags="-mt,-lpthread pthread $ax_pthread_flags"
- ;;
-+esac
-
-- *-darwin*)
-- ax_pthread_flags="none -pthread $ax_pthread_flags"
-+# Are we compiling with Clang?
-+
-+AC_CACHE_CHECK([whether $CC is Clang],
-+ [ax_cv_PTHREAD_CLANG],
-+ [ax_cv_PTHREAD_CLANG=no
-+ # Note that Autoconf sets GCC=yes for Clang as well as GCC
-+ if test "x$GCC" = "xyes"; then
-+ AC_EGREP_CPP([AX_PTHREAD_CC_IS_CLANG],
-+ [/* Note: Clang 2.7 lacks __clang_[a-z]+__ */
-+# if defined(__clang__) && defined(__llvm__)
-+ AX_PTHREAD_CC_IS_CLANG
-+# endif
-+ ],
-+ [ax_cv_PTHREAD_CLANG=yes])
-+ fi
-+ ])
-+ax_pthread_clang="$ax_cv_PTHREAD_CLANG"
-+
-+
-+# GCC generally uses -pthread, or -pthreads on some platforms (e.g. SPARC)
-+
-+# Note that for GCC and Clang -pthread generally implies -lpthread,
-+# except when -nostdlib is passed.
-+# This is problematic using libtool to build C++ shared libraries with pthread:
-+# [1] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25460
-+# [2] https://bugzilla.redhat.com/show_bug.cgi?id=661333
-+# [3] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=468555
-+# To solve this, first try -pthread together with -lpthread for GCC
-+
-+AS_IF([test "x$GCC" = "xyes"],
-+ [ax_pthread_flags="-pthread,-lpthread -pthread -pthreads $ax_pthread_flags"])
-+
-+# Clang takes -pthread (never supported any other flag), but we'll try with -lpthread first
-+
-+AS_IF([test "x$ax_pthread_clang" = "xyes"],
-+ [ax_pthread_flags="-pthread,-lpthread -pthread"])
-+
-+
-+# The presence of a feature test macro requesting re-entrant function
-+# definitions is, on some systems, a strong hint that pthreads support is
-+# correctly enabled
-+
-+case $host_os in
-+ darwin* | hpux* | linux* | osf* | solaris*)
-+ ax_pthread_check_macro="_REENTRANT"
-+ ;;
-+
-+ aix*)
-+ ax_pthread_check_macro="_THREAD_SAFE"
-+ ;;
-+
-+ *)
-+ ax_pthread_check_macro="--"
- ;;
- esac
-+AS_IF([test "x$ax_pthread_check_macro" = "x--"],
-+ [ax_pthread_check_cond=0],
-+ [ax_pthread_check_cond="!defined($ax_pthread_check_macro)"])
-+
-
--if test x"$ax_pthread_ok" = xno; then
--for flag in $ax_pthread_flags; do
-+if test "x$ax_pthread_ok" = "xno"; then
-+for ax_pthread_try_flag in $ax_pthread_flags; do
-
-- case $flag in
-+ case $ax_pthread_try_flag in
- none)
- AC_MSG_CHECKING([whether pthreads work without any flags])
- ;;
-
-+ *,*)
-+ PTHREAD_CFLAGS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\1/"`
-+ PTHREAD_LIBS=`echo $ax_pthread_try_flag | sed "s/^\(.*\),\(.*\)$/\2/"`
-+ AC_MSG_CHECKING([whether pthreads work with "$PTHREAD_CFLAGS" and "$PTHREAD_LIBS"])
-+ ;;
-+
- -*)
-- AC_MSG_CHECKING([whether pthreads work with $flag])
-- PTHREAD_CFLAGS="$flag"
-+ AC_MSG_CHECKING([whether pthreads work with $ax_pthread_try_flag])
-+ PTHREAD_CFLAGS="$ax_pthread_try_flag"
- ;;
-
- pthread-config)
-- AC_CHECK_PROG(ax_pthread_config, pthread-config, yes, no)
-- if test x"$ax_pthread_config" = xno; then continue; fi
-+ AC_CHECK_PROG([ax_pthread_config], [pthread-config], [yes], [no])
-+ AS_IF([test "x$ax_pthread_config" = "xno"], [continue])
- PTHREAD_CFLAGS="`pthread-config --cflags`"
- PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
- ;;
-
- *)
-- AC_MSG_CHECKING([for the pthreads library -l$flag])
-- PTHREAD_LIBS="-l$flag"
-+ AC_MSG_CHECKING([for the pthreads library -l$ax_pthread_try_flag])
-+ PTHREAD_LIBS="-l$ax_pthread_try_flag"
- ;;
- esac
-
-- save_LIBS="$LIBS"
-- save_CFLAGS="$CFLAGS"
-- LIBS="$PTHREAD_LIBS $LIBS"
-+ ax_pthread_save_CFLAGS="$CFLAGS"
-+ ax_pthread_save_LIBS="$LIBS"
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-+ LIBS="$PTHREAD_LIBS $LIBS"
-
- # Check for various functions. We must include pthread.h,
- # since some functions may be macros. (On the Sequent, we
-@@ -204,8 +312,18 @@ for flag in $ax_pthread_flags; do
- # pthread_cleanup_push because it is one of the few pthread
- # functions on Solaris that doesn't have a non-functional libc stub.
- # We try pthread_create on general principles.
-+
- AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>
-- static void routine(void *a) { a = 0; }
-+# if $ax_pthread_check_cond
-+# error "$ax_pthread_check_macro must be defined"
-+# endif
-+ static void *some_global = NULL;
-+ static void routine(void *a)
-+ {
-+ /* To avoid any unused-parameter or
-+ unused-but-set-parameter warning. */
-+ some_global = a;
-+ }
- static void *start_routine(void *a) { return a; }],
- [pthread_t th; pthread_attr_t attr;
- pthread_create(&th, 0, start_routine, 0);
-@@ -213,93 +331,188 @@ for flag in $ax_pthread_flags; do
- pthread_attr_init(&attr);
- pthread_cleanup_push(routine, 0);
- pthread_cleanup_pop(0) /* ; */])],
-- [ax_pthread_ok=yes],
-- [])
-+ [ax_pthread_ok=yes],
-+ [])
-
-- LIBS="$save_LIBS"
-- CFLAGS="$save_CFLAGS"
-+ CFLAGS="$ax_pthread_save_CFLAGS"
-+ LIBS="$ax_pthread_save_LIBS"
-
-- AC_MSG_RESULT($ax_pthread_ok)
-- if test "x$ax_pthread_ok" = xyes; then
-- break;
-- fi
-+ AC_MSG_RESULT([$ax_pthread_ok])
-+ AS_IF([test "x$ax_pthread_ok" = "xyes"], [break])
-
- PTHREAD_LIBS=""
- PTHREAD_CFLAGS=""
- done
- fi
-
-+
-+# Clang needs special handling, because older versions handle the -pthread
-+# option in a rather... idiosyncratic way
-+
-+if test "x$ax_pthread_clang" = "xyes"; then
-+
-+ # Clang takes -pthread; it has never supported any other flag
-+
-+ # (Note 1: This will need to be revisited if a system that Clang
-+ # supports has POSIX threads in a separate library. This tends not
-+ # to be the way of modern systems, but it's conceivable.)
-+
-+ # (Note 2: On some systems, notably Darwin, -pthread is not needed
-+ # to get POSIX threads support; the API is always present and
-+ # active. We could reasonably leave PTHREAD_CFLAGS empty. But
-+ # -pthread does define _REENTRANT, and while the Darwin headers
-+ # ignore this macro, third-party headers might not.)
-+
-+ # However, older versions of Clang make a point of warning the user
-+ # that, in an invocation where only linking and no compilation is
-+ # taking place, the -pthread option has no effect ("argument unused
-+ # during compilation"). They expect -pthread to be passed in only
-+ # when source code is being compiled.
-+ #
-+ # Problem is, this is at odds with the way Automake and most other
-+ # C build frameworks function, which is that the same flags used in
-+ # compilation (CFLAGS) are also used in linking. Many systems
-+ # supported by AX_PTHREAD require exactly this for POSIX threads
-+ # support, and in fact it is often not straightforward to specify a
-+ # flag that is used only in the compilation phase and not in
-+ # linking. Such a scenario is extremely rare in practice.
-+ #
-+ # Even though use of the -pthread flag in linking would only print
-+ # a warning, this can be a nuisance for well-run software projects
-+ # that build with -Werror. So if the active version of Clang has
-+ # this misfeature, we search for an option to squash it.
-+
-+ AC_CACHE_CHECK([whether Clang needs flag to prevent "argument unused" warning when linking with -pthread],
-+ [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG],
-+ [ax_cv_PTHREAD_CLANG_NO_WARN_FLAG=unknown
-+ # Create an alternate version of $ac_link that compiles and
-+ # links in two steps (.c -> .o, .o -> exe) instead of one
-+ # (.c -> exe), because the warning occurs only in the second
-+ # step
-+ ax_pthread_save_ac_link="$ac_link"
-+ ax_pthread_sed='s/conftest\.\$ac_ext/conftest.$ac_objext/g'
-+ ax_pthread_link_step=`AS_ECHO(["$ac_link"]) | sed "$ax_pthread_sed"`
-+ ax_pthread_2step_ac_link="($ac_compile) && (echo ==== >&5) && ($ax_pthread_link_step)"
-+ ax_pthread_save_CFLAGS="$CFLAGS"
-+ for ax_pthread_try in '' -Qunused-arguments -Wno-unused-command-line-argument unknown; do
-+ AS_IF([test "x$ax_pthread_try" = "xunknown"], [break])
-+ CFLAGS="-Werror -Wunknown-warning-option $ax_pthread_try -pthread $ax_pthread_save_CFLAGS"
-+ ac_link="$ax_pthread_save_ac_link"
-+ AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
-+ [ac_link="$ax_pthread_2step_ac_link"
-+ AC_LINK_IFELSE([AC_LANG_SOURCE([[int main(void){return 0;}]])],
-+ [break])
-+ ])
-+ done
-+ ac_link="$ax_pthread_save_ac_link"
-+ CFLAGS="$ax_pthread_save_CFLAGS"
-+ AS_IF([test "x$ax_pthread_try" = "x"], [ax_pthread_try=no])
-+ ax_cv_PTHREAD_CLANG_NO_WARN_FLAG="$ax_pthread_try"
-+ ])
-+
-+ case "$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG" in
-+ no | unknown) ;;
-+ *) PTHREAD_CFLAGS="$ax_cv_PTHREAD_CLANG_NO_WARN_FLAG $PTHREAD_CFLAGS" ;;
-+ esac
-+
-+fi # $ax_pthread_clang = yes
-+
-+
-+
- # Various other checks:
--if test "x$ax_pthread_ok" = xyes; then
-- save_LIBS="$LIBS"
-- LIBS="$PTHREAD_LIBS $LIBS"
-- save_CFLAGS="$CFLAGS"
-+if test "x$ax_pthread_ok" = "xyes"; then
-+ ax_pthread_save_CFLAGS="$CFLAGS"
-+ ax_pthread_save_LIBS="$LIBS"
- CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-+ LIBS="$PTHREAD_LIBS $LIBS"
-
- # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
-- AC_MSG_CHECKING([for joinable pthread attribute])
-- attr_name=unknown
-- for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
-- AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
-- [int attr = $attr; return attr /* ; */])],
-- [attr_name=$attr; break],
-- [])
-- done
-- AC_MSG_RESULT($attr_name)
-- if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
-- AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
-- [Define to necessary symbol if this constant
-- uses a non-standard name on your system.])
-- fi
-+ AC_CACHE_CHECK([for joinable pthread attribute],
-+ [ax_cv_PTHREAD_JOINABLE_ATTR],
-+ [ax_cv_PTHREAD_JOINABLE_ATTR=unknown
-+ for ax_pthread_attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
-+ AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <pthread.h>],
-+ [int attr = $ax_pthread_attr; return attr /* ; */])],
-+ [ax_cv_PTHREAD_JOINABLE_ATTR=$ax_pthread_attr; break],
-+ [])
-+ done
-+ ])
-+ AS_IF([test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xunknown" && \
-+ test "x$ax_cv_PTHREAD_JOINABLE_ATTR" != "xPTHREAD_CREATE_JOINABLE" && \
-+ test "x$ax_pthread_joinable_attr_defined" != "xyes"],
-+ [AC_DEFINE_UNQUOTED([PTHREAD_CREATE_JOINABLE],
-+ [$ax_cv_PTHREAD_JOINABLE_ATTR],
-+ [Define to necessary symbol if this constant
-+ uses a non-standard name on your system.])
-+ ax_pthread_joinable_attr_defined=yes
-+ ])
-
-- AC_MSG_CHECKING([if more special flags are required for pthreads])
-- flag=no
-- case "${host_cpu}-${host_os}" in
-- *-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
-- *-osf* | *-hpux*) flag="-D_REENTRANT";;
-- *solaris*)
-- if test "$GCC" = "yes"; then
-- flag="-D_REENTRANT"
-- else
-- flag="-mt -D_REENTRANT"
-- fi
-- ;;
-- esac
-- AC_MSG_RESULT(${flag})
-- if test "x$flag" != xno; then
-- PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
-- fi
-+ AC_CACHE_CHECK([whether more special flags are required for pthreads],
-+ [ax_cv_PTHREAD_SPECIAL_FLAGS],
-+ [ax_cv_PTHREAD_SPECIAL_FLAGS=no
-+ case $host_os in
-+ solaris*)
-+ ax_cv_PTHREAD_SPECIAL_FLAGS="-D_POSIX_PTHREAD_SEMANTICS"
-+ ;;
-+ esac
-+ ])
-+ AS_IF([test "x$ax_cv_PTHREAD_SPECIAL_FLAGS" != "xno" && \
-+ test "x$ax_pthread_special_flags_added" != "xyes"],
-+ [PTHREAD_CFLAGS="$ax_cv_PTHREAD_SPECIAL_FLAGS $PTHREAD_CFLAGS"
-+ ax_pthread_special_flags_added=yes])
-
- AC_CACHE_CHECK([for PTHREAD_PRIO_INHERIT],
-- ax_cv_PTHREAD_PRIO_INHERIT, [
-- AC_LINK_IFELSE([
-- AC_LANG_PROGRAM([[#include <pthread.h>]], [[int i = PTHREAD_PRIO_INHERIT;]])],
-- [ax_cv_PTHREAD_PRIO_INHERIT=yes],
-- [ax_cv_PTHREAD_PRIO_INHERIT=no])
-+ [ax_cv_PTHREAD_PRIO_INHERIT],
-+ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]],
-+ [[int i = PTHREAD_PRIO_INHERIT;
-+ return i;]])],
-+ [ax_cv_PTHREAD_PRIO_INHERIT=yes],
-+ [ax_cv_PTHREAD_PRIO_INHERIT=no])
- ])
-- AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes"],
-- AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], 1, [Have PTHREAD_PRIO_INHERIT.]))
-+ AS_IF([test "x$ax_cv_PTHREAD_PRIO_INHERIT" = "xyes" && \
-+ test "x$ax_pthread_prio_inherit_defined" != "xyes"],
-+ [AC_DEFINE([HAVE_PTHREAD_PRIO_INHERIT], [1], [Have PTHREAD_PRIO_INHERIT.])
-+ ax_pthread_prio_inherit_defined=yes
-+ ])
-
-- LIBS="$save_LIBS"
-- CFLAGS="$save_CFLAGS"
-+ CFLAGS="$ax_pthread_save_CFLAGS"
-+ LIBS="$ax_pthread_save_LIBS"
-
-- # More AIX lossage: must compile with xlc_r or cc_r
-- if test x"$GCC" != xyes; then
-- AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
-- else
-- PTHREAD_CC=$CC
-+ # More AIX lossage: compile with *_r variant
-+ if test "x$GCC" != "xyes"; then
-+ case $host_os in
-+ aix*)
-+ AS_CASE(["x/$CC"],
-+ [x*/c89|x*/c89_128|x*/c99|x*/c99_128|x*/cc|x*/cc128|x*/xlc|x*/xlc_v6|x*/xlc128|x*/xlc128_v6],
-+ [#handle absolute path differently from PATH based program lookup
-+ AS_CASE(["x$CC"],
-+ [x/*],
-+ [
-+ AS_IF([AS_EXECUTABLE_P([${CC}_r])],[PTHREAD_CC="${CC}_r"])
-+ AS_IF([test "x${CXX}" != "x"], [AS_IF([AS_EXECUTABLE_P([${CXX}_r])],[PTHREAD_CXX="${CXX}_r"])])
-+ ],
-+ [
-+ AC_CHECK_PROGS([PTHREAD_CC],[${CC}_r],[$CC])
-+ AS_IF([test "x${CXX}" != "x"], [AC_CHECK_PROGS([PTHREAD_CXX],[${CXX}_r],[$CXX])])
-+ ]
-+ )
-+ ])
-+ ;;
-+ esac
- fi
--else
-- PTHREAD_CC="$CC"
- fi
-
--AC_SUBST(PTHREAD_LIBS)
--AC_SUBST(PTHREAD_CFLAGS)
--AC_SUBST(PTHREAD_CC)
-+test -n "$PTHREAD_CC" || PTHREAD_CC="$CC"
-+test -n "$PTHREAD_CXX" || PTHREAD_CXX="$CXX"
-+
-+AC_SUBST([PTHREAD_LIBS])
-+AC_SUBST([PTHREAD_CFLAGS])
-+AC_SUBST([PTHREAD_CC])
-+AC_SUBST([PTHREAD_CXX])
-
- # Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
--if test x"$ax_pthread_ok" = xyes; then
-- ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
-+if test "x$ax_pthread_ok" = "xyes"; then
-+ ifelse([$1],,[AC_DEFINE([HAVE_PTHREAD],[1],[Define if you have POSIX threads libraries and header files.])],[$1])
- :
- else
- ax_pthread_ok=no
-diff --git a/scripts/checks.m4 b/scripts/checks.m4
-index 915a5011..b9095cee 100644
---- a/scripts/checks.m4
-+++ b/scripts/checks.m4
-@@ -21,7 +21,7 @@ AC_DEFUN([TORRENT_CHECK_XFS], [
-
- AC_DEFUN([TORRENT_WITHOUT_XFS], [
- AC_ARG_WITH(xfs,
-- AC_HELP_STRING([--without-xfs], [do not check for XFS filesystem support]),
-+ AS_HELP_STRING([--without-xfs],[do not check for XFS filesystem support]),
- [
- if test "$withval" = "yes"; then
- TORRENT_CHECK_XFS
-@@ -34,7 +34,7 @@ AC_DEFUN([TORRENT_WITHOUT_XFS], [
-
- AC_DEFUN([TORRENT_WITH_XFS], [
- AC_ARG_WITH(xfs,
-- AC_HELP_STRING([--with-xfs], [check for XFS filesystem support]),
-+ AS_HELP_STRING([--with-xfs],[check for XFS filesystem support]),
- [
- if test "$withval" = "yes"; then
- TORRENT_CHECK_XFS
-@@ -63,7 +63,7 @@ AC_DEFUN([TORRENT_CHECK_EPOLL], [
-
- AC_DEFUN([TORRENT_WITHOUT_EPOLL], [
- AC_ARG_WITH(epoll,
-- AC_HELP_STRING([--without-epoll], [do not check for epoll support]),
-+ AS_HELP_STRING([--without-epoll],[do not check for epoll support]),
- [
- if test "$withval" = "yes"; then
- TORRENT_CHECK_EPOLL
-@@ -134,7 +134,7 @@ AC_DEFUN([TORRENT_CHECK_KQUEUE_SOCKET_ONLY], [
-
- AC_DEFUN([TORRENT_WITH_KQUEUE], [
- AC_ARG_WITH(kqueue,
-- AC_HELP_STRING([--with-kqueue], [enable kqueue [[default=no]]]),
-+ AS_HELP_STRING([--with-kqueue],[enable kqueue [[default=no]]]),
- [
- if test "$withval" = "yes"; then
- TORRENT_CHECK_KQUEUE
-@@ -145,7 +145,7 @@ AC_DEFUN([TORRENT_WITH_KQUEUE], [
-
- AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [
- AC_ARG_WITH(kqueue,
-- AC_HELP_STRING([--without-kqueue], [do not check for kqueue support]),
-+ AS_HELP_STRING([--without-kqueue],[do not check for kqueue support]),
- [
- if test "$withval" = "yes"; then
- TORRENT_CHECK_KQUEUE
-@@ -158,7 +158,7 @@ AC_DEFUN([TORRENT_WITHOUT_KQUEUE], [
-
- AC_DEFUN([TORRENT_WITHOUT_VARIABLE_FDSET], [
- AC_ARG_WITH(variable-fdset,
-- AC_HELP_STRING([--without-variable-fdset], [do not use non-portable variable sized fd_set's]),
-+ AS_HELP_STRING([--without-variable-fdset],[do not use non-portable variable sized fd_set's]),
- [
- if test "$withval" = "yes"; then
- AC_DEFINE(USE_VARIABLE_FDSET, 1, defined when we allow the use of fd_set's of any size)
-@@ -172,14 +172,13 @@ AC_DEFUN([TORRENT_WITHOUT_VARIABLE_FDSET], [
- AC_DEFUN([TORRENT_CHECK_FALLOCATE], [
- AC_MSG_CHECKING(for fallocate)
-
-- AC_TRY_LINK([#define _GNU_SOURCE
-+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#define _GNU_SOURCE
- #include <fcntl.h>
-- ],[ fallocate(0, FALLOC_FL_KEEP_SIZE, 0, 0); return 0;
-- ],
-- [
-+ ]], [[ fallocate(0, FALLOC_FL_KEEP_SIZE, 0, 0); return 0;
-+ ]])],[
- AC_DEFINE(HAVE_FALLOCATE, 1, Linux's fallocate supported.)
- AC_MSG_RESULT(yes)
-- ], [
-+ ],[
- AC_MSG_RESULT(no)
- ])
- ])
-@@ -188,13 +187,12 @@ AC_DEFUN([TORRENT_CHECK_FALLOCATE], [
- AC_DEFUN([TORRENT_CHECK_POSIX_FALLOCATE], [
- AC_MSG_CHECKING(for posix_fallocate)
-
-- AC_TRY_LINK([#include <fcntl.h>
-- ],[ posix_fallocate(0, 0, 0);
-- ],
-- [
-+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <fcntl.h>
-+ ]], [[ posix_fallocate(0, 0, 0);
-+ ]])],[
- AC_DEFINE(USE_POSIX_FALLOCATE, 1, posix_fallocate supported.)
- AC_MSG_RESULT(yes)
-- ], [
-+ ],[
- AC_MSG_RESULT(no)
- ])
- ])
-@@ -202,7 +200,7 @@ AC_DEFUN([TORRENT_CHECK_POSIX_FALLOCATE], [
-
- AC_DEFUN([TORRENT_WITH_POSIX_FALLOCATE], [
- AC_ARG_WITH(posix-fallocate,
-- AC_HELP_STRING([--with-posix-fallocate], [check for and use posix_fallocate to allocate files]),
-+ AS_HELP_STRING([--with-posix-fallocate],[check for and use posix_fallocate to allocate files]),
- [
- if test "$withval" = "yes"; then
- TORRENT_CHECK_POSIX_FALLOCATE
-@@ -215,8 +213,7 @@ AC_DEFUN([TORRENT_CHECK_STATVFS], [
-
- AC_MSG_CHECKING(for statvfs)
-
-- AC_TRY_LINK(
-- [
-+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
- #if HAVE_SYS_VFS_H
- #include <sys/vfs.h>
- #endif
-@@ -226,12 +223,11 @@ AC_DEFUN([TORRENT_CHECK_STATVFS], [
- #if HAVE_SYS_STATFS_H
- #include <sys/statfs.h>
- #endif
-- ],[
-+ ]], [[
- struct statvfs s; fsblkcnt_t c;
- statvfs("", &s);
- fstatvfs(0, &s);
-- ],
-- [
-+ ]])],[
- AC_DEFINE(FS_STAT_FD, [fstatvfs(fd, &m_stat) == 0], Function to determine filesystem stats from fd)
- AC_DEFINE(FS_STAT_FN, [statvfs(fn, &m_stat) == 0], Function to determine filesystem stats from filename)
- AC_DEFINE(FS_STAT_STRUCT, [struct statvfs], Type of second argument to statfs function)
-@@ -240,8 +236,7 @@ AC_DEFUN([TORRENT_CHECK_STATVFS], [
- AC_DEFINE(FS_STAT_BLOCK_SIZE, [(m_stat.f_frsize)], Determine the block size)
- AC_MSG_RESULT(ok)
- have_stat_vfs=yes
-- ],
-- [
-+ ],[
- AC_MSG_RESULT(no)
- have_stat_vfs=no
- ])
-@@ -252,8 +247,7 @@ AC_DEFUN([TORRENT_CHECK_STATFS], [
-
- AC_MSG_CHECKING(for statfs)
-
-- AC_TRY_LINK(
-- [
-+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
- #if HAVE_SYS_STATFS_H
- #include <sys/statfs.h>
- #endif
-@@ -263,12 +257,11 @@ AC_DEFUN([TORRENT_CHECK_STATFS], [
- #if HAVE_SYS_MOUNT_H
- #include <sys/mount.h>
- #endif
-- ],[
-+ ]], [[
- struct statfs s;
- statfs("", &s);
- fstatfs(0, &s);
-- ],
-- [
-+ ]])],[
- AC_DEFINE(FS_STAT_FD, [fstatfs(fd, &m_stat) == 0], Function to determine filesystem stats from fd)
- AC_DEFINE(FS_STAT_FN, [statfs(fn, &m_stat) == 0], Function to determine filesystem stats from filename)
- AC_DEFINE(FS_STAT_STRUCT, [struct statfs], Type of second argument to statfs function)
-@@ -277,8 +270,7 @@ AC_DEFUN([TORRENT_CHECK_STATFS], [
- AC_DEFINE(FS_STAT_BLOCK_SIZE, [(m_stat.f_bsize)], Determine the block size)
- AC_MSG_RESULT(ok)
- have_stat_vfs=yes
-- ],
-- [
-+ ],[
- AC_MSG_RESULT(no)
- have_stat_vfs=no
- ])
-@@ -296,7 +288,7 @@ AC_DEFUN([TORRENT_DISABLED_STATFS], [
-
- AC_DEFUN([TORRENT_WITHOUT_STATVFS], [
- AC_ARG_WITH(statvfs,
-- AC_HELP_STRING([--without-statvfs], [don't try to use statvfs to find free diskspace]),
-+ AS_HELP_STRING([--without-statvfs],[don't try to use statvfs to find free diskspace]),
- [
- if test "$withval" = "yes"; then
- TORRENT_CHECK_STATVFS
-@@ -311,7 +303,7 @@ AC_DEFUN([TORRENT_WITHOUT_STATVFS], [
-
- AC_DEFUN([TORRENT_WITHOUT_STATFS], [
- AC_ARG_WITH(statfs,
-- AC_HELP_STRING([--without-statfs], [don't try to use statfs to find free diskspace]),
-+ AS_HELP_STRING([--without-statfs],[don't try to use statfs to find free diskspace]),
- [
- if test "$have_stat_vfs" = "no"; then
- if test "$withval" = "yes"; then
-@@ -333,7 +325,7 @@ AC_DEFUN([TORRENT_WITHOUT_STATFS], [
-
- AC_DEFUN([TORRENT_WITH_ADDRESS_SPACE], [
- AC_ARG_WITH(address-space,
-- AC_HELP_STRING([--with-address-space=MB], [change the default address space size [[default=1024mb]]]),
-+ AS_HELP_STRING([--with-address-space=MB],[change the default address space size [[default=1024mb]]]),
- [
- if test ! -z $withval -a "$withval" != "yes" -a "$withval" != "no"; then
- AC_DEFINE_UNQUOTED(DEFAULT_ADDRESS_SPACE_SIZE, [$withval])
-@@ -354,7 +346,7 @@ AC_DEFUN([TORRENT_WITH_ADDRESS_SPACE], [
-
- AC_DEFUN([TORRENT_WITH_FASTCGI], [
- AC_ARG_WITH(fastcgi,
-- AC_HELP_STRING([--with-fastcgi=PATH], [enable FastCGI RPC support (DO NOT USE)]),
-+ AS_HELP_STRING([--with-fastcgi=PATH],[enable FastCGI RPC support (DO NOT USE)]),
- [
- AC_MSG_CHECKING([for FastCGI (DO NOT USE)])
-
-@@ -365,13 +357,10 @@ AC_DEFUN([TORRENT_WITH_FASTCGI], [
- CXXFLAGS="$CXXFLAGS"
- LIBS="$LIBS -lfcgi"
-
-- AC_TRY_LINK(
-- [ #include <fcgiapp.h>
-- ],[ FCGX_Init(); ],
-- [
-+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <fcgiapp.h>
-+ ]], [[ FCGX_Init(); ]])],[
- AC_MSG_RESULT(ok)
-- ],
-- [
-+ ],[
- AC_MSG_RESULT(not found)
- AC_MSG_ERROR(Could not compile FastCGI test.)
- ])
-@@ -382,13 +371,10 @@ AC_DEFUN([TORRENT_WITH_FASTCGI], [
- CXXFLAGS="$CXXFLAGS -I$withval/include"
- LIBS="$LIBS -lfcgi -L$withval/lib"
-
-- AC_TRY_LINK(
-- [ #include <fcgiapp.h>
-- ],[ FCGX_Init(); ],
-- [
-+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <fcgiapp.h>
-+ ]], [[ FCGX_Init(); ]])],[
- AC_MSG_RESULT(ok)
-- ],
-- [
-+ ],[
- AC_MSG_RESULT(not found)
- AC_MSG_ERROR(Could not compile FastCGI test.)
- ])
-@@ -403,7 +389,7 @@ AC_DEFUN([TORRENT_WITH_XMLRPC_C], [
- AC_MSG_CHECKING(for XMLRPC-C)
-
- AC_ARG_WITH(xmlrpc-c,
-- AC_HELP_STRING([--with-xmlrpc-c=PATH], [enable XMLRPC-C support]),
-+ AS_HELP_STRING([--with-xmlrpc-c=PATH],[enable XMLRPC-C support]),
- [
- if test "$withval" = "no"; then
- AC_MSG_RESULT(no)
-@@ -419,12 +405,10 @@ AC_DEFUN([TORRENT_WITH_XMLRPC_C], [
- CXXFLAGS="$CXXFLAGS `$xmlrpc_cc_prg --cflags server-util`"
- LIBS="$LIBS `$xmlrpc_cc_prg server-util --libs`"
-
-- AC_TRY_LINK(
-- [ #include <xmlrpc-c/server.h>
-- ],[ xmlrpc_registry_new(NULL); ],
-- [
-+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ #include <xmlrpc-c/server.h>
-+ ]], [[ xmlrpc_registry_new(NULL); ]])],[
- AC_MSG_RESULT(ok)
-- ], [
-+ ],[
- AC_MSG_RESULT(failed)
- AC_MSG_ERROR(Could not compile XMLRPC-C test.)
- ])
-@@ -466,23 +450,23 @@ AC_DEFUN([TORRENT_CHECK_PTHREAD_SETNAME_NP], [
-
- AC_MSG_CHECKING(for pthread_setname_np type)
-
-- AC_TRY_LINK([
-+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
- #include <pthread.h>
- #include <sys/types.h>
-- ],[
-+ ]], [[
- pthread_t t;
- pthread_setname_np(t, "foo");
-- ],[
-+ ]])],[
- AC_DEFINE(HAS_PTHREAD_SETNAME_NP_GENERIC, 1, The function to set pthread name has a pthread_t argumet.)
- AC_MSG_RESULT(generic)
- ],[
-- AC_TRY_LINK([
-+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[
- #include <pthread.h>
- #include <sys/types.h>
-- ],[
-+ ]],[[
- pthread_t t;
- pthread_setname_np("foo");
-- ],[
-+ ]])],[
- AC_DEFINE(HAS_PTHREAD_SETNAME_NP_DARWIN, 1, The function to set pthread name has no pthread argument.)
- AC_MSG_RESULT(darwin)
- ],[
-@@ -495,7 +479,7 @@ AC_DEFUN([TORRENT_DISABLE_PTHREAD_SETNAME_NP], [
- AC_MSG_CHECKING([for pthread_setname_no])
-
- AC_ARG_ENABLE(pthread-setname-np,
-- AC_HELP_STRING([--disable-pthread-setname-np], [disable pthread_setname_np]),
-+ AS_HELP_STRING([--disable-pthread-setname-np],[disable pthread_setname_np]),
- [
- if test "$enableval" = "no"; then
- AC_MSG_RESULT(disabled)
-diff --git a/scripts/common.m4 b/scripts/common.m4
-index 55e8d66e..2f54402e 100644
---- a/scripts/common.m4
-+++ b/scripts/common.m4
-@@ -1,6 +1,7 @@
- AC_DEFUN([TORRENT_WITH_SYSROOT], [
- AC_ARG_WITH(sysroot,
-- AC_HELP_STRING([--with-sysroot=PATH], [compile and link with a specific sysroot]),
-+ AS_HELP_STRING([--with-sysroot=PATH],
-+ [compile and link with a specific sysroot]),
- [
- AC_MSG_CHECKING(for sysroot)
-
-@@ -22,7 +23,8 @@ AC_DEFUN([TORRENT_WITH_SYSROOT], [
-
- AC_DEFUN([TORRENT_ENABLE_ARCH], [
- AC_ARG_ENABLE(arch,
-- AC_HELP_STRING([--enable-arch=ARCH], [comma seprated list of architectures to compile for]),
-+ AS_HELP_STRING([--enable-arch=ARCH],
-+ [comma seprated list of architectures to compile for]),
- [
- AC_MSG_CHECKING(for target architectures)
-
-@@ -82,7 +84,8 @@ AC_DEFUN([TORRENT_MINCORE_SIGNEDNESS], [
-
- AC_DEFUN([TORRENT_MINCORE], [
- AC_ARG_ENABLE(mincore,
-- AC_HELP_STRING([--disable-mincore], [disable mincore check [[default=enable]]]),
-+ AS_HELP_STRING([--disable-mincore],
-+ [disable mincore check [[default=enable]]]),
- [
- if test "$enableval" = "yes"; then
- TORRENT_MINCORE_SIGNEDNESS()
-@@ -174,7 +177,8 @@ AC_DEFUN([TORRENT_CHECK_ALIGNED], [
-
- AC_DEFUN([TORRENT_ENABLE_ALIGNED], [
- AC_ARG_ENABLE(aligned,
-- AC_HELP_STRING([--enable-aligned], [enable alignment safe code [[default=check]]]),
-+ AS_HELP_STRING([--enable-aligned],
-+ [enable alignment safe code [[default=check]]]),
- [
- if test "$enableval" = "yes"; then
- AC_DEFINE(USE_ALIGNED, 1, Require byte alignment)
-@@ -189,7 +193,8 @@ AC_DEFUN([TORRENT_DISABLE_INSTRUMENTATION], [
- AC_MSG_CHECKING([if instrumentation should be included])
-
- AC_ARG_ENABLE(instrumentation,
-- AC_HELP_STRING([--disable-instrumentation], [disable instrumentation [[default=enabled]]]),
-+ AS_HELP_STRING([--disable-instrumentation],
-+ [disable instrumentation [[default=enabled]]]),
- [
- if test "$enableval" = "yes"; then
- AC_DEFINE(LT_INSTRUMENTATION, 1, enable instrumentation)
-@@ -206,7 +211,8 @@ AC_DEFUN([TORRENT_DISABLE_INSTRUMENTATION], [
-
- AC_DEFUN([TORRENT_ENABLE_INTERRUPT_SOCKET], [
- AC_ARG_ENABLE(interrupt-socket,
-- AC_HELP_STRING([--enable-interrupt-socket], [enable interrupt socket [[default=no]]]),
-+ AS_HELP_STRING([--enable-interrupt-socket],
-+ [enable interrupt socket [[default=no]]]),
- [
- if test "$enableval" = "yes"; then
- AC_DEFINE(USE_INTERRUPT_SOCKET, 1, Use interrupt socket instead of pthread_kill)
-@@ -214,3 +220,14 @@ AC_DEFUN([TORRENT_ENABLE_INTERRUPT_SOCKET], [
- ]
- )
- ])
-+
-+AC_DEFUN([TORRENT_DISABLE_IPV6], [
-+ AC_ARG_ENABLE(ipv6,
-+ AS_HELP_STRING([--enable-ipv6],
-+ [enable ipv6 [[default=no]]]),
-+ [
-+ if test "$enableval" = "yes"; then
-+ AC_DEFINE(RAK_USE_INET6, 1, enable ipv6 stuff)
-+ fi
-+ ])
-+])
-diff --git a/scripts/rak_compiler.m4 b/scripts/rak_compiler.m4
-index 9a361bed..bc1572a3 100644
---- a/scripts/rak_compiler.m4
-+++ b/scripts/rak_compiler.m4
-@@ -26,7 +26,7 @@ AC_DEFUN([RAK_CHECK_CXXFLAGS], [
-
- AC_DEFUN([RAK_ENABLE_DEBUG], [
- AC_ARG_ENABLE(debug,
-- AC_HELP_STRING([--enable-debug], [enable debug information [[default=yes]]]),
-+ AS_HELP_STRING([--enable-debug],[enable debug information [[default=yes]]]),
- [
- if test "$enableval" = "yes"; then
- CXXFLAGS="$CXXFLAGS -g -DDEBUG"
-@@ -41,7 +41,7 @@ AC_DEFUN([RAK_ENABLE_DEBUG], [
-
- AC_DEFUN([RAK_ENABLE_WERROR], [
- AC_ARG_ENABLE(werror,
-- AC_HELP_STRING([--enable-werror], [enable the -Werror and -Wall flags [[default -Wall only]]]),
-+ AS_HELP_STRING([--enable-werror],[enable the -Werror and -Wall flags [[default -Wall only]]]),
- [
- if test "$enableval" = "yes"; then
- CXXFLAGS="$CXXFLAGS -Werror -Wall"
-@@ -54,7 +54,7 @@ AC_DEFUN([RAK_ENABLE_WERROR], [
-
- AC_DEFUN([RAK_ENABLE_EXTRA_DEBUG], [
- AC_ARG_ENABLE(extra-debug,
-- AC_HELP_STRING([--enable-extra-debug], [enable extra debugging checks [[default=no]]]),
-+ AS_HELP_STRING([--enable-extra-debug],[enable extra debugging checks [[default=no]]]),
- [
- if test "$enableval" = "yes"; then
- AC_DEFINE(USE_EXTRA_DEBUG, 1, Enable extra debugging checks.)
-diff --git a/scripts/rak_cxx.m4 b/scripts/rak_cxx.m4
-deleted file mode 100644
-index 0db61b83..00000000
---- a/scripts/rak_cxx.m4
-+++ /dev/null
-@@ -1,14 +0,0 @@
--AC_DEFUN([RAK_CHECK_CXX11], [
-- AC_ARG_ENABLE([c++0x],
-- AC_HELP_STRING([--enable-c++0x], [compile with C++0x (unsupported)]),
-- [
-- if test "$enableval" = "yes"; then
-- AX_CXX_COMPILE_STDCXX_0X
-- else
-- AX_CXX_COMPILE_STDCXX_11(noext)
-- fi
-- ],[
-- AX_CXX_COMPILE_STDCXX_11(noext)
-- ]
-- )
--])
deleted file mode 100644
@@ -1,29 +0,0 @@
-From eca577e2a29d64251b5df1c69be53c5b1ffe6bde Mon Sep 17 00:00:00 2001
-From: Jari Sundell <sundell.software@gmail.com>
-Date: Thu, 8 Sep 2022 05:08:44 +0900
-Subject: [PATCH] Create FUNDING.yml
-
----
- .github/FUNDING.yml | 13 +++++++++++++
- 1 file changed, 13 insertions(+)
- create mode 100644 .github/FUNDING.yml
-
-diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
-new file mode 100644
-index 00000000..ad5998e8
---- /dev/null
-+++ b/.github/FUNDING.yml
-@@ -0,0 +1,13 @@
-+# These are supported funding model platforms
-+
-+github: [rakshasa]
-+patreon: rtorrent
-+open_collective: # Replace with a single Open Collective username
-+ko_fi: # Replace with a single Ko-fi username
-+tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
-+community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
-+liberapay: # Replace with a single Liberapay username
-+issuehunt: # Replace with a single IssueHunt username
-+otechie: # Replace with a single Otechie username
-+lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
-+custom: ['https://rakshasa.github.io/rtorrent/donate.html']
@@ -6,57 +6,12 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=393a5ca445f6965873eca0259a17f833"
DEPENDS = "zlib libsigc++-2.0 openssl cppunit"
-SRC_URI = "git://github.com/rakshasa/libtorrent;branch=master;protocol=https \
- file://0001-Fix-compilation-issue-with-gcc-v6.x-and-empty-CXXFLA.patch \
- file://0002-Modfiy-gcc-v6.x-fix-for-empty-CXXFLAGS-See-10.patch \
- file://0003-Add-space-to-fmt-str-in-log_gz_file_write.patch \
- file://0004-IPv4-filter-enhancement-11IPv4-filter-enhancement-Cl.patch \
- file://0005-Disable-extents-test-to-pass-TravisCI-See-11.patch \
- file://0006-Bumped-version-to-0.13.7.patch \
- file://0007-Added-support-for-openssl-1.1.patch \
- file://0008-Use-AC_COMPILE-instead-of-AC_RUN-to-check-for-execin.patch \
- file://0009-Modify-configure-to-prevent-unnecessary-kqueue-check.patch \
- file://0010-Display-info-on-failed-tracker-bencode-parsing-See-9.patch \
- file://0011-Strip-tags-also-when-displaying-info-on-failed-track.patch \
- file://0012-Switch-to-C-11-MRT-RNG-for-random-bytes.patch \
- file://0013-Prevent-loss-of-m_ipv6_socket-attribute-which-led-to.patch \
- file://0014-If-during-socket-creation-AF_INET6-failes-initialize.patch \
- file://0015-Fixes-https-github.com-rakshasa-rtorrent-issues-731.patch \
- file://0016-Fix-honoring-throttle.min_peers-settings-in-rtorrent.patch \
- file://0017-increase-piece-length-max.patch \
- file://0018-Set-max-piece-size-512mb.patch \
- file://0019-Fixed-compiler-warning.patch \
- file://0020-Added-_GNU_SOURCE-to-fallocate-test.-neheb.patch \
- file://0021-Fixed-diffie-hellman-implementation.patch \
- file://0022-Increased-max-timeout-for-tracker-requests.patch \
- file://0023-Close-log-files-when-reusing-a-name.patch \
- file://0024-Bumped-to-version-0.13.8.patch \
- file://0025-Allow-logs-to-be-appended-rather-than-overwritten.patch \
- file://0026-Removed-log-append-function.-Added-append-parameter-.patch \
- file://0027-Backport-changes-from-feature-bind.-200.patch \
- file://0028-libtorrent.pc.in-add-Libs.Private-202.patch \
- file://0029-Fix-for-inotify-missing-quickly-renamed-files-203.patch \
- file://0030-Fix-compiler-warnings.-204.patch \
- file://0031-Fix-log-format-so-GCC-can-check-it.-205.patch \
- file://0032-Consolidate-make-script-to-optimize-build.-206.patch \
- file://0033-Refactor-make-process.-207.patch \
- file://0034-Changes-automake-required-files.patch \
- file://0035-Replaced-custom-execinfo-autoconf-test.patch \
- file://0036-Added-option-to-disable-pthread_setname_np.patch \
- file://0037-Improved-backtrace-error-checking.patch \
- file://0038-Fixed-issue-with-multiple-connections-from-NAT-not-w.patch \
- file://0039-Added-disable-execinfo-option-to-configure.patch \
- file://0040-Detect-ip-address.patch \
- file://0041-Added-ipv6-options.patch \
- file://0042-Removed-obsolete-files.patch \
- file://0043-Updated-and-cleaned-up-automake.-224.patch \
- file://0044-Create-FUNDING.yml.patch \
- "
-SRCREV = "c167c5a9e0bcf0df23ae5efd91396aae0e37eb87"
+SRC_URI = "git://github.com/rakshasa/libtorrent;branch=master;protocol=https"
+SRCREV = "e60f222241319aaae482789517ad00ae9344bd13"
CVE_STATUS[CVE-2009-1760] = "backported-patch: patched in our product"
-PV = "1"
+PV = "0.13.8+git${SRCPV}"
S = "${WORKDIR}/git"
This reverts commit 3259bc75f5cbe83623e340efd4518414ae2f7593. AUH incorrectly identified the tag "pre-merge-1" as version "1". Signed-off-by: Peter Kjellerstedt <peter.kjellerstedt@axis.com> --- ...issue-with-gcc-v6.x-and-empty-CXXFLA.patch | 44 - ...c-v6.x-fix-for-empty-CXXFLAGS-See-10.patch | 56 - ...pace-to-fmt-str-in-log_gz_file_write.patch | 27 - ...ncement-11IPv4-filter-enhancement-Cl.patch | 379 - ...extents-test-to-pass-TravisCI-See-11.patch | 47 - .../0006-Bumped-version-to-0.13.7.patch | 30 - .../0007-Added-support-for-openssl-1.1.patch | 105 - ...nstead-of-AC_RUN-to-check-for-execin.patch | 24 - ...-to-prevent-unnecessary-kqueue-check.patch | 46 - ...failed-tracker-bencode-parsing-See-9.patch | 58 - ...when-displaying-info-on-failed-track.patch | 60 - ...tch-to-C-11-MRT-RNG-for-random-bytes.patch | 45 - ...m_ipv6_socket-attribute-which-led-to.patch | 45 - ...-creation-AF_INET6-failes-initialize.patch | 27 - ...hub.com-rakshasa-rtorrent-issues-731.patch | 29 - ...ottle.min_peers-settings-in-rtorrent.patch | 40 - .../0017-increase-piece-length-max.patch | 22 - .../0018-Set-max-piece-size-512mb.patch | 22 - .../0019-Fixed-compiler-warning.patch | 22 - ..._GNU_SOURCE-to-fallocate-test.-neheb.patch | 74 - ...-Fixed-diffie-hellman-implementation.patch | 293 - ...sed-max-timeout-for-tracker-requests.patch | 64 - ...-Close-log-files-when-reusing-a-name.patch | 123 - .../0024-Bumped-to-version-0.13.8.patch | 30 - ...-be-appended-rather-than-overwritten.patch | 109 - ...nd-function.-Added-append-parameter-.patch | 101 - ...kport-changes-from-feature-bind.-200.patch | 7365 ----------------- ...ibtorrent.pc.in-add-Libs.Private-202.patch | 26 - ...fy-missing-quickly-renamed-files-203.patch | 27 - .../0030-Fix-compiler-warnings.-204.patch | 470 -- ...-log-format-so-GCC-can-check-it.-205.patch | 33 - ...e-make-script-to-optimize-build.-206.patch | 843 -- .../0033-Refactor-make-process.-207.patch | 2710 ------ ...0034-Changes-automake-required-files.patch | 22 - ...placed-custom-execinfo-autoconf-test.patch | 48 - ...option-to-disable-pthread_setname_np.patch | 135 - ...37-Improved-backtrace-error-checking.patch | 594 -- ...-multiple-connections-from-NAT-not-w.patch | 199 - ...disable-execinfo-option-to-configure.patch | 32 - .../libtorrent/0040-Detect-ip-address.patch | 457 - .../libtorrent/0041-Added-ipv6-options.patch | 85 - .../0042-Removed-obsolete-files.patch | 444 - ...Updated-and-cleaned-up-automake.-224.patch | 2979 ------- .../libtorrent/0044-Create-FUNDING.yml.patch | 29 - .../libtorrent/libtorrent_git.bb | 51 +- 45 files changed, 3 insertions(+), 18468 deletions(-) delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0001-Fix-compilation-issue-with-gcc-v6.x-and-empty-CXXFLA.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0002-Modfiy-gcc-v6.x-fix-for-empty-CXXFLAGS-See-10.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0003-Add-space-to-fmt-str-in-log_gz_file_write.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0004-IPv4-filter-enhancement-11IPv4-filter-enhancement-Cl.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0005-Disable-extents-test-to-pass-TravisCI-See-11.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0006-Bumped-version-to-0.13.7.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0007-Added-support-for-openssl-1.1.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0008-Use-AC_COMPILE-instead-of-AC_RUN-to-check-for-execin.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0009-Modify-configure-to-prevent-unnecessary-kqueue-check.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0010-Display-info-on-failed-tracker-bencode-parsing-See-9.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0011-Strip-tags-also-when-displaying-info-on-failed-track.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0012-Switch-to-C-11-MRT-RNG-for-random-bytes.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0013-Prevent-loss-of-m_ipv6_socket-attribute-which-led-to.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0014-If-during-socket-creation-AF_INET6-failes-initialize.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0015-Fixes-https-github.com-rakshasa-rtorrent-issues-731.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0016-Fix-honoring-throttle.min_peers-settings-in-rtorrent.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0017-increase-piece-length-max.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0018-Set-max-piece-size-512mb.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0019-Fixed-compiler-warning.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0020-Added-_GNU_SOURCE-to-fallocate-test.-neheb.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0021-Fixed-diffie-hellman-implementation.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0022-Increased-max-timeout-for-tracker-requests.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0023-Close-log-files-when-reusing-a-name.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0024-Bumped-to-version-0.13.8.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0025-Allow-logs-to-be-appended-rather-than-overwritten.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0026-Removed-log-append-function.-Added-append-parameter-.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0027-Backport-changes-from-feature-bind.-200.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0028-libtorrent.pc.in-add-Libs.Private-202.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0029-Fix-for-inotify-missing-quickly-renamed-files-203.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0030-Fix-compiler-warnings.-204.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0031-Fix-log-format-so-GCC-can-check-it.-205.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0032-Consolidate-make-script-to-optimize-build.-206.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0033-Refactor-make-process.-207.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0034-Changes-automake-required-files.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0035-Replaced-custom-execinfo-autoconf-test.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0036-Added-option-to-disable-pthread_setname_np.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0037-Improved-backtrace-error-checking.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0038-Fixed-issue-with-multiple-connections-from-NAT-not-w.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0039-Added-disable-execinfo-option-to-configure.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0040-Detect-ip-address.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0041-Added-ipv6-options.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0042-Removed-obsolete-files.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0043-Updated-and-cleaned-up-automake.-224.patch delete mode 100644 meta-oe/recipes-connectivity/libtorrent/libtorrent/0044-Create-FUNDING.yml.patch